WhereAmI app crashes when reopened from background on iPhone


#1

I just realized that I originally posted this in the forum for the old book the first time. Maybe know one looks at that forum anymore since I got no replies, so I am posting here too. Very frustrated trying to figure this out. Can anyone help with this?

I have the WhereAmI app working and left it on my phone to show the wife and family I am learning stuff. It is exhibiting a regular crashing behavior though. Here is what happens…

When you first open app and run it it does fine,
If you hit home and then open it again within just a few minutes it does fine,
If you leave it in the background then reopen more than a few minutes (say like 5 or more) later it crashes.
You can then reopen it then and it does fine but the pattern repeats.

I have double checked all my code with the book and looked on the errata page but can’t figure out what could be wrong. The Xcode organizer shows logs for all the crashes but I don’t know how to read that yet. I was starting to wonder if since this is just a learning project app, not meant for real use, maybe it is missing something that makes it multitask/background/reopen??? correctly? I am using Xcode 4.1 on Lion with iPhone 4 running iOS 4.3.4. I would be grateful for any assistance anyone can offer. I’m willing to up load my code or crash log also. Thanks!


#2

I have downloaded the example code from the book and it has the same error. It must be that something has changed in iOS since the version the book was wrote for and the code just needs updated, or possibly a legit iOS bug. I am afraid I am just to new at iOS dev to figure it out and don’t wish to waste anymore time on this problem. Gonna move on to the next chapter and project.


#3

When you exit an application by hitting the Home button, the application is still running. If the OS shuts it down in the meantime, Xcode still keeps the debugger attached to it. When the OS shuts it down, it issues a kill signal to it. The debugger sees that SIG_KILL and halts there. Thus, you are seeing the OS acting appropriately.

You should shutdown an application when you are done debugging it by clicking the Stop button in Xcode.


#4

Thanks for your reply. Why does it do this even when I disconnect and try to run the app on the iPhone again hours later? When Xcode builds and deploys the app to the iPhone am I not getting the same build the real finished app would install?


#5

Disconnecting an iOS device while Xcode still has a debugger attached to an application is very bad. You’ll get all sorts of issues that won’t let you build and run on your device if you do this.

I imagine it has something to do with the application being halted by the debugger, but you are trying to open it up again. If you want to run the application later without Xcode, make sure to kill it from Xcode by hitting the stop button. Then, you can unplug it and launch it whenever you like.


#6

Thanks again for your reply. I am afraid I have already tried making sure I did as you described to the exact same results. I have even been able to recreate the crash in the simulator under the exact same circumstances. I also posted on this on stackoverflow(stackoverflow.com/questions/6811 … anding-thi) you can view my crash log and the exact error msg there. It was sending a sigabrt exception and stating that region was in valid. Is there something that needs to be done to reinitialize that variable on resume of app?


#7

This crash log is telling you that an exception is being thrown:

8   libobjc.A.dylib                 0x35fdbc84 objc_exception_throw + 64
9   CoreFoundation                  0x3504d3c6 -[NSException raise] + 2

Check the console (in the debugger area if it’s still running in Xcode, or the device’s console log in the organizer) - what exception is being thrown? That is the most important piece of the puzzle.

Also, the guy telling you to cast it to double or float is talking nonsense. The compiler already does that for you; you can ignore him.


#8

I will run it tonight and watch the console again. When I looked as I simulated it in the simulator previously, I would press the simulated home button wait a while then click to open the app. The debugger said that [worldView setRegion:region] was being passed an invalid region. That really didn’t make sense to me because it sets the region just fine when you open the app the first time, and it even tracks you down the road when driving and running it on the phone. That’s why I thought maybe the variable region needed reinitialized when returning the app to the foreground or something. Tonight I’ll hook up the phone and recreate the crash and then copy and paste the results here. Thanks for the tip about the number conversion and the patience with a frustrated rookie!


#9

Okay I recreated the crash on the iPhone with Xcode debugger running. Here is the console output. Aside from the assumption that the variable region seems to be invalid for some reason, although it worked before, I have no clue what is wrong or how to fix it.

