passforios
                                
                                 passforios copied to clipboard
                                
                                    passforios copied to clipboard
                            
                            
                            
                        IOS 12.X / app crashing
I'm using IOS 12.X and the app stopped working after the recent update. Is the build still correctly targeting all IOS version?
The app is crashing at the loading time, so I don't know how I can find some debugging information. Let me know how I can help you out to fix the issue.
The app is supposed to work on iOS 12 and above. Let me check what's going on here.
If possible can you switch to the TestFlight version, I'll see the crash log. Note that the TestFlight version is same with the open source master branch. I can just see some crash call stack, and no secret will be sent to the developer.
I just joined, and when I try to start the app, the same symptom happens. Dunno if you get any stack trace as it's pretty quick before it crashes and goes to the background.
I pulled a crash log from my device from the release build. (Xcode > Window > Devices > choose device > View Device Logs). Each crash produces this same log. From a quick skim it seems to be ObjectiveGit compiled against a too-new SDK version?
Hmm, when I run from Xcode I get
dyld: Library not loaded: /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit
  Referenced from: /var/containers/Bundle/Application/22452200-126E-4408-A5F8-D453C71B3A42/Pass.app/Pass
  Reason: image not found
Which makes sense because PasswordDecryptor.swift imports this iOS 13+ framework.
But then
dyld: Library not loaded: /System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit
  Referenced from: /private/var/containers/Bundle/Application/17E1DCD2-882E-438C-9138-2F8BA45A786D/Pass.app/Frameworks/YubiKit_3C81011B9560B8C8_PackageProduct.framework/YubiKit_3C81011B9560B8C8_PackageProduct
  Reason: image not found
