I have noticed that when performing native debugging on Xcode 4 if I have my app installed, then delete the app, then attempt to debug again from Xcode 4, the time it takes to perform the step "Transferring package" is pathologically slow. Has anyone else experienced this? I dread deleting the app as it will take 20-30 minutes to load the app.
Our app has lots of user files that get deleted when app is deleted. Perhaps some sort of sync-like process is running at same time. Killing Xcode 4 does not fix the issue.
I think now you must use Xcode 6.3 and it will allow you to do everything in easiest way. Here this version of Xcode is most stable version I have worked with for last few years.
I would like to offer some general guidance on this as the symptom you see can have many causes. In fact most versions of Xcode have had these symptoms for differing reasons in my experience.
I've seen the slow transfer problem before (Xcode 4 I think), when I switched my app to be an app that could run in the background. To get around that, I would either force kill the app from the phone itself, or I would change the bundle id of the app when deploying it (as a hack).
68cherries commented on seeing the problem after profiling. Doing profiling of a device generates a lot of data on your Mac, and perhaps also on the device but I don't know. So its worth switching phones with another phone, ideally one that has a lot of free space; does the problem follow the phone?
Sometimes deploying has a problem when resources are missing; resources are rebuilt upon clean. Try pressing the option button and then doing a clean - it cleans intermediate files. (option-shift-command-k). This can happen in particular when you delete a resource but still reference it from a story board. Going through the story board looking for exclamation mark warnings is helpful (particularly with Apple Watch apps).
Periodically it is worth doing a resource file audit. Quite often we deploy files not actually needed by the target device. For example, bash script files, old icons, etc. The fewer resources, the fewer things that can be incorrect, and can often trigger an idea about what has changed with your resources that might explain the problem. It also makes the deployment smaller for your customers.
Note with this problem its worth debugging it from both sides. For example, look at your Mac console logs to see any errors, or your activity monitor for unexpected behaviours and tasks. On the device side, its worth installing iOS console from lemonjar.com to see if anything got to the device end and if there were errors there.
Related
I am going to launch my app on the AppStore and I would like to keep track of crashes and fix them as soon as possible. If possible, it would be nice to collect also some additional information about user activity and other useful stuff.
In order to do so, I have looked for some crash reporting tools and the most interesting ones I have found are: TestFlight Live, QuincyKit and Crashlytics.
Among those three, QuincyKit should be the lightest one but the other two seem to be quite interesting since they provide more sophisticated reports and other interesting stuff.
My goal is to have as many information as I can on any issue the user can experience, but at the same time I don't want to make the app slower or consume more resources.
In your opinion and from your personal experience, which of these tools is the best one (taking into account my goal and my needs)?
By using TestFlight Live or Crashlytics I would make my app too slow?
Is there a risk to overload the device?
Reports provided by QuincyKit are precise enough? How many information can I retrieve from them?
Thanks!
Here is what I decided:
I am using Crashlytics for crash reporting (yes, it seems to be really great) and TestFlight for tracking user activity (checkpoints are really useful to find out what users generally do and figure out what the tendency is).
I followed the instructions written here
I honestly think Crashlytics is a better solution than Testflight for crash reporting.
Here's what you get with Crashlytics that you don't get with the others.
Duplicate culling (TF does this too, but its not too great at it, Crashlytics is damned near perfect)
You can actually mark crashes as closed/resolved, and get them out of your list for a given version.
Crashlytics does everything TF's Crash reporting does, but better and then some (logging, stack traces, etc.)
Percentage of affected users, and the numbers that go with that. (ie: should i fix the bug that happened to one guy, or the one that's happening to 10k?) Testflight doesn't tell you this.
Prioritization based on occurrence. This is probably the most important gain in my opinion.
These are just a few, but I figure they're probably the most important ones for you.
We used Testflight's crash reporting for close to 2 years on an extremely popular app (several million D/Ls). Its definitely better than nothing, and very convenient if you're using TF for distribution as well, however you get many more benefits from Crashlytics. We switched to Crashlytics this summer and now we're actually able to manage crashes and make smart decisions about what to fix and when, instead of just sifting through a giant never ending list.
I see you already accepted an answer, but I'd seriously give it another look even if you opt to continue with Testflight. I've found its hard to really grasp what you're missing until your app has shipped, at which point is even harder to change.
Crashlytics is second to none for crash reporting.
We were in the same boat as you trying to find the best crash reporting solution. After some thorough investigation and test runs of TestFlight, HockeyApp, and Crashlytics, we originally chose HockeyApp because they allowed us beta distribution along with crash reporting on both iOS and Android (we wanted both in one solution for both platforms). However, HockeyApp's exception backtracing was just not giving us any additional crash details. This is where Crashlytics shines. Their exception backtracing is amazing. Period.
So here's my summary of all 3 SDKs:
Crashlytics
#1 crash reporting
#1 exception backtracing, bar none (provides very useful extra crash details)
Extremely fast and lightweight
Custom key logging for additional crash context
Best duplicate crash recognition and culling
Automatic SDK updates (Their Mac app automatically updates the Crashlytics iOS SDK in your project)
No beta distribution (I'd love a one stop solution for crash reporting and beta distribution)
Automatic build server support
TestFlight
Somewhat heavy, and adds bloat to your app package
Great beta distribution
No Android support (at least when we tested back 6+ months ago)
HockeyApp (HockeyKit - Beta distribution, QuincyKit - Crash reporting)
Lightweight
Crash reporting UI a bit confusing
Exception backtracing severely limited (at least when we tested in March of 2011)
Very good beta distribution
All that said, we chose Crashlytics for crash reporting, and HockeyApp for beta distribution. But you must chose what works best for your needs.
Definitely recommend Crashlytics as well.
TestFlight Live has given me issues in the past. It seems every time I go to use TestFlight, it is down anyway.
Crashlytics is awesome. Here's why:
Adding it to your project couldn't be easier. There is a Mac app that does most of the hard work for you.
Automatically updates itself
Prioritizes crashes for you
Provides handy stats like OS and device percentages as well as average memory available, etc
I use Crashlytics in all of my applications. I added it to Hipstamatic when I was there and the data we got was shocking. It really helped improve our product. I also tried TestFlight Live and quickly removed it after the first beta since it was causing crashes.
Crashlytics is awesome. You should use it.
If we're only talking about crash reporting, Crashlytics is far better than TestFlight. (Never tried QuincyKit, so I can't compare the 3 options)
We've been using Crashlytics for over a year on Weddar and it has been great. Having tried other solutions before I have to say that before installing it I was kind of suspicious of the great features they were stating, but the installation was indeed done in about 5 minutes and it only added around 40-45Kb to the app.
The crash reports are incredibly detailed making it really fast to pinpoint solutions for the bugs and the updates to the sdk are pretty steady and stable. The team is incredibly supportive too. I remember that we had a problem with the new ARM7s when iPhone5 came out and they solved it in about 30 minutes.
I use TestFlight for user beta testing management so I've tried TestFlight Live SDK in the summer just to see if it was a solution to have all integrated in one service, but we had a really bad experience with it. I had 2 updates rejected in the App Store Approval for the first time (Weddar was launched in April 2011) and we lost about a month trying to catch the bug. When LIVE beta testing, no user would complain about any problem, we "solved" it by removing the TF SDK. Never quite understood what was the problem. We contacted TestFlight team and never had contact back. (Another big big detail is that TF SDK added about 800Kb to our app.)
So, even if I still use TestFLight for beta testing, if you're looking for a great and lightweight crash reporting SDK, I definitely say that you should use Crashlytics.
Hope this helps.
I'd say go with TestFlight (Live)
In my experience the TestFlight SDK won't crash/slow-down your device and has very versatile crash reporting - allowing you to debug reported errors fairly accurately.
TestFlight also doubles-up as a feedback package for when you're testing in-development.
It's also a pretty light SDK.
To be more specific (in answering your list of questions):
TestFlight allows you to scalp for user 'checkpoints' and has its own version of NSLog that allows you to dynamically log events at runtime.
Your app wouldn't slow down as network requests are handled off the main thread.
I don't understand why a device would get overloaded by using either of the SDKs you've mentioned.
QuincyKit reports seem reasonably precise, however you need to make up your own mind about the precision you need - you can find QuincyKit docs here.
I started noticing that it was taking several minutes (5-10) to build and run apps on my iPhone 4S from Xcode. I was running XCode 4.5.2 and iOS6.0 on my 4S and decided to figure out the problem. There was another similar question posted here but it was closed without a definitive answer. (which is a shame since this is a valid concern for folks.) I am reposting the question to explain what I observed. Hopefully it will help someone.
First I rebooted my Mac after several impatient attempts to install a relatively small app seemed to hang. I tried removing all of my old provisioning profiles from my Mac and my iPhone thinking I was having trouble with expired certs/profiles. I tried a few more times and decided to let it just hang to see what happens. It eventually launched the app on my device after about 5-10 minutes. I Googled around and found some hints that maybe I should try rebooting my iPhone and re-synching with iTunes. (I had already made an unsuccessful attempt at synching which also seemed to take forever.) On my next attempt to synch I decided to remove some larger apps (700+MB) to clear space since I was down to my last GB.
Things were still slow so I decided to reboot my iPhone and then re-synching it. I rebooted my phone and went to sync in iTunes again and this time the sync went quickly. I had cleared an extra 3+GB leaving me about 4+GB of free space. I restarted XCode and my app is now installing quickly.
My take-away is such that I believe there may be extra daemons running over time on the device and restarting my phone is what ultimately helped restore install times. Also, I'm not sure if clearing space helped or not. I would like to know what the root cause/solution is but that depends on others having similar experiences and responding.
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.
I have an iPhone app that's been in development for about 2 weeks. We recently tried the "release" version of the build on a device, and to our great unhappiness, it crashes in one of the views with an "EXC_BAD_ACCESS".
This crash only occurs on devices, and only in the "release" build. Not only that, but it only happens the first time the app is launched! It is also 100% reproducible.
We have removed the small block of code that deals with data persistence, and have tried re-openning Xcode, cleaning the project, deleting and reinstalling the app, etc., as some other questions suggest.
Do you have any advice for a) what might be causing this problem, and b) how to go about debugging if it only happens in "release"?
Thanks
It turns out there was no problem in the code at all.
The reason it was crashing was that Xcode was trying to attach the debugger to the release build for some reason! We are still trying to figure out why, because we have checked the most obvious places, but I'm sure it won't be too hard to track down.
The build works fine if you install from iTunes or the Xcode organizer instead of building and running from Xcode directly, so it won't affect your end-users at all, as long as you are careful to check for other first-run issues.
We can only guess what the cause might but if it's 100% reproducible, then it should be a good candidate for some fprintf-style debugging.
Figure out the most probable place for the error to occur, and start putting "Got past xxx view initialization" style statements in to start narrowing the problem. It's tedious, but eventually, you'll get there.
In theory fprintf statements could affect the problem. However, it's rare that it does so, so it's a good place to start.
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