I have compiled 2 static libs of same code-base, one for simulator and one for device. I would like to know, whether should i submitted both libs to Apple.
Or can I create a universal static lib, which can run on both Simulator as well on Device. Is it recommended by Apple to submit only universal library ? How can I produce that ?
Apples don't care about code for iOS simulator and thats shy when you build application for submit, binary for i386 architecture won't be compiled by default and that's correct behavior. Just build for device and submit it, everything will be OK.
Related
The current AppStore version of my app is seeing crashes for hundreds of users, where bundled frameworks cannot be found. This didn't come up in testing, and I've been unable to reproduce the problem, whether on the simulator or a device, regardless of whether I wipe the device clean and to a fresh install, or install over an existing version.
The error log I've obtained from a user indicates:
Dyld Message: Library not loaded: #rpath/OMGHTTPURLRQ.framework/OMGHTTPURLRQ
Referenced from: /var/containers/Bundle/Application/BB320110-3C64-4772-9A3A-208F4CAD84B5/PicTapGo.app/PicTapGo
Reason: image not found
However, upon review, that framework certainly IS included in the actual bundle that was sent to the App Store, in the Frameworks folder. In the Xcode project, Runtime Search Paths includes '#executable_path/Frameworks', and that's where the frameworks are bundled.
This is the first time we've linked against a dynamic lib (which is a must, because the lib includes Swift code), so it's possible (likely, even), that I'm missing something crucial about embedded frameworks here.
Again, the strange thing about this is that I can wipe my iPhone clean, and reinstall this version from the App Store, and the error does not occur. In every configuration I've tested (including with our beta testers), the library loads just fine. This means that the framework is missing for only SOME users. Further, there doesn't appear to be any rhyme or reason to the failure. It's happening on all manner of iOS devices, on all versions of iOS 9 (though I don't see any iOS 8 crashes listed in the Xcode organizer). I've been completely unable to reproduce the issue, but for affected users, it happens consistently.
Any idea why only some devices would be unable to find a bundled framework? Does the App Store monkey with your bundle configuration in some circumstances?
After some investigation, it appears that the libraries did indeed disappear. Snooping the actual library binaries that were shipped to the App Store, they ended up only getting built for arm64. Still working on how this happened (maybe some CocoaPods weirdness), but this neatly explains the dyld failures in the wild. For arm64 architectures (iPhone 5s and later), everything is A-OK. For the 4s, 5, 5c, and older iPads, dyld couldn't find the lib. Apparently, the App Store strips out non-compatible architectures when they process the app, and that portion of the bundle is just plain missing on armv7 devices. Looking at the crash reports available, none of them are on arm64 devices.
All of the "library not found" crashes, with a log like the one noted above, are on iOS9. There are similar crashes on iOS 8, but with a different message. I'm assuming it's the one I'm able to reproduce locally ("no suitable image found... Did find <somelib>: mach-o, but wrong architecture"), and this dovetails with the idea that iOS8 devices would get the full fat binary. Lib would be there, but no arm7.
This failure wasn't evident during normal development. I use an iPhone 6 as a primary testing device, and my beta team is apparently all on newer devices as well. I had relied on the simulator to test on older devices. It looks like that's a Bad Idea™ for at least one reason I can cite now. In the future, I'll be testing on an actual, factual armv7 device before sending things into the world.
So, for anyone experiencing dyld failures in the future, this is one more thing to look for. Will update this if that doesn't turn out to be the case.
EDIT: One more tidbit from the autopsy, for posterity - The way we ended up with arm64-only in the AppStore build is by bundling the debug version of the library, not the AppStore version. I bundled the frameworks by creating a new Copy phase, and dragging the frameworks from the Products group of the CocoaPods. However, the actual binary you get when configuring a copy phase that way depends on which scheme you currently have active. If you have a Debug scheme active, you get the debug build of the library. If you have an AppStore scheme active, you get an AppStore build. This is a hard-coded path in the Xcode project, and regardless of which scheme you choose for your main project's build in the future, you'll be bundling the version you originally dragged.
By default, Debug builds only build the active architecture, meaning the Debug libraries were missing armv7 support.
I have a Xcode project, that includes a Static Library project, that uses another static library that does not support the iOS simulator architecture (Vuforia SDK: libQCAR.a).
Vuforia SDK documentation states:
Vuforia applications must be deployed to a device to run; they cannot be run in the iOS simulator.
This is my project structure:
MyApp.xcodeproj
Classes
MyStaticLibrary.xcodeproj
Classes that depends on libQCAR.a
Frameworks
libMyStaticLibrary.a
libQCAR.a
My problem is that MyApp.xcodeproj does not build for the iOS Simulator because libQCAR.a is not built for the i386 architecture.
Is there anyway to make MyApp.xcodeproj ignore the libQCAR.a library when building for i386? I would be able to disable all the code that depends on the library with #if !(TARGET_IPHONE_SIMULATOR)
You can use a conditional build settings to specify the library you want to link only on a given platform, instead of adding the library to your project in the usual ways. Specifically, you will need to specify:
-lQCAR
in "Other Linker Flags".
Have a look at the attached image that should make things more clear (in the picture I am linking only for the simulator, you will want to select a device, I guess).
Also, do not forget to add the path to the directory containing the library to "Library Search Path" build setting (this does not need to be conditional; it would not do any harm on the simulator).
This issue seems very similar to: Xcode: Conditional Build Settings based on architecture (Device (ARM) vs Simulator (i386))
I believe sergio's solution is very close, but have you tried specifying the full path to the library under Other Linker Flags (potentially without "-l" - just the path)?
In my case, it should specify clearly which SDK uses which flags.
So in Any iOS Simulator SDK, you should not include the library.
In Any iOS SDK, you should include it. In my case, it's -lCloudReco.
I have an SDK to achieve some special stream of video but I've got only the binary of this, I think this was built for arm7.
I have an app built with this library and it runs great on iPhone 4, 4s and iPad 2 but when building for iPad 4th generation with an arm7s xcode shows lots of errors about files being ignored.
I'm pretty sure it's the architecture cause changing the build architecture the errors appear and disappear.
Is there any way to make this work? I mean build for new architectures having only binaries files of the old one?
Unfortunately not. To build your app for armv7s all the code – which includes said library – has to be built for it. There is a hack to add armv7s support to static libraries but I would strongly recommend against using it.
That being said, for now it's not a big deal if you're building your app for armv7 only. It will still work fine on the iPhone 5.
Just go into the build settings of your Target and set "armv7" as the only architecture your app should be built for.
At one point in the future Apple will probably require that all new apps / app updates will be built for armv7s, like the did with armv7 a few years ago, but for now it's not a problem. By then the developer of the static library will hopefully have provided an update.
I have noticed that, due to a load of libraries, I could reduce my app size a lot by removing the i386 symbols. However I am unsure if this is acceptable from an Apple review point of view as I heard they test in the simulator.
Am I crazy for thinking about removing this support to make my apps smaller?
A device build does not include i386 support. If you have libraries that are compiled for i386 exlude them from the final build process (remove them from the target, so they wont be copied to the app bundle)
Your final build shouldn't be including that stuff. They don't test in the simulator. Lots of applications won't work in the simulator, such as anything requiring in-app purchases or Game Center integration.
I have an iOS fat static library (iphoneos & iphonesimulator), if I was to use this during an app submission would it fail on the grounds that the binary includes iphonesimulator code?
I think there is no problem. When you link your app for device it simply embed the code for the architecture your are using. So your app compiled for device does not embed code for simulator.