Pre-release checklist before building final version for App Store - iphone

Curious what practices people have learned before making their final build and submitting to the App Store? Aside from switching from Debug to Release & commenting out calls to NSLog what other basic and/or not so basic things should we be watching out for?

This is a good question and I'd like to restate some of the answers and add a few of my own. I've made this answer Community Wiki, feel free to add to it.
Delete the app from your device, turn off WiFi, off cellular data, now install and test app. Does it work properly (as much as it can without Internet)? Does it at least tell the user that a network connection is required (if it is) or does it crash?
If you use CLLocationManager: Delete the app, fresh install and run, but do not allow app to have Location Data. Does the app behave well or does it crash? Does it at least tell the user that it can't run without location data (if that is a requirement)? Does it work on an iPod Touch that does all geo location using WiFi only?
Run the app in the simulator and for each view controller do the following steps: (a) From the iPhone Simulator menu select "Hardware" --> "Simulate Memory Warning", (b) now navigate around your app to other view controllers and see if everything is working, (c) repeat test for another view controller.
If you support older firmware (ie: iOS 3.1.3), install your app on a device running 3.1.3 and test it there (if you don't have one, use the 3.2 simulator).
Start your app while on a phone call or when Personal Hotspot is active. Are all the screen layouts correct (the status bar is 40px high instead of 20)? Did the bottom 20px of the view get pushed off the screen or did it resize correctly?
Accept a phone call while in your app, does it resign active and resume properly? Do sounds from your app stop playing while in the phone call?
Start your app while playing music, does the music continue to play? Do your sounds mix properly or fade the music appropriately?
Test performance on a slower devices with limited RAM such as: iPhone 3G (128MB RAM, 412Mhz CPU) or iPod Touch (1st or 2nd gen).
Run the Clang static analyzer and fix (or at least understand) every warning.
Make sure NSZombiesEnabled is NO in the environment variables (caution: not sure if this is still a problem)

A few things:
I actually recommend not creating a build configuration called "Distribution" as Apple specifies, because I often am creating ad hoc builds for beta testers. I create two build configurations, one called Ad Hoc and one called AppStore, so I'm not confused. The only difference between the two is the presence of the Entitlements.plist file for the Ad Hoc build. This way I can test as closely as possible what I will be submitting to Apple.
Most developers are optimists. That's why we are working weekends to create an app that we just know is going to make us a millionaire. Before submitting though, be a pessimist. Imagine everything that can possibly go wrong, and double check it.
Don't assume anything. Don't assume that that tiny little change you made to the app won't affect anything else. Murphy's Law says that that tiny change will cause your app to crash on all iPod Touches or something. Test, test, test thoroughly between the final code edit and Appstore submission. If you have to make a tiny change, then repeat until it's perfect.
Remember that if the app doesn't crash for 99.9% of your users, then 1 out of every 1,000 downloads will result in a 1-star scathing review.
I use Clang static analyzer, Leaks and Object Allocations during development, but I do an extra run of these tools before submission just in case.
If you don't have an older device, get one, because the 3GS performance is significantly better and you may miss some important performance issues.
Test your app with the following configurations when network or location are applicable:
iPod Touch
iPhone 3G
iPhone 3GS
iPhone in Airplane mode
iPhone with Wi-Fi
iPhone with EDGE
Call the phone while using your app

Instead of switching to Release, I switch to "Distribution". It's a copy of Release, but that's is how I got taught by some Apple doc and iPhoneDeveloperTips.
Important points:
After the final build, but before you rush off to zip up your app, open the bundle using the Finder's Show Package Contents. Due to some bug in the MacOS, which bit me in versions prior to Snow Leopard (and it might still be there), if you zip up too fast (using the Finder's Compress or Archive menu item), some of the resources have yet to be flushed out into the file. When you do a Show Package Contents, the contents get updated. The way you would notice this problem is that the size of your compressed app would be between a fifth to a tenth or less of the expected size. You might think to yourself, "hey, that zip utility really does a great job of compressing", but that's not the case. This problem would occur at this point instead of during testing mainly because you are doing a "clean all" build and all the resources and contents of the app bundle are starting out empty and then being filled by Xcode. And for some reason, even after Xcode is done creating the file, the contents are still not actually there, if you compress, but would be there if you looked at them (sort of a reverse Heisenberg). Beware.
Another area I spend a lot of time on is to make a nice backup of the sources, after I have committed all the latest changes to SVN, made a new branch, and tagged the file. I also like to have my version number match my SVN build/commit number so I always know which SVN version matches my release. I have those two version numbers in my info.plist and can be pulled up by the app user when they hit i for info. For example, a current info.pist includes:
<key>CFBundleShortVersionString</key>
<string>2.0a1</string>
<key>CFBundleVersion</key>
<string>346</string>
There are different thoughts on how to use the CFBundleVersion. This is my way. Also useful is the command line utility, agvtool.
Once the app is built, after compressing so you're not actually making any changes to the compressed version, go check the app file and make sure it is signed with the right distribution cert and not your adhoc one. Learning to use the command line utility, codesign, is helpful for this kind of checking and debugging. By making the compressed copy first, you ensure that you're not in any way going to change the final copy that Xcode has handed you and that you will upload to itunesconnect, if all looks well.
Other things to remember are the app icon, the various other icons and graphics you need for the iTunes store, the info.plist, and the fact that when the uploading of the app fails with a cryptic error message, it usually has to do with one of these pieces being missing from the compressed file you are building (those pieces that belong in the app bundle).

