www.dosomethinghere.com
An Introduction to Windows Phone 7 Development (CONDG meeting, August 21, 2010)
Tonight I attended the Central Ohio .NET Developers Group meeting at the Microsoft office in Polaris. Jeff Blankenburg gave a presentation on developing applications for the Windows Phone 7 platform, and Mel Grubb gave a short talk on the Should open-source testing library.
Jeff’s presentation was very high level, but still informative. He did confirm my biggest disappointment on the platform, and that is the glaring lack of a data store. I guess that Microsoft couldn’t find anyone to port over the SQL Mobile 2005 code. Or maybe even the SQL Server Compact code. Or the SQL Server Mobile Edition code.
Second iPhone app approved
After 9 days, my company’s second iPhone app, Football Statware, was approved on Sunday, August 22, 2010, and is available for download from the App Store.
I have already pushed an update to the application with a few minor fixes, we will see how long this update takes.
Rack mounted server… Strap mounted server… Same difference.
While the set up pictured below was not our equipment, I am still kind of glad that our servers are not hosted at this facility any longer.
Second iPhone app submitted
This past Friday, I submitted my company’s second iPhone application to the App Store for approval. We did not do any profiling on this application for performance or memory leaks, but hopefully it will go through without incident. Stay tuned.
Highly useful Objective-C code
I just got the inspiration to add the following line of code to the app delegate header of my latest iPhone application:
#define VERY_YES YESIf you are wondering about the etymology of this, please check out the following informational message:
Where does the term “very yes” originate from?
I leave it to the imagination and creativity of my fellow developers to adapt this code to run in other flavors of C. Please make sure to credit me if you decide to use it.
The O in iOS is for Orchestra (CIDUG meeting, July 27, 2010)
Geoffrey Goetz gave a presentation on iPhone application development at the Columbus iPhone Developer User Group on July 27, 2010. His topic was mainly a recap of some of the application approval and performance issues that were covered at the 2010 WWDC.
The most interesting part of his presentation for me was his presentation on using the Zombies feature of Instruments. We had some random crashes going on in our Basketball Statware application, and this might have helped to chase down the problem. As it was, I believe we fixed the problem by moving like named variables just sitting by themselves in the implementation files inside the class as class variables.
NSLogTable improvements
Are you tired of seeing the date, time (with seconds and even milliseconds), application name and other stuffs appearing at the beginning of each and every line of the debugging console? You know, the NSLog lines that you use for debugging purposes that look like this:
2010-07-22 20:42:46.998 MyApplicationName[246:207] Setting up reachability notifier 2010-07-22 20:42:47.006 MyApplicationName[246:207] Version: 0.6 2010-07-22 20:42:47.007 MyApplicationName[246:207] Checking for database 2010-07-22 20:42:47.007 MyApplicationName[246:207] Database existsThis information can be helpful, but for the purposes of my utility class that outputs the contents of a SQLite3 database table (see my blog post entitled Nicely formatted data to debugger console for iPhone SDK), this is very annoying as it takes up a lot of the debugging console window.
Well, I decided to look to see if I could output to the debugging and remove the date, time, and application name from the beginning of each line. As it turns out, I found that you cannot do this with NSLog, but luckily I found the following web page that contained the answer:
Even though the web page is for Cocoa development, there is nothing Mac OS X specific looking in there, so I copied the QuietLog function and pasted it into my NSLogTable implementation file, and now I can see much more of my nicely formatted tables since the left 33% of my screen is not filled up with useless dates, times, application names, and thread identifiers.
Here is now what my NSLogTable.m file looks like. (The NSLogTable.h file is unchanged.)
// // NSLogTable.m // #import "NSLogTable.h" @implementation NSLogTable void QuietLog (NSString *format, ...) { if (format == nil) { printf("nil\n"); return; } // Get a reference to the arguments that follow the format parameter va_list argList; va_start(argList, format); // Perform format string argument substitution, reinstate %% escapes, then print NSString *s = [[NSString alloc] initWithFormat:format arguments:argList]; printf("%s\n", [[s stringByReplacingOccurrencesOfString:@"%%" withString:@"%%%%"] UTF8String]); [s release]; va_end(argList); } + (void)dumpTable:(NSMutableArray *)rows { int idx = 0; NSMutableArray *rowData; int colWidths[100]; NSString *s; NSMutableString *ms = [[NSMutableString alloc] init]; BOOL firstRow = YES; for (int i = 0; i < 100; i++) colWidths[i] = 0; // get the maximum column widths for (id row in rows) { rowData = (NSMutableArray *)row; for (int i = 0; i < [rowData count]; i++) { s = [rowData objectAtIndex:i]; if ([s length] > colWidths[i]) { colWidths[i] = [s length]; } } } for (id row in rows) { [ms setString:@""]; if (firstRow) { [ms appendString:@" "]; firstRow = NO; } else { [ms appendFormat:@"%4d ", idx]; } rowData = (NSMutableArray *)row; for (int i = 0; i < [rowData count]; i++) { s = [rowData objectAtIndex:i]; [ms appendString:[s stringByPaddingToLength:colWidths[i] withString:@" " startingAtIndex:0]]; [ms appendString:@" "]; } QuietLog(@"%@", ms); idx++; } [ms release]; QuietLog(@""); } @endTwo more iPhone SDK facts you may not know
Here are two other fun facts I discovered about the iPhone SDK:
1. You can present a modal view controller on top of another modal view controller
This would appear to contradict fact #2 from my posting of July 13th, but I have learned some new information. In my previous attempts to stack up modal view controllers, I was sending the presentModalViewController method call to the navigation controller defined in my app delegate. For the second modal view controller, if I just send the presentModalViewController method call in the first view controller to self, all works as it should.
2. Watch your colons on delegate selectors
I was trying to wire up a cancel delegate call that passed no parameters back to the caller, since none are necessary. However, the cancel delegate that I copied and changed from the working accept delegate was never firing in the following code:
if (delegate && [delegate respondsToSelector:@selector(myDelegateCancelPressed:)]) { [delegate myDelegateCancelPressed]; }After I removed the colon from inside the @selector, it worked right as rain.
Two iPhone SDK facts you may not know
I discovered (quite by accident) two things today about iPhone software development. These are things that are probably documented and discussed elsewhere, so here is yet another documenting/mentioning of them.
1. The order of stuff in Interface Builder is actually pretty important
So I am in Interface Builder, copying and pasting some repetitive stuff. I usually like to have the document window open on the left of the screen, the view open middle left, the inspector middle right, and the library on the right. And every once in a while, the stuff I pasted that showed up at the bottom of the list of controls in my view disappeared.
As it turns out, this was happening when I was subconsciously sending the newly pasted controls to the back, and as you may not know, the order of the controls as shown in a view pertains exactly to the z-order of the controls. The control that I was sending to the back going to the top of the list of controls under the view in the document window.
2. Don’t try to present a modal view controller on top of another modal view controller
The subject above says it all. If you create a view controller and use the presentModalViewController method, nothing really happens. The new view is created, but just sort of fizzles out before reaching the screen. (Or in other words, the init is called, but viewDidLoad is never reached.)
This will present a bit of a challenge, as just about every other environment I have worked in allows you to lay modals on top of other modals.
Shine On You Crazy Icon
If you are trying to remove the shine effect from the icon on your iPhone application, and it is not working, check the order of items in your info.plist file.
I had the “Icon already includes gloss effects” item at the bottom of my plist file with a value of checked, but it would not get rid of the shiny icon on the simulator or on a device. I found that, after I moved the entry up to the top of the plist file, it now gave me an unshiny icon on the simulator and on a new device that I tried the software on.
My main iPod touch that I use for development still has the shiny icon even after deleting the application from the device and powering it off and back on. Anyone have any ideas why this would be?
iPhone app update available in App Store
Good news for those of you who tried to use the first revision of our Basketball Statware iPhone app and found yourself looking at a silently failing crash when you sync.
Version 1.0.1 of Basketball Statware is now available for download in the App Store. Also, a little bug was fixed up concerning visiting the event list view when you do not have any events in your game.
Here is the URL for the product:
And here is a link to the revision history document for this application on our support web site:
Basketball Statware iPhone application revision history
The next revision of the application is going to have more minor bug fixes and memory leak fixes, as well as a neat feature that switches between a box score summary and an extended box score summary by rotating the device from portrait to landscape mode. This is almost ready to be submitted to Apple for approval, and should be ready by the middle of July.
Droid tethering with PdaNet
By the way, I forgot to mention that while John and I were on our Codestock trip, I got tired of hoping beyond hope that the 2.2 Froyo update would appear on my Verizon Droid and purchased a license for the PdaNet software for Android. (I have a great fear of open wi-fi access points.)
It worked flawlessly with both the Mac OS X and Windows 7 operating systems on my BootCamp MacBook Pro. Nice job June Fabrics. Here is a link to their Android product:
The demo of the software will run for 14 days, and then it will start blocking secure web sites. Also, you install a client application on your Windows or Macintosh computer that you need to run, along with running the PdaNet application on your device and activating the USB or Bluetooth mode. I did not try the Bluetooth mode, I just brought my Droid USB cable and communicated that way.
I highly recommend the software for Droid owners who need an internet connection on their laptop while on the go.
CodeStock 2010, Day 2
Here were the sessions that I attended on day 2 (Saturday, June 25, 2010) of the CodeStock 2010 developer’s conference in Knoxville, Tennessee:
- Web and Cloud Development with Visual Studio 2010 by Glen Gordon
- Introduction to iPhone Development and A Quick Tour of the iPhone SDK by Gun Makinabakan
- Transitioning from WinForms to WPF by Miguel Castro
Special thanks to Michael Neel and all his peeps for putting on an excellent conference. John and I had an informative time, the venue was better than last year, and the hotel being right across the street was super convenient.
iPhone app accepted!
Good news!
Our iPhone app was accepted into the iTunes App Store on the very first try!!!
I am far too tired to post details right now, I will modify this message after I recover a bit. For now, if you want to see it, fire up your iTunes, go into the App Store, and search for Basketball Statware.
CodeStock 2010, Day 1
Here were the sessions that I attended on day 1 (Friday, June 25, 2010) of the CodeStock 2010 developer’s conference in Knoxville, Tennessee:
- Effective Interface Design by John Kellar
- Effectively Using IntelliTrace by James Ashley
- F# and Functional Programming by Chris Marinos
- Visual Studio 2010 Architecture, Modeling, and Visualization by Jennifer Marsman
- High Level Overview of Android Development by Roger Heim
All of the presenters I saw did nice jobs with their presentations. And to cap the night off, instead of sticking around the Bijou after the keynote was complete and getting loaded with all of the other developers, my coworker and I attended a local minor league baseball game.
iPhone app submitted to App Store
A momentous occasion, my company’s first iPhone app has been submitted to the App Store. Hopefully it will fly through the review process within minutes and be accepted the very first time. OK, maybe not.
There was one application uploading issue I ran into. The distribution code built just fine after a bit of tweaking, but upon uploading the .zip file to the iTunes Connect page, I got the following error:
The binary you uploaded was invalid. The application-identifier entitlement is not formatted correctly; it should contain your 10-character App ID Seed, followed by a dot, followed by your bundle identifier.As it turns out, I needed to make some changes to my Entitlements.plist file that did not appear to be mentioned or documented anywhere. Thanks to the TwoAppGuys and their blog entry iOS4 and the wildcard for the solution to this issue.
I will post again when I learn the ultimate fate of our app.
iPhone code signing issues
So I am trying to get a project started a while back into a state where it can be submitted to the app store, and of course it never goes smoothly. Today’s issue was a bunch of build and code signing errors that occurred when I tried to switch from using an older iPhone developer account to our current one, and added a new development device to the provisioning profile.
Here were the steps that I took to finally get it building and running on my development devices:
- Regenerate the development certificate and provisioning profile after adding the new development device
- Move the development certificate from the system area into the login area in Keychain Access
- Clean out the old provisioning profiles in the Xcode organizer and from the device
- Add the new provisioning profile to the device
- Add the new provisioning profile to the provisioning profile section of the Organizer under iPhone Development
- Change the code signing identity in the Project info Build tab and in the Target info Build tab
Once I did all these steps, it started to build and run on the device. Now I just can’t wait until I try to build for distribution and submit to the App Store. What could possibly go wrong?
2010 Central Ohio Day of .NET
A co-w0rker and I attended the Central Ohio Day of .NET on June 5, 2010. There was quite a bit of good content at the conference, which is a real tribute to the organizers, volunteers, and presenters.
The highlights of my day were sitting in on Matt Casto’s regular expressions talk, Phil Japikse’s M-V-VM primer, discussing the etymology of the MongoDB project with Sam Corder (I still say it was named such after the character in Blazing Saddles), Michael Eaton’s talk on WPF, and Parag Joshi’s demonstration of XNA/Windows Phone 7 game development.
UIButton can sing and dance, too!
Apparently, there is no way to take a UIButton and set it’s property to “selected” for the purposes of having the UI display the button with the background image as it appears in the UIControlStateSelected state. As a result, I decided that I would just track which of my series of UIButton controls was supposed to be selected, set the background image of all the buttons to nil, and set the UIControlStateNormal background image of the button to an image, and it seemed to work OK.
The code to do this, however, was kind of ugly, and my co-worker on this project pushed me to find a better way. The result is the ExpandoButton class that we created and added to the project. For this class (which of course inherits UIButton), I wanted to be able to initialize it to a particular background image, and I wanted to have a message I could send the button to have it switch back and forth from the unselected background image to the selected background image.
Here are the header and implementation files for the ExpandoButton object class:
// // ExpandoButton.h // #import <Foundation/Foundation.h> @interface ExpandoButton : UIButton { } - (void)setSelectedImage:(BOOL)isSelected; @end // // ExpandoButton.m // #import "ExpandoButton.h" @implementation ExpandoButton - (id)initWithCoder:(NSCoder *)decoder { if (self = [super initWithCoder:decoder]) { UIImage *image = [UIImage imageNamed:@"button_normal.png"]; UIImage *stretchImage = [image stretchableImageWithLeftCapWidth:4.0 topCapHeight:4.0]; [self setBackgroundImage:stretchImage forState:UIControlStateNormal]; self.backgroundColor = [UIColor clearColor]; } return self; } - (void)setSelectedImage:(BOOL)isSelected { NSString *file; if (isSelected) { file = @"button_selected.png"; } else { file = @"button_normal.png"; } UIImage *image = [UIImage imageNamed:file]; UIImage *stretchImage = [image stretchableImageWithLeftCapWidth:4.0 topCapHeight:4.0]; [self setBackgroundImage:stretchImage forState:UIControlStateNormal]; } @endA few notes here about the implementation file. You will of course need to add the stretchable unselected and selected button images to your project and change the names above, along with changing the cap width and height to your needs. Also, the initWithCoder part took us a few moments to figure out, it wasn’t working at first because we weren’t calling the super’s initWithCoder, just the regular old init. And finally, keep in mind that there is no error checking, optimization, or memory leak checking going on here.
To actually use the ExpandoButton, go into your Interface Builder, and from the Library window, select the Classes option, make sure the choice list right below is set to Library, and you should then be able to scroll the list and see an ExpandoButton, which looks just like a UIButton. Put that object on your view and set the size and title if you wish. VERY IMPORTANT: Make sure to set the button type of your ExpandoButton to Custom instead of the default of Rounded Rect.
Then, in your view controller header file, set up an IBOutlet with type of ExpandoButton (don’t forget the header or @class), along with the corresponding @property, and in the view controller implementation file, set up the @synthesize. After you save the files and build, go back into Interface Builder and set up the connection between the IBOutlet and the ExpandoButton on the view. (I hope you remembered where it was. When you set it to Custom and if you do not have any title text, the button sort of disappears.)
If everything is hooked up and working correctly, in your implementation file code, you can do something like this:
[myExpandoButton setSelectedImage:YES];And the button should show up with the selected background image.
iPad 101: A Magical and Revolutionary Introduction (CIDUG meeting, May 25, 2010)
Justin Munger gave a presentation on some of the new features of the iPad and how to utilize them in the iPhone SDK at the Columbus iPhone Developer User Group on May 25, 2010. The topics he covered were the new modal dialogs, split views, gesture recognizers, and building a universal application for both iPhone and iPad.
His sample code and presentation slides are located on the CIDUG web site at: