BuySellAds.com

Until Dec 3rd, 44% off all Manning books, including Barcodes with iOS! Promo code: mobicftw
Our DNA is written in Objective-C
Jump

Target-specific Headers

Often you will add multiple targets to your project file to build variants of the same app. For example if you have a Lite version or Ad-sponsored variant using the same source code you would definitely save yourself a lot of work having a single project and then multiple targets.

While I was helping a colleague merging three projects into one we found it impossible to assign headers to single targets. You can assign source code, images and lots of other file types, but why oh why no headers? How would we make sure that from 3 Constants.h files always the correct one would be used?

There are of course methods out there which propose to either have a script replace the headers or use an ugly contruct like this:

#if defined(TARGET_1)
#import
#elif defined(TARGET_2)
#import
#else
#error Must define a TARGET macro!
#end

I you you too are cringing from seeing such code. Surely there must be a more elegant solution. I searched, and I found not one but TWO.
Read more

Custom Back Button on Navigation View

When you push a view controller onto a navigation stack, the back button will always show the title of the previous view controller. This can lead to ugly effects if the title is too long. But then again, you want long titles on your view controllers because you don’t want to let the title bar space go to waste.

The method of how you can customize the back button is a little bit counterintuitive, but it was shown on episode 13 of the Standford lectures. [Here my I came to a screetching halt]

When I went to search my Blog for the link to the Standford stuff, I also found that I had already posted exactly the same recipe already one month ago. And  It’s still valid, even though I did not remember posting it. This serves to show that you might not be as productive at 5 am in the morning as you would assume. Memory is lacking then.

Well, just to put in at least something new, here is a before and after visual illustration:

Before:

Before

After:

After

Go to the previous article “Shorter Back Buttons

GeoCorder 1.0.3

The customer crash reports that Apple now makes available showed me a problem with GeoCorder that I had missed.

  • Removed redundant code that would load and save tracks in a seperate file in addition to the trackpoints written directly to a SQLite database while recording. This could cause timouts on program exit and long loading times at program start for people with lots of recorded trackpoints.
  • Thus program start and exit are now much faster for people with lots of recorded tracks.

It’s embarrassing I know, but how can you spot such a thing? When you test your app you don’t think to record so many tracks that applicationWillTerminate will time out and be aborted by the iPhone OS. But thanks to the crash reports I was immediately steered in the right direction of what to fix.

I’ve submitted this quick fix release to Apple, more usability enhancements are in the works.

UPDATE May 16th:

Apple rejected the update claiming that without network connectivity the screen stays black. That’s not possible because GeoCorder has a Default.png image and there is no network activity unless the user sends a track via e-mail. I tested the app on my iPhone 3G on 2.2.1 and iTouch 3.0b5, with and without network. No black screen.

But to be safe I ran Clang Static Analyzer over the code for 2.0 and even 3.0 and found a couple of unused variables, a mismatch between unsigned and signed and one code file that was not even used. So I cleaned those up and resubmitted.

UPDATE May 21st:

Apple rejected it again this time with an even more annoying message. But this time is the first time that they actually provide some information how I can fix it.

Your application, GeoCorder, cannot be posted to the App Store at this time because it does not adhere to the iPhone Human Interface Guidelines as outlined in iPhone SDK Agreement section 3.3.5.

When the device is not connected to a network, GeoCorder does not load its contents. When the user is on the “Record GPS Tack” screen the App fails to load location (please refer to screen shot). This behavior might lead to user confusion. It would be appropriate to display either a notification or an alert stating that internet connectivity is required.

Please take a look at the Reachability iPhone program sample which demonstrates the use of the System Configuration Reachability API to detect the absence of WiFi and Wireless Wide Area Network (WWAN) services. Your application can then take appropriate action at the first point where network services are required.

Translation from convoluted to plain English: In Airplane Mode the iPhone does not get Core Location updates. Now why do they think of this NOW on the THIRD version I submitted to them for review?!

SECOND UPDATE MAY 21st:

I finished the app (once again) and submitted it to Apple with these enhancements:

  • I revamped the inner workings of the blip graph so that it can show recieving of Core Location updates independently from whether the user chooses to record them or not. Non-recorded blips are grey, recorded ones are red.
  • Position updates are now active as soon as the recording modal screen is opened and are deactivated as soon as the screen is exited.
  • Implemented connectivity sensing according to Apple’s suggestion. If you enter the recording screen without internet connectivity you get an alert to that effect.
  • I made a nicer splash screen, because having it look like the final recording table view would anger users because it would look like for the time of loading that the app does not react to user input.
  • Also I submitted a new free version of GeoCorder which will be sponsored by AdMob. It’s technologically identical to original GeoCorder.

I’ll update as soon as they get through.

UPDATE May 24th:

I received a crashing bug rejection (for a change *G*) for GeoCorder [FREE].

Thanks to the attached crash report and detailed instructions on how to reproduce the crash I quickly found the problem and fixed it. I had a dangling object reference to previously released memory. This would show if you recorded a track, removed it and tried to record another. Since both GeoCorders share the same code I had to replace the binary for regular GeoCorder as well.

Apple is getting faster, at least with newly submitted apps. I’m glad Apple Reviewers are working on Saturdays as well to work through new apps. That can only mean that they have multiple shifts, because Saturday is not a regular work day in the USA.

UPDATE June 16th

Apple had approved the free version rather quickly but the regular version was stuck “in review” even though it contains exactle the same code and functionality minus the ads. I wrote to Apple two days again and now finally the regular version became available as well.

This Certificate Has Expired

Has it been 6 months already?

My development and distribution certificates expired much to my surprise while I was sitting on the train. Well actually it had expired the previous night, but it only transpired to me the first time I wanted to Build&Go while en route to Vienna. Which mildly annoyed me at first, but then I found that I can backdate my computers clock two days and restart XCode to allow for temporary continuation of some on-device testing.
Certificate has expired

To renew my certificates I logged into the program portal which already knew that I “currently do not have a valid certificate”. I used the keychain’s certificate assistant to generate the requests saved to disk and submitted them to apple for countersigning.

One thing that confused me was that now the name of the development certificate contains some additional string. I thought that maybe that was appended because I did not remove the expired certificates first, but even when I redid the whole process I did not get rid of it. Another surprise courtesy of Apple.

Read more

The Death of Global Variables

c0der asks:

I currently implement global variables by defining them within the AppDelegate.h file (outside of class definition) and then include this file in each ViewController.m that needs access to these variables.

This works just fine but I’ve noticed that after saving/restoring these variables as persistent data (NSUserDefaults), their values seem to change over time.

My question: is this approach the right way to handle globals without encapsulation? I use a lot of ‘C’ data types — int, char, etc. for my global variables (rather than NSInterger, etc.) so I’m not sure if there’s a better approach.

My short answer: DON’T. Globals are EEEEVILLLLLL. Why not create an engine class for your app that you use as shared instance. Define all your “globals” there.

Read more

Should I Release Outlets?

bqbqhaha asks:

Let me ask you something as below.

  1. A variable declared as IBOutlet could be released?
  2. A variable declared as IBOutlet should be released?

I search for this issue many times, but still the answer is not found.
plz help me , plz

He is asking a question that most of us have when beginning with Interface Builder and Outlets. In plain English his question is “Should I release instance variables declared as IBOutlet?”

Read more

Wife Widowed, Kids Orphaned 'cause Daddy's got a Mac

(Note from editor: When Dr. Touch is not coding or in surgery he preaches the Mac gospel and sometimes somebody hears the calling and switches. This article illustrates this, the title where his own words on twitter.)

Jayman888Thanks to Dr Touch for the opportunity to make a contribution to his blog. I’m a new MacBook user and have had my gorgeous new white MacBook for 48 whole hours. I’m writing this with it sat on my lap. I’ve decided to give it a name ‘Polo’. I don’t know if the meaning will translate into other countries, but in the UK a polo is a small, white mint and is cool.

I’ve been a PC Windows user all my life; I’m 38 now and started using computers on a regular daily basis in the early to mid 90’s. One of the main reasons for the switch is the slow ‘Applefication’ of my life. It started as I replaced an MP3 player with an iPod shuffle, and then an iPod Classic and then I replaced my mobile with an iPhone.

Read more

MyAppSales 1.0.4

I woke up early and was looking for something useful to do with this extra time that would not take too much brain power. This minor update to MyAppSales addresses a pressing issue and some internal cosmetics.

  • Before this fix the local timezone would be used when interpreting a report date. This could lead to unexpected behavior when travelling and synching reports in an earlier timezone. Now all report dates are interpreted as from timezone “America/Los_Angeles”, which is the timezone of Apple in Cupertino.
  • Cleaned up code of iTunes Connector class as a result of making the exchange rate class a shared instance, ordered the functions therein in a more logical way and added section titles for clarification.
  • Now for finding out if a report already was downloaded only the date and type is used. Before this change also time was used but this would change with different local timezones causing duplicate entries.

Refresh your copy from the customer-only SVN to get this update.

UPDATE: WAIT with updating if you have previously existing entries!!! You will get duplicate entries.  (see third fix above. Let me know if you need help cleaning up duplicate entries from your database)

Don't mention SDK/OS 3.0!

If you have any kind of updates that you are publishing right now, please don’t make the mistake of mentioning something like “made compatible with OS 3.0″. A developer friend of mine had his application update rejected because of this.

If Apple Reviewers see such a statement you will get rejected with a lengthy reply stating that the next version is confidential and you are in breach of paragraph §2.1 SDK Agreement.

“…Apple may provide You with pre-release versions of the SDK that constitute Apple Confidential Information and are subject to the confidentiality obligations of this Agreement.”

It will save you a week if you don’t do the above.

Minutes after I posted this heads-up on a forum I was seconded:

I can confirm this too. Got all our apps caught in this trap.
Don’t mention 3.0. anywhere! =P

So in summary you have to make sure that your apps run on a OS 3.0 device, but you cannot mention that you took this effort in the release notes because even mentioning OS 3.0 is illegal. Coming to think of it, I have mentioned OS 3.0 now 5 times, I hope that Austria is to far off for Apple lawyers to serve me a cease and desist.

“But I meant it well! All in the interest of the community!” will be my famous last words when I will get dragged off to jail.

Date Closest to 'NOW'

Nagarajan asks:

I have needed a SQLite query that returns exactly a time which is very closest to the current time.

From 7:00pm,8:00pm, 9:00am and 10:00pm if the current time is 8:30pm, I will require 10:00pm.

This is more of a SQLite question than related to Cocoa Touch. But since SQLite is the mobile database engine of choice for Cocoa Touch, I’ll entertain this question as well. And follow it up with some Cocoa Code.

Read more