Look into this check list document # Github
https://github.com/bapu/AppReleaseCheckList

Related

How can I test my signed app on an unjailbroken iOS device

As part of our software development life cycle, we want to make sure that the binary we test in house before pushing to iTunes, is the same as the binary that we push to iTunes. I know that sounds really silly, but it's a matter of checks and balances in a mid size company, so that the testers can be sure the coders didn't add in anything after testing occurred.
So is there a way to run a signed/certed app on a device that's not jail broken? Or is there a way to verify that an IPW is the exact identical code in the zip that gets pushed to iTunes?
Or possibly a way to accomplish my goals with a different way?
We have a valid developer account and around 15 different devices that are not jail broken. Would prefer to test with them left stock and not jail broken.
If you compile your app for distribution using an ad-hoc profile you can later take that archive and resign it with the appstore profile and upload it.
You can't however upload an application that was compiled with an development certificate.
A binary signed to go to the App Store cannot be run on devices via the normal ways. You can test the code by having the developers create an Ad Hoc build. This will have the same functionality as the App Store version, but you can test it.
Unfortunately, when the app is recompiled for the App Store, more code can be added.
Do you not have access to the code to test? If you must, you can have them create an adhoc in front of you, test it, and then recompile for the app store all in front of you. Seems a bit overkill, however.
There is with another trick:
first test you code for functionality's, buggs in normal way.
Than push the code to AppStore, but set the release date farther with 3 weeks, while your testers are validating it is that what they tested last time or not. Somewhere here, I have read that possibility forgot where. Never tried!

Iphone app sharing file with iTunes problem

Somebody please help me out. This problem is killing me.
I went through tones of documents and posts. All seems to suggest that simply add a UIFileSharing key into info.plist and set boolean value to YES, files in App's Documents folder (not sub-folder, I know) will show up in iTunes.
However my problem is that I don't have an iPhone, so I really have no clue about what exactly the behaviors of both iPhone or iTunes will be when try to verify this file sharing thing. And what is the right way to verify this.
So when my client try to verify this off my watch (we are on different sides of earth), he keeps reporting back that file sharing feature not work. It is certain that file is properly stored under Documents folder.
In the last attempt, he claimed that he can see the app but not files.
I would like to know the following things, so I can guide him through this and end this pain:
Is it really plain and simple like add one key, no changes to code needed? Or did I miss something?
Are there any special requirements for building (like, only work for release build?), deploying?
What will really happen when plug the iPhone into the computer and sync with iTunes? Will the app show up in the Apps tab anyway, or only show up if file sharing feature are enabled correctly?
Thank you all.
Is it really plain and simple like add one key, no changes to code needed? Or did I miss something?
Yes
Are there any special requirements for building (like, only work for release build?), deploying?
No
What will really happen when plug the iPhone into the computer and sync with iTunes? Will the app show up in the Apps tab anyway, or only show up if file sharing feature are enabled correctly?
It will show up in the app view (on top) all the times. But you will only see them in the file sharing area if you have an app with enabled filesharing.
File sharing is only available on iPhone OS 4 onwards and iPad 3.2
Make sure your client has iOS4 or later.

Will building & running another iOS project disassociate existing provisioning or app id's?

I recently recovered from not being able to test on my device in Xcode. After much headache, it turned out that I only needed to uninstall/reinstall iTunes, but I'd certainly rather not do so frequently.
(See: prior thread)
The troubles seemed to begin after I built and ran some sample projects which obviously did not have my App id, etc. Is this always the case? Should I live in fear of compiling other projects that I haven't previously associated with my device and/or developer profile?
I'm not exactly sure if the App id/bundle/provisioning/keychain/whatever needs to be done per test ad hoc App or if it only matters that your device is provisioned and your plist matches what Apple has when you go to upload to the iTunes store.
I've run many samples on my device through Xcode and never had any issues. There's certainly no reason why this should happen.
It's hard to say "No, you shouldn't be worried" without knowing what the issue is, but it's not intended to break in this way, and it doesn't for most of us!

Unknown and unreproducible crash causes App Store rejection

After submitting our application several times, we continue to receive the following response:
Thank you for submitting My App to the
App Store. We've reviewed your
application and determined that we
cannot post this version of your iPad
application to the App Store because
My App is crashing on iPad running
iPhone OS 3.2 and Mac OS X 10.6.2. My
App crashes upon launch.
Unfortunately, crash logs have not
been generated.
However, resigning the same build with the AdHoc entitlements and loading the build onto the device yields no such crash. After a number of attempts, the application simply does not crash as reported by the reviewer. Furthermore, the reviewer does not provide any useful logging that may have been generated by SpringBoard such as an exit status or event if it had worked properly for any other device. There are no calls to explicitly exit or quit the application in the code line and yet the application terminates on startup.
What might cause an application to terminate in such a manner?
Under what conditions is an application tested that might not be found under a development environment?
Could it be a result of a signing issue that the submission validation system is simply unable to catch?
Thanks in advance.
After fighting with this for weeks, the application has finally been approved. The key: signing corruption. Hence why the application would start (or at least appear to start by showing the splash screen) and then suddenly vanish without a crash log. It failed Springboard's preflight sighing check.
A good tool to keep in mind to check for signing issues. It tells if the application has a valid signing:
codesign -vvvv MyApp.app
When I built the application, I would cp it to a network storage device where our product manager would pull it down and submit it to Apple. If decompressed on the NAS, the code signing was valid. But if you coped the compressed application back off the NAS and validate it, it would fail.
The lesson: make use of the new XCode utility to submit applications.
A few suggestions:
Try to use the leaks tool of the static analyzer to see if there are any memory leaks or problems your not seeing.
Does your app use a web service? This happened to me one time because the day Apple was reviewing the app the web service went down. That cause a crash. If thats the case you would want to add something to catch that.
Finally, In the logs Apple sent you did they send you the dsym file? If they did you can run atos from the command line and it will convert the address to symbols. That will show you what thread and symbol it's crashing on.
Be sure you test with a variety of settings: with Wifi disabled/enabled, with 3G disabled, Airplane mode on/off, location services disabled, etc.
As a last resort, assume there is a problem in your code that executes at startup. Remove half your startup code, set your release date in the far future (just in case it gets approved), then resubmit and see if they have the same problem. If not the problem is in the half you removed... it's a binary search.
I think you have two options: try harder to reproduce the defect using the tools other people are mentioning or to catch those crashes in the field.
PLCrashReporter will trap on an uncaught exception and store all relevant information. Next time your app is run, it can send the crash report that you can then symbolificate and view a stack trace of.
Ouch! That's a tough one. I've had this kind of thing happen before, but it seemed it was reproduce-able when I switched to a different device (iPhone 3G vs 3Gs, etc.). In your case though, it sounds like you're iPad only, so that might not help. There's a difference between 3G and Wifi, I suppose, but I would be really surprised if that was causing a crash on one and not the other.
One thing you could try if you think Apple's not doing their part is to change the binary name and re-submit it under another app name/record. See if you get the same response. If you get the same reviewer, you might, but I think there's a good chance you would get a different reviewer with a new app. Just set your app release date to some time in the distant future and it will never actually show up in the app store if they approve it. If the new app comes back rejected for the same reason, you've got work to do, but if they do in fact approve it, then I would get on the phone with them and point out the discrepancy.
My approach would be to make sure that the compilation is absolutely clean both in the static analyzer (this is NOT optional, it will save you time!) and for the build itself. Then set everything as described on CocoaDev' NSZombie page. Then make sure you have an iPod running 3.2 (actual hardware, not simulator) and test, test, test. Do it with network available and not available, with the device nearly full and freshly restored, every other variation you can think of. Run it with the debugger active and as a release build disconnected. Use Leaks, Instruments and all the other tools to peek in there and get a better feel for what is happening. If you exhaust every possibility you are going to have to beg for more detail from Apple but I bet you find a problem - one of the most important things in debugging an issue like this is to try to forget everything you think you know for sure and start at the beginning.

