Oct 06, 2010
When creating a static universal framework we’re facing one quite annoying problem. How do we get our pretty images added to the app bundle that our code will be used in?
Contrary to what you might be used to on the Windows platform there is no built-in method of embedding graphics files into an app binary. Because of this you see famous SDKs like FBConnect provide a bundle together with their libraries. To add these you have to add both the library/framework and the graphics bundle to your project.
Bundles are basically just folders that have been named with the .bundle extension. This hides their content from lazy clicking, but you can still look inside in terminal or by right click and “Show Package Contents”. This opens the bundle like a folder and you can edit its contents.
Now for the longest time I had a longing to package library and SDK code in neat frameworks that you would simply drag&drop into a target project. I managed to build two libraries and glue them together so that the same library can be used for building for simulator and device. Then guest author Netytan demonstrated how you can hack a bundle project to create a framework instead. The graphics problem was literally the only open loop to close.
Until today …
Sep 02, 2010
You can see that Apple is constantly polishing the APIs from version to version, but sometimes they make a more drastic change that breaks existing code. Well, not exactly “breaks”, but starts to show warnings about you daring to use deprecated methods.
One such change came out of their trying to adhere to their own naming conventions of methods. The second kind of late polishing is if there are new structures introduced without a matching Make macro for easy filling of said structures. I have an example for you, also in CoreLocation.
In this post I’m exploring two such changes and tell you how I dealt with them in a backwards compatible way.
Aug 17, 2010
If your app requires an internet connection for certain tasks you will have to be able to deal with situations where connectivity drops out for some time. For many cases it might be sufficient to display an error when stringWithContentsOfURL returns nil, but it’s better customer service to inform the user beforehand. Apple thinks so too, they test all apps also in airplane mode and your app better not crash or confuse the user or else it will get rejected.
Fortunately there is a great sample on the Apple Website that you might have heard it’s name mentioned in many circles: Reachability. The first version of this was difficult to use but Apple staff keeps polishing their works and so we have reached version 2.2 already, recently updated for iOS 4. The major change that 2.x gave us is the ability to get continuous updates on connection availability. This enables us to have our apps work similar to the iTunes app which displays a message to this effect when there’s no connection and has the UI return as soon as the connection is back.
So, let’s explore how to add the source for Reachability to our project and have some live checks.
Aug 14, 2010
It was before SDK 3.2 that I developed a technique to add tap-and-hold interactivity to your tableview cells. In this article I’ll demonstrate the old technique, which still works, and contrast it with how much easier it has become if you can target iOS 3.2 and above.
First the “old way”. It needs to customize touch handling for the tableview cells themselves, which means you have to subclass UITableViewCell.
Jul 30, 2010
CGRect might just be one of the most often used structures that you have in your fingers when coding for iPhone. View frames and bounds are something that you touch way more often than dealing with CGSize or CGPoint values.
So it pays to know about all the nifty utilities that Apple provides for you to make your life easier.
Jul 21, 2010
When I revisited the settings screen on MyAppSales to add a switch it turned my stomach how I would have added it over a year ago versus to the way I’m doing it now.
The Old Way
Consider the following snipped just to get a similar nausea so that you can appreciate what I am going to show you afterwards. That’s from a random switch in cellForRowAtIndexPath.
NSString *CellIdentifier = @"ServerSectionSwitch";
SwitchCell *cell = (SwitchCell *)[tableView dequeueReusableCellWithIdentifier:
if (cell == nil)
cell = [[[SwitchCell alloc] initWithFrame:CGRectZero reuseIdentifier:
cell.titleLabel.text = @"Enable on WLAN";
ASiSTAppDelegate *appDelegate = (ASiSTAppDelegate *)[[UIApplication sharedApplication]
cell.switchCtl.on = appDelegate.serverIsRunning;
[cell.switchCtl addTarget:appDelegate action:@selector(startStopServer:)
So obviously I had created a custom tableview cell, so let’s glance at that as well.
Jul 15, 2010
I previously explained how to use NSUserDefaults to your advantage, basically being the OSX equivalent to the Windows registry. User Defaults are the way how you can persist small amounts of data in a convenient way. They are basically dictionaries that the system takes care of for you with the added benefit of being cached in memory.
Today we’ll up it one notch. Session 124 of the WWDC 2010 videos brought to my attention the fact that there’s also a mechanism to provide default values for the defaults. Up until now I would have retrieved an object from the defaults, checked if it’s nil and then set the value. Consider the following code snipped from SpeakerClock:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber *countdownNum = [defaults objectForKey:@"Countdown"];
countdown = [countdownNum doubleValue];
countdown = self.currentPreset.startDuration;
This works, but it’s not elegant. Wouldn’t it be great if we could pre-register those values so that a simple retrieval always has a result?
Jul 04, 2010
UPDATE: Added handleOpenURL to the flow charts. Added UIApplicationExitsOnSuspend. Untangled some lines.
UPDATE: renamed deprecated handleOpenURL to newer name.
Now that we all are moving our source code gradually to iOS 4 I had to pause and think a bit about where to move which code. A problem that I’m facing frequently when updating a project is that the didFinishLaunching is only called if the app really launches.
That poses a bit of a challenge if you are used to doing things like refreshing images or other files off the internet. An app that is resumed from standby does no longer go through this delegate method. So an app that would always show fresh content upon launch before 4.0 multitasking would no longer load any new content as soon as you build it for 4.0. That’s actually one of the main reasons why I have not yet had time to update MyAppSales to 4.0.
To gain the possibility for “fast app switching” you actually don’t need to do anything. All apps automatically support it because they no longer get terminated if the user pushes the Home button. They get put into a sleep mode while the iPhone still has enough memory for everything else. It’s only if RAM runs out that the OS starts killing apps. There is begins with the ones that have the most memory reserved.
I grabbed the free trial of Omnigraffle and the Non-techie Process Flowchart Stencils by gfraser. Then I researched when all these various delegate methods of UIApplication are being called and drew charts to illustrate the flow.
By inhaling first how it was before multitasking and then upgrading your mental process to backgrounding we can begin to fully appreciate how it all fits together.
Jul 04, 2010
Prior to iOS 3.2 your only option for playing videos on iPhone was to use MPMoviePlayerController and only in full screen mode. It made sense because who really wants to look at stamp sized videos on his mobile phone.
The iPad changed all that and brought along several changes in how you can place videos. All those changes also made it into the iPhone SDKs. Here’s a pitfall that you might not have seen if you didn’t upgrade the SDK on one of your iPhone projects.