Refactoring:
- Get receipts from StoreKit Transaction.currentEntitlements
- Search for the originally purchased build in the local receipt anyway
(Kvitto)
- Fall back to release receipt (Kvitto), if any, for feature eligibility
in TestFlight builds
- Parse and verify expiration date in subscriptions
- Decouple in-app identifier composition from BundleConfiguration
- Fix user level features only applied when a receipt was not found
Testing:
- Add StoreKit configuration
- Fake purchases with PP_FAKE_IAP
- Fake user level with PP_USER_LEVEL
Then for reactive receipt reload, detect app activation differently:
- iOS/tvOS on .scenePhase
- macOS on launch and NSWorkspace.didActivateApplicationNotification
As to features:
- Credit former "Full version" purchasers with all current AND future
features, except the Apple TV
Streamline initialization of AppContext objects without singletons,
especially because some are interconnected.
Rethink ProfileProcessor to be the only gateway of profile processing
for:
- Include
- Save
- Connect
Provide closures with access to the IAPManager for eligibility checks.
Finally, take a ProfileProcessor parameter in:
- ProfileManager (for isIncluded and willSave)
- ExtendedTunnel (for willConnect)
so that it's used implicitly without having to put it into the SwiftUI
environment.
Other than that:
- Move AppError to CommonLibrary
- Skip decoding of attributes from Core Data because they are already
part of the profile
- Perform profiles removal in a single publisher, in
reloadRemoteProfiles() after importing remote profiles
- Only force a new lastUpdate/fingerprint if profile is saved locally,
DO NOT alter them if imported from remote repository because this would
cause a re-save on iCloud
- Profiles were purged twice on launch in the main macOS app
Add profile attribute `isAvailableForTV` and set specific behavior to:
- Observe shared profiles and delete locally when unshared
- Only keep locally those profiles with the TV attribute enabled
- Add toggle in UI
Additions to the domain:
- Update rather than replace existing Core Data profile
- Attach ProfileAttributes to Profile.userInfo
- Store one-off `fingerprint` UUID on each save
With the above in place, fix and improve ProfileManager to:
- Use `fingerprint` to compare local/remote profiles in history and thus
avoid local re-import of shared profiles
- Use `deletingRemotely` to delete local profiles when removed from the
remote repository (default false)
- Use `isIncluded` filter to exclude certain profiles from the local
repository (default nil)
- Move InteractiveView to AppUI for use in TV, with
OpenVPNCredentialsView
- Move non-UI entities to AppLibrary (IAP, ExtendedTunnel,
ProfileProcessor)
- Take API out of CommonLibrary (tunnel extension does not need it)
- Reorganize theme views/modifiers into separate files
Mainly:
- Aggregate shared/mock entities in less scattered files
- Review package dependencies
Also:
- Decouple ProfileRepository from Core Data Repository in UtilsLibrary
(filters done by ProfileManager)