Reputation: 61
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?
Upvotes: 2
Views: 844
Reputation: 61
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.
Upvotes: 1