iPhone App fails to properly ??copy? database file ONLY with ad-hoc or app-store distribution and NOT in development mode

I just submitted this to Apple Support, but I'm wondering if anyone here has encountered something similar.
SUMMARY: my iphone app crashes when downloaded from the iTunes app store or from an ad-hoc distribution, but doesn't "crash" when run in debug mode on the simulator or on my iPod
DETAILS: The app contains a rather large sqlite database file (~180 meg uncompressed, 56 meg compressed). This may be relevant.
When launched, the application should copy the database (if necessary). After this, the user should be presented with a table-view containing approximately 6,000 rows. The information presented within these rows is derived from reading a table within the aforementioned database.
This all works properly when I run the application in the iPhone simulator and also when I run the application in debug mode on my iPod.
The app was approved by Apple. However, when users began to download the app through iTunes, I began receiving emails saying that the UITableView was not populated with any information. To investigate, I downloaded a copy of the app from the app store and I saw a similar result (i.e., UITableView is displayed, but the rows are empty).
I believe I am able to reproduce the problem using an ad-hoc distribution of my app.
The ad-hoc distribution behaves similarly (i.e. shows no rows in the UITableView) to the app-store download. Specifically, I have done the following multiple times (I delete and reinstall the application each time).
add my ad-hoc provisioning
certificate to iTunes
add my ad-hoc app build to iTunes
sync my iPod Touch with iTunes
start my ad-hoc app
app seems to always crash upon the first startup (i.e., the splash screen shows for a second and then I see the home screen of my iPod Touch)
second and subsequent start-ups of the ad-hoc app do not crash, but the UITableView is empty.
None of this happens when I run the app on the simulator or when I deploy in development/debug mode on the same iPod.
I have tried to examine crash logs associated with the initial crashing of the app (see step 5 above), but no crash log is created at that point in time. HOWEVER, a crash log is created when I sync iTunes with my iPod Touch, but it might as well be written in Polish.
So, it appears as though the app-store reviewers who approved my app only examined the behavior of the application using the simulator and/or in development/debug mode. It's possible that the issue is related to the large size of the database file, but this is complete speculation on my part. To the best of my understanding there should not be a limit on app-size or database size near 180 meg. This also wouldn't necessarily explain why the app works in debug/development mode.
Has anyone seen anything similar?
I think I figured this out (haven't tested it yet)...
Turns out the entire crash log isn't written in polish.
There's a part that says that the "application failed to launch in time"
I suspect that my database is too large to be copied during launch of the application.
to quote apple: ***iPhone OS uses a watchdog timer when applications are launched. If an application takes too long to complete its initial startup, the operating system terminates the application. Applications terminated for this reason will have the exception code 0x8badf00d and related information noted in the associated crash report:*
*When Xcode launches an application, the watchdog timer is disabled to compensate for additional overhead that may be incurred when Xcode attaches the debugger. As a result, your application's long startup may initially escape your attention if you are exclusively testing by running from Xcode.***