I had uploaded my app to the App Store but it was rejected two times, with the reason being that the app is crashing on iPhone 4 (iOS 4.3.5). I have tested my app on the same version but I can't make it crash.
My app is getting user location for drawing a path on g-map. I have also tested with location service enable/disable, wifi on/of. For all these ways I have tested, my app is not crashing.
After symbolicating my last crash report I have found location and that is in cellForRowAtindexpath:
if([finalarray count]>0)
{
cell.shopnamelbl.text=[[finalarray objectAtIndex:indexPath.row] valueForKey:#"name"];
cell.distancelbl.text=[NSString stringWithFormat:#"%#km",[[finalarray objectAtIndex:indexPath.row] valueForKey:#"distance"]];
}
else if([unsortedarray count]>0)
{
cell.shopnamelbl.text=[[unsortedarray objectAtIndex:indexPath.row] valueForKey:#"name"];
cell.distancelbl.text=#"";
}
else
{
cell.shopnamelbl.text=#"Loading...";
cell.distancelbl.text=#"";
}
return cell;
in above code on cell.shopnamelbl.text=#"Loading..."; this line is the cause of my crash, but in my testing everything works perfectly. I am not seeing a crash anywhere else in my app.
So now what can I do to fix this?
There's nothing obviously wrong with the code you've posted, so it's likely to be some other difference between what you've been testing and what Apple have on their handsets.
On first run, their device will have nothing in NSUserDefaults set, nothing in the keychain, nothing in the Documents directory. You need to completely wipe your device of any trace of previous runs of your app. Deleting and re-installing isn't enough.
It might also be worth trying on a number of devices. It's possible that you've inadvertently made some assumptions about how long certain operations take which don't hold on the faster/slower/different handsets that Apple uses for testing.
Related
I'm trying to implement a gamecenter aware app targeted to iOS 6. To give some info on the environment I'm working on mac os 10.7.5 with XCode version is 4.5.2 and xcode is running iphone and ipad simulator version 6.0. The problem is I cannot connect to gamecenter in sandbox mode neither through ipad or iphone simulator, but the same code works as desired while testing in my iphone.
I followed the gamecenter programming guide in apple's developer library and I got this atm it is called from applicationDidFInishLaunching in appdelegate:
- (void)authenticateLocalUser:(UIViewController *)currentViewController
{
if (!gameCenterAvailable) return;
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
if (viewController != nil)
{
[currentViewController presentViewController:viewController animated:YES completion:nil];
}
else if (localPlayer.isAuthenticated)
{
NSLog(#"Player authenticated");
}
else
{
NSLog(#"Player not authenticated");
}
NSLog(#"Error: %#",error);
};
}
It outputs:
Error: Error Domain=GKErrorDomain Code=2 "The requested operation has been cancelled."
UserInfo=0x8690510 {NSLocalizedDescription=The requested operation has been cancelled.}
GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.218:4398";
"gk-commnat-cohort" = "17.173.254.220:16386";
"gk-commnat-main0" = "17.173.254.219:16384";
"gk-commnat-main1" = "17.173.254.219:16385";
}
I already tried hosts file fix though my OS is not 10.8.2 but it didn't help. https://devforums.apple.com/thread/168811?tstart=0
Any idea what can be the possible cause?
Edit: Well, it turns out the output part starting with GKSConnSettings does not indicate any problems, that's the regular output while connecting to game center as I understood from what I read over internet. I printed the actual error message (GKErrorDomain = 2 ...) inside the authentication block.
I got the inspiration from : https://stackoverflow.com/a/8115807/837244, and decided to log in to game center account with a different piece of code. So in viewdidload I normally called:
[[GCHelper sharedInstance] authenticateLocalUser:self];
Now I commented that out, accessed game center through below URL scheme, logged in to my account and after that logged out.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"gamecenter:"]];
And lastly reverted back by commenting out URL code and using the original code. Now it works fine, I guess the problem was that a game center account was already hooked up in simulator and it denied every login request bc of that. Hope apple goes clearer with error messages, it took a month to fix such a simple issue, may this help to others.
I know this question references specific Xcode and iOS simulation versions, but if your simulator is already logged in one account, and you don't mind losing whatever data you've got on the simulator (chances are small, but you never know), you can simply reset the settings and data on it.
Go to:
Simulator -> Reset Content and Settings...
...and confirm the action when prompted.
This is certainly true for Xcode7.x running an iOS 9.x simulator, someone else might be able to verify whether it's true for earlier versions (especially as I've unearthed quite an old question and answer).
Animal451
Necrothreadomancy: +1
I met a strange problem about IOS which I can't find the way to fix.
I'm developing an App on iPhone.
It works fine when I run it in Simulator or on my iPhone device.
It works fine when I shut down my iPhone and restart the iPhone.
But it can not be opened after my iPhone's is power off, still can't be opened after the iPhone has been charged.
But when I reconnect the iPhone to the Xcode without reinstall it, it can be opened.
I don't know what the problem is and what worse is that I can't debug it cos it works fine when I debug it.
I think that must be a CoreData problem and I did something in the applicationWillTerminate method:
(void)applicationWillTerminate:(UIApplication *)application {
....
NSError *error;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Handle the error.
}
}
}
What else am I supported to do? is there some delegate method like applicationWillTerminateWhenPowerOff to let me save the CoreData ? Or am I lose something ?
Update:
I fix it now. After checking the device log in organizer of Xcode, I find out the reason why it can't be opened.
It miss the SenTestingKit frame.
You probably have a bug in applicationDidFinishLaunching or another routine called when your application starts up.
First check for crash logs in Xcode's Organizer with the device connected.
You could also put some logging code in all of your UIApplication delegate routines to see which routines (if any) are getting called and perhaps throwing an exception. NSLogger is a nice utility for that since it can log from an iPhone to a Mac over WiFi.
Hello I am planning to develop a simple iPhone game. I would like to be able to distinguish between a genuine crash, and the user killing the app ( by double tapping home screen and long-clicking it to kill it) .
Can someone please shed some light on what exactly happens when the user kill the app through the multitasking bar.
If your app is in the background and suspended when the user kills it, it will receive no notification. This accounts for the majority of cases.
If your app is currently running in the background (there are only very specific categories of apps that can do that), then it receives applicationWillTerminate.
Indeed, Apple is very clear as to the fact that you should save any relevant data before entering the background. Have a look at this (chapter "Responding to Application Termination"):
Even if you develop your application using iOS SDK 4 and later, you must still be prepared for your application to be killed without any notification. The user can kill applications explicitly using the multitasking UI. In addition, if memory becomes constrained, the system might remove applications from memory to make more room. If your application is currently suspended, the system kills your application and removes it from memory without any notice. However, if your application is currently running in the background state (in other words, not suspended), the system calls the applicationWillTerminate: method of your application delegate. Your application cannot request additional background execution time from this method.
EDIT:
about the "saying sorry" thing...
you can certainly do that on the next launch. simply store a key in NSUserDefaults and remove it when the app enters the background (I hope all this sounds familiar to you, otherwise look into the UIApplicationDelegate protocol).
when the app starts up, you check the key; if it is there, then the app was not closed by the user; if the app is not there, then the user at least moved the app to the background and did not experience any sudden termination...
For iOS6 and later there is a way to do this. A side effect of State Restoration is that it will delete the state when there is either a crash during restore or a user manually kills the app. You can use this to your advantage to detect a user manually killing the app.
From the documentation:
Be aware that the system automatically deletes an app’s preserved state when the user force quits the app. Deleting the preserved state information when the app is killed is a safety precaution. (The system also deletes preserved state if the app crashes at launch time as a similar safety precaution.) If you want to test your app’s ability to restore its state, you should not use the multitasking bar to kill the app during debugging. Instead, use Xcode to kill the app or kill the app programmatically by installing a temporary command or gesture to call exit on demand.
The following code assumes that you already have a BOOL for crash detection called _didCrashInLastSession. There are different approaches for getting this value such as this 3rd party library. In your code call the method [self getLaunchType] to see which type of launch you are dealing with and act on that accordingly. Put the following in your AppDelegate.m:
typedef NS_ENUM(NSInteger, LaunchType) {
LaunchTypeUnknown,
LaunchTypeNewInstall,
LaunchTypeNormalLaunch,
LaunchTypeCrashedLastSession,
LaunchTypeUserManualQuit,
};
static BOOL hadStateToRestore = NO;
static NSString * const kAppHasEverRunKey = #"appHasEverRun";
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
// Called when going into the background
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAppHasEverRunKey];
[[NSUserDefaults standardUserDefaults] synchronize];
return YES;
}
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
// Called on start up
hadStateToRestore = YES;
return YES;
}
- (LaunchType)getLaunchType
{
if (_didCrashInLastSession) {
return LaunchTypeCrashedLastSession;
}
if (![[NSUserDefaults standardUserDefaults] boolForKey:kAppHasEverRunKey]) {
return LaunchTypeNewInstall;
}
if (!hadStateToRestore) {
return LaunchTypeUserManualQuit;
}
return LaunchTypeNormalLaunch;
}
Update: At least one 3rd party SDK breaks this technique: Urban Airship.
You can do it through your device also.
Connect your device to your machine.
Run xcode and go to organizer.
There select your device and device logs.
There you can also see crash logs of your app or game.
I have a weird problem that hopefully someone could shed some light on.
I have an ipad app in the AppStore that was released when 3.2 was the only
available iOS for ipad. App ran fine on this iOS but as soon as 4.2.1 came out for ipad
and some of my users therefore updated to the new iOS the app now crashes when a
certain UIBarButtonItem is pressed. In the interim from iOS 3.2 to when iOS
4.2.1 came out i submitted no updates so it was the exact same app running on
each iOS yet i had this problem only on 4.2
After symbolicating in Organizer and viewing the Distribution build crash report
I am able to at least see the line of code that is causing this...
while(i < [filteredData count]) {
thats it!!...just a simple check during a while loop. The last thing in the crash
log points to the above line of code....
filteredData is a NSMutableArray that is definitely allocated/initialized at
this point. It is actually used in another piece of code before this with no
problems.
Again, this line of code gave my app no problems on iOS 3.2 but on iOS 4.2.1 it
causes EXC_BAD_ACCESS (SIGSEGV)
When i install the app on my device via xcode with a debug or release config it works perfect but when installing from AppStore (distribution build) it crashes and only on 4.2!
Just to clarify.....
app works perfect on debug AND distribution modes on 3.2
app works perfect on debug mode on 4.2 BUT app crashes on distribution mode on 4.2
Any thoughts? .....cuz i'm confused/lost
Thanks for taking the time
Possibly an optimisation made by the compiler in Release builds causes this, especially as you dont get the issue in Debug
Can you refactor to...
NSUInteger count = [filteredData count];
while(i < count) {
Or is filteredData mutating in the loop?
NSUInteger count = [filteredData count];
while(i < count) {
blah;
blah;
count = [filteredData count];
}
I have an iPad application that builds and runs perfectly the first time. But if I exit the application and open it again, the interface is completely unresponsive. If I exit and open another time, it never gets past the splash screen.
What's strange is that if I wait a minute or two before opening it again, it always runs fine.
Any ideas on what might be going on or where I should start my debugging efforts? I would throw in breakpoints and see what's going on, but by the time I start the application a second time, the debugger has already exited. Is there a way to keep the debugger and console running through multiple executions of an app?
Thanks,
Luke
Edit: Here's some code I use for NSUserDefaults - could this be the problem?
In viewDidLoad in my main view controller:
bgnum = [prefs integerForKey:#"bgnum"];
menuVisible = [prefs boolForKey:#"menuVisible"];
songTitles = [[NSMutableArray alloc] initWithArray:[prefs arrayForKey:#"songTitles"]];
numberOfSongs = [prefs integerForKey:#"numberOfSongs"];
In viewWillDisappear:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setBool:menuVisible forKey:#"menuVisible"];
[prefs setInteger:bgnum forKey:#"bgnum"];
[prefs setObject:songTitles forKey:#"songTitles"];
[prefs setInteger:numberOfSongs forKey:#"numberOfSongs"];
[prefs synchronize];
I'd look at what's happening in your initialization code, loadView, didFinishLaunching, etc., and trace it out. It's easy to get 3 or 4 methods deep in that stuff and do too much there when some of it should be lazy. With out more information or any sample code it's all wild guesses. One such guess is user defaults or anything that you're loading from a file or dictionary up front? I could see how something there could cycle through several states.
There's a big difference between "exiting the application and opening it again" which in context implies you are doing it rather quickly and "waiting a minute or two".
I have a rather large application that I develop on which routinely takes several seconds to "unload" on the iPad, which results in me rapidly exiting and re-entering causing the application to appear in a partially configured state, and causing unusual behavior.
This could be due to the fact that your application hasn't completely dealloc'd and closed its threads out, and thus when you launch it again quickly, the thread is resumed (and on 3.2 or earlier, will be unstable since it's already started killing itself off).
Do some timings... see what the threshold is for "it crashes" and "it works". If it's more than 10 seconds, then I would say something is wrong. Less than that, and you could be seeing what I just described,
With the device connected, run the app in debug mode from xCode and then exit the app. Now, disconnect the USB cable and run your app again - is it completely frozen? If you rotate the device, does your view orientation change? Once the app is terminated, plug your USB back in and go to xCode->Window->Organizer.
You should see your iPad device on the left of the screen. Select it and you should see some tabs on the right for Console and Crash report. Select your app from the dropdown and look to see if any console messages have been logged, or if a crash has occured - you should get a stack trace if it did which should help.
I once had a similar problem when I had NSZombieEnabled as an active argument in my executable, so that could be worth investigating too.