I've compiled an app with IPhone base SDK 4.0, deployment target on iPhone OS 3.0. This app contains OS 4.0 new feature: local notification.
It works well on iPod 2G with OS 4.0; however it crashes every time the app start up on iPhone 1G with OS 3.0. It appears to be runtime reference error:
"dyld: Symbol not found: _OBJC_CLASS_$_UILocalNotification
Referenced from: /var/mobile/Applications/73A3FAB1-63AE-4A71-8C6B-932142A728FE/Tapatalk X.app/Tapatalk X
Expected in: /System/Library/Frameworks/UIKit.framework/UIKit"
If the UIKit framework is different between SDK3.0 & SDK4.0, why it doesn't report while compiling? How can I apply local notification feature on this app, while the app can still running on devices with OS3.0? Thanks.
This answer solved the problem for me:
That error is being triggered because
you didn't weak-link the UIKit
framework. The UIKit framework in
iPhone OS 3.2 added the
UISplitViewController, and if you link
it in as normal your application will
assume those symbols exist on 3.0,
where they don't.
To weak-link a framework, find your
application target in Xcode, inspect
it, and go to the General tab. At the
bottom of that tab should be a list of
frameworks, with a column for Type.
Change the Type for UIKit from
Required to Weak and rebuild your
application. That should take care of
the runtime errors.
This seems safe to me, given that UIKit is always going to be on the devices we're targetting.
If you use a 4.0 SDK feature and you want to support 3.0 devices, you need to check that the functionality exists before you use it.
If you're using a new class (as you are) something like the following should work:
Class localNotificationC = NSClassFromString(#"UILocalNotification");
if (localNotificationC) {
UILocalNotification* localNotification = [[localNotificationC alloc] init];
// do stuff
[localNotification release];
}
else {
// what to do with the 3.0 SDK
}
As for why the compiler doesn't tell you, well, you told the compiler that you were using the 4.0 SDK and those classes/methods work on 4.0.
I found this information really useful. However my question is how to test if the application crashes or not after this change.
The background is I had the same issue with my iPad application. I have my BaseSDK set as 4.3 and Deployment target is 3.2. I never got this crash while doing ad-hoc provisioning and running the app on 3.2 iPad and it got approved by Apple too. But users reported that when they started the application after download on iPad 3.2 it crashes before showing the main screen even.
I was using [UILocalNotifition alloc] in my code which I think could be the result of below crash:
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x00000001, 0xe7ffdefe
I seem to have fixed this by converting the above statement as per Stephen's suggestion.
However I really don't know how to test it. I am not getting any crash earlier too while testing the application before submission on 3.2 and currently also I am not getting any crash on start up.
I really need to validate this fix before I push the update to app store. Could someone please shed more light on how to test this? It would be really helpful if I can reproduce this crash with the previous version of my application and the same is not the case with current version after this fix.
Related
I'm running an application in an iPad Simulator (4.3) that crashes due to a missing symbol error:
dyld: Symbol not found: _OBJC_CLASS_$_NSMetadataQuery
Referenced from: /Users/Me/Library/Application Support/iPhone Simulator/4.3.2/Applications/B13BE6DF-61B9-4C23-98E7-BEC72330FF19/iPad.app/iPad
Expected in: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
in /Users/Me/Library/Application Support/iPhone Simulator/4.3.2/Applications/B13BE6DF-61B9-4C23-98E7-BEC72330FF19/iPad.app/iPad
At what point in the launch process does this error occur? I don't seem to be actually executing any code - I have placed breakpoints at both the locations where this class would be instantiated (which is never executed when version is < 5.0) and at the delegate method applicationWillFinishLaunching:
But, the crash occurs before either points are hit.
I know that the underlying issue is that the NSMetadataQuery class was added in iOS 5.0, but I would of course like to maintain backwards-compatibility with earlier versions. (I'm using the proper NSClassFromString calls.)
I have an iPhone application which uses NSMetadataQuery on iOS 5.0, and skips it if running 4.3 or lower, and works properly in the simulator. Thus, I'm confused as to why this particular program crashes.
Does the NSMetadataQuery class actually exist in the iPhone version of iOS 4.2 and 4.3, but not in the iPad version? (And the API simply wasn't exposed until iOS 5.0?)
The underlying issue was that the Foundation framework was strongly-linked in the iPad version of the application (that was crashing) and was weakly-linked in the iPhone version. (Which allowed the iPhone version to run without requiring those classes at linking time. Of course, calling/instantiating any of those classes on 4.X versions of the iPhone simulator would have similarly crashed.)
Problem was solved by changing (under the Project Info in Xcode) the dependency option of the Foundation.framework from required to optional.
I've got a couple of applications in the App Store at the moment which I've had ready after the release of iOS4. If I try and download one of these in the App store on a 3.x device, it will tell me I need to upgrade. Is there a way to make my application not do this, as I don't think I am using any API calls specific to iOS4.
I originally thought that this could not be done but I just now installed 'Plants vs Zombies' and 'Angry Birds' on my iPod Touch (running 3.1.3) so it must be possible as I'm sure these have released updates recently, and being in the top5 games, I would have thought they were developed using the iOS4 SDK. I am hoping it is just one value somewhere but if anyone could let me know how to do it that would be awesome :).
Easy. Open up your project info.
Find this line "iPhone OS Deployment Target" select 3.0
You can still develop with the latest xcode and current 4.0 SDK, but if you dont make any 4.0 calls this should allow you to weak link to 3.0+ and allow apps to work.
You really should test this on a 3.0+ device to see if it works though. You can still set your Base SDK to 3.2 or 4.0.
I was just wondering if anyone knows of any articles relating to upgrading an iPhone application from 3.0 to iOS4. (Thanks for this iWasRobbed).
While the application still runs on iOS4, it will not run on the iPhone 4, but does on my iPhone 3G.
When I deploy the app on the iPhone 4, the Default screen loads and it will sit there hanging. The only inclination towards a problem I get is this warning:
warning: UUID mismatch detected with the loaded library - on disk is:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk/System/Library/Frameworks/UIKit.framework/UIKit
warning: UUID mismatch detected with the loaded library - on disk is:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk/System/Library/PrivateFrameworks/DataAccessExpress.framework/DataAccessExpress
Thanks
James
James,
Apple has provided this checklist: http://developer.apple.com/iphone/checklist/
It generally should not be that big of an issue. Typically, you just set the baseline SDK as 4.0 and the deployment target as either 4.0 or something 3.0+.
If it is not running on an iPhone 4, you may wish to explain further what specifically it is doing or not doing when you attempt to run it on that device. Keep in mind that all apps (for the most part) that were designed to run on 3.0 and above will typically run well on an iPhone 4.
There might be some issues with deprecated methods, so make sure you resolve those prior to installing and running the app. You should get a compiler warning for any of those, if not check your target settings and there should be a checkbox for it.
Other than that, I'm not sure what else would prevent you without understanding further details of your project.
As additional information, you should really look into the WWDC 2010 video called "Future Proofing Your Applications" (watching it now :)
That is most likely a mismatch between what iOS your iPhone 4 is running and what SDK you're using in Xcode. The UUIDs are mismatched because the iPhone 4 is using a different version SDK to what you've coded in.
Solution, install the latest SDK and make sure your iPhone matches this. The latest out is 4.1
I had the same problem and think I have solved it because the problem has gone away.
Firstly I deleted the build folder. Then I Installed the latest version of ios (4.1 in this case) onto my iphone through itunes. Afterwards i installed the latest xcode and iphone sdk package from the apple devlopers site.
This in itself probably fixed the problem but just to be sure I added a new provisioning profile for the phone on my computer and everything worked great afterwards.
Hope that helps
I am dealing with an old code designed for iPhone OS 2.0. In this code I have some instructions that we deprecated on iPhone 3.0.
I am not willing to change the version because I have many customers, specially on iPod Touch, that are still using 2.0. If I update the instructions they will be unable to continue receiving the updates.
The application is compiled for 2.0 and always have been like that.
I have submitted a new version for Apple, where some bugs were corrected and new functionality was added. I have always sent this app to apple and they never complained. Now they rejected the application telling me that it is crashing under OS 3.1.3.
I've followed their instructions but I don't see any crash and the part of the code that uses the "deprecated" function works perfectly on 3.1.3.
Compiling the project for 3.1.3, I see a yellow warning on Xcode telling me that one instruction was deprecated on 3.1.3.
The big question is: will this instruction work on 3.1.3 and should I ignore this warning?
Can this make the iPhone crash?
In my mind, all new versions of the iPhone OS keeps back compatibility with older versions, so, as I think, any application compiled for 2.0 will run on 3.1.3 and all versions up.
As you see, I have tested this on 3.1.3 and the application works perfectly.
How can that be? Any ideas?
thanks for any help.
Deprecated calls are designed to work in the OS release that they became deprecated in, but stop working in some (undefined) future OS. The deprecation is a warning to developers: Hey, you should change your code, this WILL break in the future. It's a way to update the API-base without breaking everyone.
In summary, you're okay to use these calls now, but you'll want to edit the code should you ever decide to ditch 2.x operability.
I'm writing an iPhone app that needs direct access to the camera. Since it is in-house, I have no qualms about using the full set of headers and private frameworks.
I included and the PhotoLibrary framework in the application. It compiles for the 2.0 firmware, and I can put it on the device and run it. As soon as it is started, however, it quits and returns to the home screen.
I think that the PhotoLibrary framework is somehow not being loaded or something similar.
I would post some debugging output, but I don't actually have the phone yet.
Thanks!
That might or might not be the problem. The iPhone simulator lets you get away with a lot of stuff that doesn't work on an actual device-- there's any number of classes that a simulator app can use that don't exist on the phone (e.g. NSXMLDocument, available on Mac OS X and iPhone simulator but not actual iPhones). Get the phone, run the app, and use Xcode to look at the phone's system console to see why it's crashing.
Thanks for all the help.
It turns out that I was trying to use classes from the iPhone 2.0 SDK with an iPhone that has 2.2.1. Thus, it would compile correctly when I set the device to 2.0 in Xcode, but would fail on the iPhone because the old classes were no longer there.
I fixed my problem by getting the classes from the 2.2.1 SDK. Now my program runs fine on the iPhone.