iPad Simulator (4.3) crashes with dyld error - iphone

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.

Related

Is it possible an xcode archive is corrupted without letting me know? WEIRD iOS 4.x behavior

I have an app on the iphone app store that has a very bizarre bug. It has to do with a user dragging an image around the screen. On iOS 5.x it works beautifully. On iOS 4.x it does not work (only lets you drag on a diagonal). The bug is disastrous because it prevents the user from continuing.
Anyways, there should be no reason why the code acts differently between 4.x and 5.0 (no deprecated methods were used or anything). And when I started testing for the problem I realized that the code I compiled and submitted to apple built onto my iphone actually works perfectly on 4.2.
So, the app store version of my app exhibits the weird bug explained above on 4.x and not on 5.0, but the app does not exhibit the bug WITH THE SAME CODE when built from xcode to my device. How is that possible? Could the compiler have messed things up?
Resolved. This was the issue was with armv6 and the LLVM 3.0 compiler with CGPoints. See here: Apple Dev Forum

XCode 3.2.3 running on iOS3 - Wired framework

I looked around on Stack Overflow and I didn't find the solution of a strange problem.
I started developing a project on XCode 3.1 then I decided to upgrade on XCode 3.2.4 and targeting iOS3 iPhones. I then followed the topics dealing with that and I changed the Base SDK to iOS 4.1 and the target os to 3.0. Everything worked fine until I made changes to my project.
Indeed I added CoreMedia.framework to my project.
It worked well on simulator, but crashed at launch on the iPhone. Here is the log I can get:
<Notice>: dyld: Library not loaded: /System/Library/Frameworks/CoreMedia.framework/CoreMedia
Referenced from: /var/mobile/Applications/72F009B5-82A8-49DC-A5CD-708EE1A4553C/myapp.app/myapp
Reason: image not found
(I had the same problem with other frameworks like CoreVideo for example)
I tried on an iOS4 iPhone and it worked well, so I think XCode doesn't link/copy the right framework on the iPhone. When I get info on a framework under XCode, here is the path I get:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk/System/Library/Frameworks/MediaPlayer.framework
But I get the same path when I get info on a framework of the first version of the project (when I was using XCode 3.1). It sounds like the new frameworks added have a wrong reference.
Does anybody have an idea of how to solve this problem? Any help would be greatly appreciated. :)
You have to weak link your libraries.
On xcode go to targets-> right click get info. on General tab on the lower section you will see your libs, change the CoreMedia type to be weak.
Ofcourse the lib won't be available on os3 so you'll need to add checks in your code so you wont call the lib on os3

Weak linking to support previous iOS versions

I'm trying to support older iOS versions in my app. I initially thought I only have to set those frameworks to "weak linking" that are not present in the older OS, e.g. the iAd framework. And then make sure that I don't call unsupported APIs in the code. However, when I try to run the app (which is compiled with the most recent framework) in the old simulator, it crashes during startup with a message similar to
18/07/2010 11:07:29 UIKitApplication:xxxxx[0xe006][5729] dyld: Symbol not found: _OBJC_CLASS_$_NSAssertionHandler
18/07/2010 11:07:29 UIKitApplication:xxxxx[0xe006][5729] Referenced from: xxxxx/Applications/23CE4978-D25F-4DB4-A486-0730EBBB501B/xxxxx.app/xxxxx
18/07/2010 11:07:29 UIKitApplication:xxxxx[0xe006][5729] Expected in: /Xcode3.1.4/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
18/07/2010 11:07:29 UIKitApplication:xxxxx[0xe006][5729] in xxxxx/Applications/23CE4978-D25F-4DB4-A486-0730EBBB501B/xxxxx.app/xxxxx
After setting all frameworks to weak linking, I still get an error message:
18/07/2010 11:33:32 UIKitApplication:xxxxx[0xc4a7][8204] dyld: Symbol not found: __objc_empty_vtable
18/07/2010 11:33:32 UIKitApplication:xxxxx[0xc4a7][8204] Referenced from: xxxxx/Applications/23CE4978-D25F-4DB4-A486-0730EBBB501B/xxxxx.app/xxxxx
18/07/2010 11:33:32 UIKitApplication:xxxxx[0xc4a7][8204] Expected in: /usr/lib/libobjc.A.dylib
What am I doing wrong?
I think I found the solution (please can someone confirm this?):
You cannot use the simulator to test if your apps run with a previous iOS version. It only works on the device, according to Apple:
iPhone OS Note: Mac OS X v10.6 does not support using iPhone
Simulator SDKs prior to version 3.0.
In addition, when building with the
simulator SDKs, the binary runs only
on the same OS version as the SDK, not
on earlier or later versions.
This seems really dull. How am I supposed to test backwards compatibility without having one physical iPhone for each SDK version? Not good.
You can't use the new class directly if you want to support old platforms. Instead, you use NSClassFromString like so:
class myClass = NSClassFromString(#"NSCoolNewClass");
if (myClass)
//do stuff

NSXMLParserDelegate and iPhone SDK 3.1.X

I have an app on the store which was built for 3.1.2, but which was crashing under 4.0GM. I've fixed the crash problem using Xcode 3.2.3, but was also getting warnings that such-and-such class did not implement NSXMLParserDelegate. I added to the headers and everything seemed fine. I've now submitted the app and it's waiting for review. This latest version was compiled with base SDK of 4.0, and a deployment target of 3.1.2.
The problem I have is that this morning I opened up the project in Xcode 3.2.2, and when building against base SDK of 3.1.2, I'm getting compile errors saying that NSXMLParserDelegate does not exist. Does this mean my app that is waiting for review is going to crash under 3.1.2 devices? This is strange, because my beta testers who are using 3.1.3 and I think 3.1.2, said the app works fine. Shouldn't it crash if it can't compile against base SDK of 3.1.2?
I think this should be ok to discuss in regards to the 4.0 NDA, as my problem is specific to 3.1.X.
First of all, the NDA has been lifted this week, so no problem to discuss the iOS 4.0 SDK.
As for your question: there's a difference between compiling and running an application.
The NSXMLParserDelegate protocol was added in the iOS4 SDK. In previous versions of the SDK, the XML parser delegate methods were declared in a category. In iOS4, these methods have been moved to a dedicated protocol, which makes it a litte cleaner. At runtime, there's no difference. Once compiled, the app doesn't know anything about protocols or categories. The NSXMLParser will simply check if a specific delegate method is implemented (via respondsToSelctor), so it will run just fine.
In general, it's not a problem to build with iOS4 SDK and run on 3.0. You do have to make sure you don't call any methods that don't exist in 3.0. This is very easy to do by calling respondsToSelector. It allows you to create a single app that runs on all OS versions, but still allows you to call 4.0-specific methods.
I hope this makes sense ...

IPhone OS4 feature link error while run on OS3.x

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.