Alas https://github.com/Yubico/yubikit-ios/issues/76
I am having this issue as well, on iOS 13. When I start the app, it immediately crashes and exits back to home screen. Let me know if I can help by providing any other info.
I'll jot down what I learned so far when I worked on this last weekend. I found 3 direct obstacles that need to be overcome to get the app working on iOS 12 again. After hacking around these I had a build that would at least display the password list.
- Pass.app links to CryptoTokenKit, an iOS 13+ framework.[^cryptotokenkitusage] Fixing this requires a simple change to mark CryptoTokenKit's linkage as "optional" (aka weak) in the Link Binary With Libraries build phase and ensure all uses are guarded by availability checks.^weakframework
- YubiKit links to CryptoTokenKit, an iOS 13+ framework, and to CoreNFC, a framework that is missing on some devices (iPhone 6 and iPod Touches at least). These should also be weakly linked.[^dontweaklinkbundled] Doing this also requires that on iOS 12 Pass does not call any YubiKit code that needs these frameworks.
- ObjectiveGit seems to have been compiled with flags that break iOS 12 compatibility. After getting past the above two issues when running from Xcode I see the ObjectiveGit crash I posted earlier. Removing ObjectiveGit then allowed the app to launch.
I am part of the way through resolving the second issue. However it's a bit of a headache.
Pass currently consumes YubiKit via SwiftPM. Package consumers can't control linkage of transitive framework dependencies (AFAIK). I thus tried to update the upstream package definition to weakly link to these frameworks. This is not a feature of the Package.swift DSL.[^spmlinkersettings] "Unsafe" linker arguments can be used to forcefully insert weak linking flags but then the package is unable to be added as a dependency except by pointing to a local checkout or a remote git branch.[^nounsafeflags]
So that made fixing the issue via SwiftPM seem unworkable. However when this problem was last discussed on the Swift forums an Apple developer said that manually specifying weak linking shouldn't be required anyway as Xcode should automatically decide to weak-link a framework when call sites of its imported symbols are all guarded behind availability checks[^jroseautoweaklink] (this is my understanding at least). (More on this later.)
I also took a detour to see if this problem could be solved more easily by switching to Carthage to manage the YubiKit dependency. Right now YubiKit upstream does not support Carthage as its build target is a static library instead of a framework. I forked YubiKit and replaced the static library target with a framework target[^yubikitfork] and Carthage worked. Then since Carthage uses the upstream project file I could manually mark the problematic frameworks as optional in YubiKit[^optionalpr] and the build worked. The main problem with this approach is that I don't know if upstream would accept this change to switch to a framework target. Also SwiftPM is the future etc.
So in summary I think there are a few potential paths forward:
- Figure out how to get automatic weak linking working. I started working on this using a development cycle of: build YubiKit, use otoolto check its imports, make code changes, repeat. I didn't get very far as I kept running into problems developing YubiKit in SwiftPM mode and as a static library. I'll try this some more using my framework target branch. Another possible route to understand this is by getting a small-as-possible fresh framework project to automatically weak link some system framework like CryptoTokenKit.
- Consume YubiKit project with manual weak linking via Carthage. This requires using a YubiKit revision with a framework target which would have to be a fork or discuss with maintainers to get upstream.
- Create some separate "Pass for iOS Light" app store build or something that excludes YubiKit from the app completely.
- Convince Apple to support weak linking in the Package.swift DSL. This would take too long. Also I have never heard back from Apple on anything ever.
[^cryptotokenkitusage]: https://developer.apple.com/documentation/cryptotokenkit and https://github.com/mssun/passforios/blob/955e50c3d3/pass/Services/PasswordDecryptor.swift#L9 [^spmlinkersettings]: https://developer.apple.com/documentation/swift_packages/linkersetting [^dontweaklinkbundled]: Don't make the same mistake I did and think that weak-linking to YubiKit itself would make sense. Weak linking only conceptually makes sense for system frameworks. It allows the linking process to proceed even in the absence of certain frameworks on disk. If we're talking about a custom framework bundled with the app, it's always present on disk. [^jroseautoweaklink]: jrose has explained this in https://forums.swift.org/t/weak-linking-of-frameworks-with-greater-deployment-targets/26017/8 and https://forums.swift.org/t/confused-by-unsafe-flags-being-disallowed-in-dependencies/27359/19. another apple employee has also said this in https://forums.swift.org/t/why-swift-package-manager-does-not-support-weak-linking-weak-framework-swiftui/31418/2 [^nounsafeflags]: https://forums.swift.org/t/confused-by-unsafe-flags-being-disallowed-in-dependencies/27359/2 [^yubikitfork]: https://github.com/bmwalters/yubikit-ios/tree/framework-working [^optionalpr]: related: https://github.com/Yubico/yubikit-ios/pull/86
I'll jot down what I learned so far when I worked on this last weekend.
Very impressive report! π
My honest opinion on this topic (app doesn't work on iOS 12) is actually that Pass for iOS should just increase its deployment target to iOS 13 (or even iOS 15 since it runs on all devices supporting iOS 13). The alternatives are a lot of work, potentially more forks of dependencies and again more frameworks built by Carthage. I'm actually very happy about the fact that we have ruled out Carthage dependencies almost completely. The setup of the project is way simpler with Swift Package Manager only. Especially for new contributors, this seems to be an important point.
Another point is security. For a password manager, it is important that the underlying platform is as safe and current as possible. An unsupported OS might have open doors which challenge all other components building on it.
Now some numbers: Apple reports that only 7 % of all iPhones are running iOS 13 or older. On the iPad side it's 14 %. I expect that the number of users who are not able to update to iOS 13 at least is very low.
Is offering support for iOS versions back to 12 really worth all the effort it may potentially cause? Isn't a simple project setup more valuable in the long run? Is it reasonable to run a password manager on a deprecated platform?
I figured out the ObjectiveGit issue. The fix is linked above. I still need to look into the YubiKit issue.
My honest opinion on this topic (app doesn't work on iOS 12) is actually that Pass for iOS should just increase its deployment target to iOS 13 (or even iOS 15 since it runs on all devices supporting iOS 13). ... Now some numbers: Apple reports that only 7 % of all iPhones are running iOS 13 or older. On the iPad side it's 14 %. I expect that the number of users who are not able to update to iOS 13 at least is very low.
iOS 12 is the terminal iOS version for ~300 million devices. From an e-waste perspective it is desirable to keep these devices useful as long as doing so is reasonably easy.
Another point is security. For a password manager, it is important that the underlying platform is as safe and current as possible. An unsupported OS might have open doors which challenge all other components building on it. ... Is it reasonable to run a password manager on a deprecated platform?
iOS 12 last received a security patch 4 months ago. Apple hasn't shown any signs of stopping said patches.
The alternatives are a lot of work, potentially more forks of dependencies and again more frameworks built by Carthage. I'm actually very happy about the fact that we have ruled out Carthage dependencies almost completely. The setup of the project is way simpler with Swift Package Manager only. Especially for new contributors, this seems to be an important point. ... Is offering support for iOS versions back to 12 really worth all the effort it may potentially cause? Isn't a simple project setup more valuable in the long run?
π on simplifying dependency management. I also agree that taking on more dependency forks makes the project harder to maintain. However I think more investigation is still required to determine what the best fix is for the YubiKit issue and to make a decision.
Hi, is there any progress on this problem.?
After reading some of above comments it seems some are suggesting to discontinue development for iOS 12, since most of the people using latest OS.
I support their suggestion but at least leave a working version behind so until upgrading our devices we can use that.
Itβs very difficult to use other device each time for getting passwords.
@ShahzarKibriya Yes. Just in the past few hours I made some real tangible progress.
I learned through experimentation that weak linking reads the availability annotations on individual symbols, not the availability annotation shown in Apple's developer documentation for the given framework.
This would be fine if not for the fact that some of Apple's symbols have really weird availability annotations likely because some frameworks were private/internal to Apple before later being released as public.
Take a look at CryptoTokenKit. Its framework-level availability (the iOS version it became public in) is iOS 13.0. But take a look at one of its symbols such as TKTokenSession. Its availability is iOS 10.0 (which is I assume when it was introduced internally within Apple).
The practical impact of this means that automatic weak linking does in fact work if the consuming code has a deployment target prior to the symbol-level availability annotations of the symbols imported from affected frameworks.
Thus ironically I was able to first fix this bug locally by lowering the deployment targets of both Pass and YubiKit (both had to be changed) to iOS 9.0. This version is before the availability annotations of CryptoTokenKit's symbols and is before the introduction of CoreNFC. Automatic weak linking then kicks in and
$ otool -L ~/Library/Developer/Xcode/DerivedData/pass*/Build/Products/Debug-iphoneos/Pass.app/Pass
...
	/System/Library/Frameworks/CryptoTokenKit.framework/CryptoTokenKit (compatibility version 0.0.0, current version 554.60.2, weak)
...
This means that there are at least 3 bug reports that could plausibly be filed with Apple:
- Fix the availability annotations in CryptoTokenKit.
- Make automatic weak linking take into account max(documentedFrameworkAvailability, symbolAvailability)to prevent what happened to CryptoTokenKit from happening in the future.
- Add explicit weak linking to the Package.swift DSL. The fact that these historical issues occurred means that SwiftPM should really have an escape hatch to force weak linking similar to the "Optional" framework setting in Xcode.
Now the next subject to address is CoreNFC. CoreNFC has a framework-level availability of iOS 11.0 and its earliest symbols also have that availability. There are also some symbols with an availability of iOS 13.0.
However Apple made an incredibly strange decision. CoreNFC.framework is not present in iOS 12 on devices without NFC support. Yes, everything we know about the meaning of availability annotations goes out the window due to this decision. The automatic weak linking system will happily strongly link to CoreNFC if your deployment target is iOS 11.0 or greater since the symbol annotations say it should thus always be available. But it isn't! The only ways to get around this problem are to have a deployment target of iOS 10.0 or earlier or to force weak linking of CoreNFC.
The CoreNFC debacle provides even better rationale for adding explicit weak linking to the Package.swift DSL.
Now what can we, the unsuspecting app developers using swift package manager along with these buggy frameworks, do?
Because weak linking appears to be determined on a per-swift-package (or per-swiftpm-generated-framwork) level, there is an interesting hack that we could do. We could create a CryptoTokenKitWrapper framework with a deployment target of iOS 9.0 but the contents of that framework would be just wrapping symbols we use from CryptoTokenKit but with proper (iOS 13.0+) availability modifiers. Since the framework deployment target is iOS 9.0, it should be weakly linked to CryptoTokenKit proper. Since the symbols it exports are restricted to iOS 13.0+ or have internal availability checks, the app using this wrapper framework would behave appropriately without compiler errors.
Now the rub: YubiKit. YubiKit seems to make extensive use of CryptoTokenKit. It would be much more difficult to create and maintain a hacky wrapper framework in YubiKit due to the number of symbols used. I also doubt that would be accepted upstream.
However YubiKit's deployment target is already wrong in Package.swift: it specifies iOS 10 still while its podspec specifies iOS 11. I would like to propose upstream just quietly dropping that to iOS 9 to avoid this whole debacle there and wait for Apple to resolve this all.
And that's what I'll do. To summarize, the best path forward for fixing the iOS 12 crash on launch is to:
- Apply build fixes to ObjectiveGit. This is done.
- Release a new ObjectiveGit. @SimplyDanny would you be willing to do this since Pass consumes your objective-git-swift-package repo?
- Implement the lower deployment target workaround in YubiKit. Here's my upstream PR..
- Create a CryptoTokenKitWrapper for Pass' small use of it. Here's my PR for that.
- Put it all together and consume those new releases. Here's the working branch that incorporates each of those small changes in my fork to restore support for iOS 12.
Please review the linked PRs if you're interested in this fix!
Release a new ObjectiveGit. @SimplyDanny would you be willing to do this since Pass consumes your objective-git-swift-package repo?
The Swift package just references the built framework. It must be released in mssun/objective-git, which @mssun is responsible for. After that, I can update the Swift package, sure.
@SimplyDanny, I have upload a new release: https://github.com/mssun/objective-git/releases/tag/0.17-passforios
- Implement the lower deployment target workaround in YubiKit. https://github.com/Yubico/yubikit-ios/pull/86.
Seems that the upstream is still working on the PR. I think we have to maintain a fork to solve this issue temporarily.
https://github.com/mssun/objective-git/releases/tag/0.17-passforios
Thank you both for the ObjectiveGit updates! Unfortunately it looks like the 0.17 binary still suffers from the bug. Is it possible that this release was compiled on the wrong branch or with a different deployment target set?
$ shasum ObjectiveGit-mssun-0.17.xcframework/ios-arm64/ObjectiveGit.framework/ObjectiveGit 
16e17d05e761a07d3b93f28e79f8a68be532ecfc  ObjectiveGit-mssun-0.17.xcframework/ios-arm64/ObjectiveGit.framework/ObjectiveGit
$ xcrun dyldinfo -bind ~/Downloads/ObjectiveGit-mssun-0.17.xcframework/ios-arm64/ObjectiveGit.framework/ObjectiveGit | rg darwin_check_fd_set_overflow
__DATA  __got            0x00368038    pointer      0 libSystem        ___darwin_check_fd_set_overflow
$ xcrun dyldinfo -bind ~/Downloads/ObjectiveGit-bmwalters.xcframework/ios-arm64/ObjectiveGit.framework/ObjectiveGit | rg darwin_check_fd_set_overflow
__DATA  __got            0x0037C038    pointer      0 libSystem        ___darwin_check_fd_set_overflow (weak import)
Seems that the upstream is still working on the PR. I think we have to maintain a fork to solve this issue temporarily.
I just took a look and was pleasantly surprised to see upstream working on an alternative solution: not requiring CryptoTokenKit at all! I tried out https://github.com/Yubico/yubikit-ios/pull/89 and it worked great after a small change I described in a comment there. We should just be able to point to the upstream branch once that change is made until the branch is merged. Thanks to the Yubico employees for this!
- Create a CryptoTokenKitWrapper for Pass' small use of it.
I also realized that in my earlier investigation I was so caught up in getting automatic weak linking working that I forgot we can simply force weak linking to take care of the app side usage of CryptoTokenKit; we don't need the wrapper framework. I simplified #543 with this approach.
~~In fact, since we use the same part of CryptoTokenKit as YubiKit, and they are replacing it with a custom implementation, we could just use their implementation if it is made public! I marked #543 as a draft until we know if this is the case.~~
@mssun I believe all the pieces are ready and they just need to be integrated. What are your thoughts on this
Thank you both for the ObjectiveGit updates! Unfortunately it looks like the 0.17 binary still suffers from the bug.
as well as #543 and #547?
Great! I'll work on it this afternoon.
Thank you to everyone for your work on this. I recently got an iPhone 6 just for an upcoming trip and it cannot be updated past iOS 12, so I have this issue. Currently I'm using iSh to copy passwords to /dev/clipboard. It's quite lolworthy.
I'll be happy to test whenever a new pre-release is pushed on testflight @mssun
Upstream YubiKit just released version 4.2.0 which contains https://github.com/Yubico/yubikit-ios/pull/89 (thanks Yubico!) I have updated #547 to point to this new version instead of the branch.
Hi @mssun, would you be willing to add me as a maintainer to this repository as well as https://github.com/mssun/objective-git? I could make the fixes documented in this thread and then hand them off to you for release. :smiley:
I'm happy to report I finally have access to my passwords on my device again!
I followed this guide to downgrade my installed app version to 0.10.0.
https://github.com/qnblackcat/How-to-Downgrade-apps-on-AppStore-with-iTunes-and-Charles-Proxy
Unfortunately this solution has a couple drawbacks:
- Requires disabling automatic app updates.
- Misses out on bug fixes from later app versions.
Hi @mssun, would you be willing to add me as a maintainer to this repository as well as https://github.com/mssun/objective-git? I could make the fixes documented in this thread and then hand them off to you for release. π
I have added you as the collaborator of https://github.com/mssun/objective-git.
Thanks to the fix from @bmwalters. I also release a TestFlight version.
 
The TestFlight build works! Thank you @mssun!
Note for others who want to try: You can download TestFlight on an iOS 12 device by first "purchasing it" using your same Apple ID on a mac, then going to the purchased section of the App Store on your iOS device and downloading it from there.
Note for others who want to try: You can download TestFlight on an iOS 12 device by first "purchasing it" using your same Apple ID on a mac, then going to the purchased section of the App Store on your iOS device and downloading it from there.
Hi @bmwalters, what does this mean? I don't have a iOS 12 device. For iOS 15, I can download the beta version in the TestFlight app.
Note for others who want to try: You can download TestFlight on an iOS 12 device by first "purchasing it" using your same Apple ID on a mac, then going to the purchased section of the App Store on your iOS device and downloading it from there.
Hi @bmwalters, what does this mean? I don't have a iOS 12 device. For iOS 15, I can download the beta version in the TestFlight app.
There are just some extra steps to install TestFlight on iOS 12. For iOS 13+ you can just download TestFlight from the app store.
Ok, I'm trying to add a footnote in the README. Is this the correct description?
You can also help us test beta versions through TestFlight [^1].
[^1]: For iOS 12 users, you can download the TestFlight app by first "purchasing it" on a Mac using your Apple ID, then going to the purchased section of the App Store on your iOS device and downloading it from there.
Hi all, please help me to test the compatibility of running on iOS 12. I'll close this issue once the TestFlight version in the App Store release.
Thanks @mssun and @bmwalters,
It is working great for me on iPhone6 (iOS 12.5.5) finally i can uninstall iSH.
Ok, I'm trying to add a footnote in the README. Is this the correct description?
You can also help us test beta versions through TestFlight 1.
Footnotes
- For iOS 12 users, you can download the TestFlight app by first "purchasing it" on a Mac using your Apple ID, then going to the purchased section of the App Store on your iOS device and downloading it from there. leftwards_arrow_with_hook
Hi bro, TextFlight app is free, can be downloaded directly from app store
Yes, absolutely. Are you using iOS 12? As @bmwalters mentioned, you cannot download the TestFlight app on iOS 12.
Yes, absolutely. Are you using iOS 12? As @bmwalters mentioned, you cannot download the TestFlight app on iOS 12.
oh OK, since I installed in previously, it is already in my purchase list.
edit: I believe, mac in not compulsory , one can use other iPhone or iPad greater than iOS 12
I confirm I can open again the beta of Pass on my iPhone 6 / iOS 12. Thank you guys!
I let you close the ticket when you will release a new version supporting those old devices.