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.
Jun 26, 2010
As of SDK 3.2 most of the touch handling code in stock controls has been taken out and replaced with this amazing new technology called Gesture Recognizers. This means besides of using them yourself and creating your own you can also fiddle with behaviors of standard controls if they interfere with your own gestures.
I’m currently working quite a bit on something based on UIScrollView and there I found several things that I needed to tweak.
The first modification I did was to get around a bug in UIScrollView. I did not actually want user zooming in my scroll view, but just use the setting of the zoomLevel to scale images without having to redraw them. And you can only set the zoomLevel to values between min and max.
So, during autorotation, I reduced the min zoom scale, set the new zoom level and then set min and max both to the new zoom. But the problem with this, as of SDK 3.2., is that if you change the min or max zoomLevel property the scroll silently adds a UIPinchGestureRecognizer to itself via the addGestureRecognizer method that now all views have.
Jun 17, 2010
We all know by now that Adobe is almost as evil as …, well let’s say they pioneered a couple of functionalities that where great for the longest time. One being the PDF format which is actually totally built into OSX everywhere. On OSX you’re able to print into a PDF without having to install extra software. Also iOS comes with PDF support and today we’ll look at how we can draw a PDF in a view.
How UIWebView sees it
The first idea you might have is to use UIWebView to display PDFs which is not difficult, just get the URL, make a NSURLRequest and pass this to a web view.
_webView = [[UIWebView alloc] initWithFrame:frame];
_webView.delegate = self;
_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
// we don't want interaction, full size
_webView.scalesPageToFit = YES;
_webView.userInteractionEnabled = NO;
_webView.backgroundColor = [UIColor whiteColor];
//fileURL is an NSURL to a PDF file
[_webView loadRequest:[NSURLRequest requestWithURL:fileURL]];
But there is one drawback: you cannot really control how it will arrive on screen. For one thing, UIWebView draws a fat gray border and shadow which might somewhat mess up your UI design.
Wouldn’t it be great if you could draw the PDF somehow into a view? Yes, we can!
Jun 04, 2010
I started out with a simple project of mine, the demo I made for DTNotepadViewController. This is a navigation stack which has a UITableView. From there you can select an entry to get a detail view looking like note paper.
The goal is to convert this iPhone-only app into a hybrid app that uses a split view on iPad.
May 25, 2010
Back in April Oliver wrote an excellent article entitled “Making Your Own iPhone Frameworks”, in which he explained how to do what many developers still proclaim as impossible: how to create custom frameworks that you can use in your iPhone apps! I would recommend that you read Oliver’s article first, especially if you’re wondering what a framework is… or, possibly, why you should consider making your own frameworks. I wont talk about that here :).
To build frameworks Oliver wrote a simple shell script that first creates a typical framework bundle, and then copies resources into the appropriate directories. In this followup article, I’ll show you how to create the framework bundle entirely within Xcode, without any scripts, plugins, product-, or package-types. While this has a few advantages, I’m not claiming that my approach is in any way perfect, and there may be problems that I haven’t encountered yet. As always, this is a work in progress, so if you have any suggestions, please feel free to leave your comments below.
Enough talking. Lets get started –
May 25, 2010
Once a year you are required to refresh your two certificates and all provisioning profiles that use these. Mine had expired and so I made a screen capture to show you how painless the renewal process can be. At the same time it also shows newcomers how to best set up their stuff on the provisioning portal.
Hint: if you find that the Submit button is not working, you can also go into the provisioning profile name field and hit Enter.
For regular development work it’s generally sufficient to have only 3 provisioning profiles:
- “Development” – uses your “iPhone Developer” certificate, a * wildcard app identifier and all your development devices
- “AdHoc” – uses your “iPhone Distribution” certificate, a * wildcard app identifier and all devices you want to do ad-hoc builds for
- “AppStore” – uses your “iPhone Distribution” certificate, and if you don’t do IAP or Push Notifications you can use a wildcard app identifier as well
You don’t need to create a new app identifier on the portal for each new app that you begin. You only ever need unique app identifiers if you publish an app capable of InAppPurchases or Push Notifications.You can change the app identifier with every upload to Apple, contrary to the bundle identifier in the info.plist which has to stay the same for the app to be accepted as an update. New bundle identifier means new app.
Once you have gone through the steps shown in the video you are good to go for another year, until the certificates expire once more.