sharedlibrary apply-load-rules all
target remote-mobile /tmp/.XcodeGDBRemote-156-32
Switching to remote-macosx protocol
mem 0x1000 0x3fffffff cache
mem 0x40000000 0xffffffff none
mem 0x00000000 0x0fff none
[Switching to process 11779 thread 0x0]
[Switching to process 11779 thread 0x0]
2011-07-30 21:33:10.132 WhereAmI[765:707] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Invalid Region <center:-180.00000000, -180.00000000 span:+0.00226092, -0.00224579>’
*** Call stack at first throw:
(
0 CoreFoundation 0x3682a64f __exceptionPreprocess + 114
1 libobjc.A.dylib 0x33a83c5d objc_exception_throw + 24
2 CoreFoundation 0x3682a3cd -[NSException dealloc] + 0
3 MapKit 0x312dfcb9 -[MKMapView setRegion:animated:] + 324
4 WhereAmI 0x000027ff -[WhereAmIAppDelegate mapView:didUpdateUserLocation:] + 218
5 MapKit 0x312e51bd -[MKMapView(UserPositioningInternal) resetUserLocation] + 148
6 MapKit 0x312e4755 -[MKMapView(UserPositioningInternal) locationManagerDidReset:] + 28
7 CoreFoundation 0x36797f03 -[NSObject(NSObject) performSelector:withObject:] + 22
8 CoreFoundation 0x367d52f9 -[NSArray makeObjectsPerformSelector:withObject:] + 400
9 MapKit 0x312d7809 -[MKLocationManager _reportLocationStatus:] + 40
10 MapKit 0x312d77d5 -[MKLocationManager _reportLocationReset] + 20
11 MapKit 0x312d8d2b -[MKLocationManager reset] + 94
12 MapKit 0x312bb0a9 -[MKLocationManager applicationResumed:] + 68
13 Foundation 0x34be2183 _nsnote_callback + 142
14 CoreFoundation 0x367f920f __CFXNotificationPost_old + 402
15 CoreFoundation 0x36793eeb _CFXNotificationPostNotification + 118
16 Foundation 0x34bdf5d3 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
17 UIKit 0x3576a727 -[UIApplication _handleApplicationResumeEvent:] + 906
18 UIKit 0x35614e27 -[UIApplication handleEvent:withNewEvent:] + 2730
19 UIKit 0x35614215 -[UIApplication sendEvent:] + 44
20 UIKit 0x35613c53 _UIApplicationHandleEvent + 5090
21 GraphicsServices 0x35f4ee77 PurpleEventCallback + 666
22 GraphicsServices 0x35f4ef01 PurpleEventSignalCallback + 16
23 CoreFoundation 0x36801a79 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 12
24 CoreFoundation 0x3680375f __CFRunLoopDoSources0 + 382
25 CoreFoundation 0x368044eb __CFRunLoopRun + 230
26 CoreFoundation 0x36794ec3 CFRunLoopRunSpecific + 230
27 CoreFoundation 0x36794dcb CFRunLoopRunInMode + 58
28 GraphicsServices 0x35f4e41f GSEventRunModal + 114
29 GraphicsServices 0x35f4e4cb GSEventRun + 62
30 UIKit 0x3563ed69 -[UIApplication _run] + 404
31 UIKit 0x3563c807 UIApplicationMain + 670
32 WhereAmI 0x000025f3 main + 82
33 WhereAmI 0x0000259c start + 40
)
terminate called after throwing an instance of ‘NSException’
(gdb)


#10

Hi,

I think it might be a timing issue. I guess iOS does some cleaning up when the app goes into the background and when it becomes active it hasn’t got around to updating the location yet.

try adding this to the beginning of didUpdateUserLocation

    if (![userLocation location])
    {
        NSLog(@"Location not available yet");
        return;
    }

HTH
Gareth


#11

I will try that when I get home. Feel free to correct me if I’m wrong, but as I understood from the book the UIMapView is using it’s own controlled instance of a location manager. I thought the location manager we created for the project only ended up being used for the annotation.


#12

Hi,

Yes - mapView is using it’s own location manager under the covers and this is keeping track of where we are as we set showsUserLocation to YES.

The app is also creating another location manager specifically for the annotation and this is only updating when we return from the textField.

HTH

Gareth


#13

Yes but isn’t didUpdateLocation: in the delegate for the annotation location manager or does it function for both? If it’s just for the annotation I don’t think your idea will fix my problem as it happens when the mapView is setting the region around it’s locationManager. I think?


#14

Apologies, please disregard my previous questions. I just looked at the code and remembered there is a didUpdateLocation for the map view. Just had a duh moment, and I was at work without the code in front of me earlier. Your suggestion has fixed the issue I was having. I was thinking it was attempting to set the region before it had a valid region. When I follow the use pattern I originally described, after reopening the app it logs the location unavailable msg and returns early from the function twice every time, but then it updates the view and continues working properly. Do you think this is caused by a recent change in Xcode or iOS? I find it hard to believe this issue only exist for me, or that none else has had this issue. Any thoughts anyone?


#15

@Agent00Vic:
Hi! You’re not the only one, I experienced the same Problem. I would have posted earlier here, but my account was not yet activated.
It seems to be a MKMapView Bug, cos the “didUpdateUserLocation” should IMHO only be called, when the location data is valid. And that’s not the case! :astonished:
I logged the status of “location” and it’s NIL for two times, before it gets valid.


#16

Glad to hear it wasn’t just me. I spent a very frustrating week or so trying to get to the bottom of this. I was sure that I had followed the instructions in the book correctly but could not figure out why it kept crashing. I agree that it must be a bug and that didUpdsteLocation should not be called unless it does in fact have a valid location. Thanks for your reply and to all who assisted figuring this out! Now I can move on in the book. Since I’m kind of OCD, and want to make sure I learn to program iOS following all the best practices, I have really been stuck here trying to figure out what I could have done wrong.


#17

Yes, I would consider it to be a bug if the MKMapView send its delegate a message when there is an invalid location (especially since I can’t find a function for checking the validity of a coordinate region).

Gareth’s solution should work - it makes sure there is a user location object before using it.