From 339e6247aa1ed03ce769c83eb672885e71083a1c Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Thu, 11 Jul 2024 02:15:19 +0800 Subject: [PATCH] chore: rename folder. --- !examples/InAppPurchaseManager | 1 - examples/InAppPurchaseManager.zip | Bin 0 -> 42428 bytes .../project.pbxproj | 386 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../UserInterfaceState.xcuserstate | Bin 0 -> 30640 bytes .../xcschemes/InAppPurchaseManager.xcscheme | 81 ++++ .../xcschemes/xcschememanagement.plist | 22 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 63 +++ .../Assets.xcassets/Contents.json | 6 + .../InAppPurchaseManager/ContentView.swift | 28 ++ .../InAppPurchaseManager.entitlements | 10 + .../InAppPurchaseManagerApp.swift | 27 ++ .../Preview Assets.xcassets/Contents.json | 6 + .../SubscriptionView.swift | 61 +++ .../InAppPurchaseManager/store.swift | 159 ++++++++ .../InAppPurchaseManager/Product.storekit | 166 ++++++++ 18 files changed, 1041 insertions(+), 1 deletion(-) delete mode 160000 !examples/InAppPurchaseManager create mode 100644 examples/InAppPurchaseManager.zip create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.pbxproj create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcuserdata/wangchujiang.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/xcshareddata/xcschemes/InAppPurchaseManager.xcscheme create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/xcuserdata/wangchujiang.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/Contents.json create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/ContentView.swift create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManager.entitlements create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManagerApp.swift create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/SubscriptionView.swift create mode 100644 examples/InAppPurchaseManager/InAppPurchaseManager/store.swift create mode 100644 examples/InAppPurchaseManager/Product.storekit diff --git a/!examples/InAppPurchaseManager b/!examples/InAppPurchaseManager deleted file mode 160000 index 393d342..0000000 --- a/!examples/InAppPurchaseManager +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 393d34253a1dbbb5f59a3cb2b863674c754d8e38 diff --git a/examples/InAppPurchaseManager.zip b/examples/InAppPurchaseManager.zip new file mode 100644 index 0000000000000000000000000000000000000000..99aa88be2cee8fced9e7a0238a738bc307fa4870 GIT binary patch literal 42428 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 J++FR){{uxAc_;t? literal 0 HcmV?d00001 diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.pbxproj b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8c2c9f2 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.pbxproj @@ -0,0 +1,386 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 7D4C0A642C3ED21B0050CB10 /* InAppPurchaseManagerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D4C0A632C3ED21B0050CB10 /* InAppPurchaseManagerApp.swift */; }; + 7D4C0A662C3ED21B0050CB10 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D4C0A652C3ED21B0050CB10 /* ContentView.swift */; }; + 7D4C0A682C3ED21E0050CB10 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7D4C0A672C3ED21E0050CB10 /* Assets.xcassets */; }; + 7D4C0A6C2C3ED21E0050CB10 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7D4C0A6B2C3ED21E0050CB10 /* Preview Assets.xcassets */; }; + 7D4C0A742C3ED2B70050CB10 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D4C0A732C3ED2B70050CB10 /* StoreKit.framework */; }; + 7D4C0A762C3ED3570050CB10 /* store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D4C0A752C3ED3570050CB10 /* store.swift */; }; + 7D4C0A792C3EDEB70050CB10 /* SubscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D4C0A782C3EDEB70050CB10 /* SubscriptionView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 7D4C0A602C3ED21B0050CB10 /* InAppPurchaseManager.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InAppPurchaseManager.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7D4C0A632C3ED21B0050CB10 /* InAppPurchaseManagerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppPurchaseManagerApp.swift; sourceTree = ""; }; + 7D4C0A652C3ED21B0050CB10 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 7D4C0A672C3ED21E0050CB10 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7D4C0A692C3ED21E0050CB10 /* InAppPurchaseManager.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = InAppPurchaseManager.entitlements; sourceTree = ""; }; + 7D4C0A6B2C3ED21E0050CB10 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 7D4C0A732C3ED2B70050CB10 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; + 7D4C0A752C3ED3570050CB10 /* store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = store.swift; sourceTree = ""; }; + 7D4C0A772C3ED5C20050CB10 /* Product.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Product.storekit; sourceTree = ""; }; + 7D4C0A782C3EDEB70050CB10 /* SubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7D4C0A5D2C3ED21B0050CB10 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7D4C0A742C3ED2B70050CB10 /* StoreKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7D4C0A572C3ED21B0050CB10 = { + isa = PBXGroup; + children = ( + 7D4C0A772C3ED5C20050CB10 /* Product.storekit */, + 7D4C0A622C3ED21B0050CB10 /* InAppPurchaseManager */, + 7D4C0A612C3ED21B0050CB10 /* Products */, + 7D4C0A722C3ED2B70050CB10 /* Frameworks */, + ); + sourceTree = ""; + }; + 7D4C0A612C3ED21B0050CB10 /* Products */ = { + isa = PBXGroup; + children = ( + 7D4C0A602C3ED21B0050CB10 /* InAppPurchaseManager.app */, + ); + name = Products; + sourceTree = ""; + }; + 7D4C0A622C3ED21B0050CB10 /* InAppPurchaseManager */ = { + isa = PBXGroup; + children = ( + 7D4C0A752C3ED3570050CB10 /* store.swift */, + 7D4C0A632C3ED21B0050CB10 /* InAppPurchaseManagerApp.swift */, + 7D4C0A782C3EDEB70050CB10 /* SubscriptionView.swift */, + 7D4C0A652C3ED21B0050CB10 /* ContentView.swift */, + 7D4C0A672C3ED21E0050CB10 /* Assets.xcassets */, + 7D4C0A692C3ED21E0050CB10 /* InAppPurchaseManager.entitlements */, + 7D4C0A6A2C3ED21E0050CB10 /* Preview Content */, + ); + path = InAppPurchaseManager; + sourceTree = ""; + }; + 7D4C0A6A2C3ED21E0050CB10 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 7D4C0A6B2C3ED21E0050CB10 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 7D4C0A722C3ED2B70050CB10 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7D4C0A732C3ED2B70050CB10 /* StoreKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7D4C0A5F2C3ED21B0050CB10 /* InAppPurchaseManager */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7D4C0A6F2C3ED21E0050CB10 /* Build configuration list for PBXNativeTarget "InAppPurchaseManager" */; + buildPhases = ( + 7D4C0A5C2C3ED21B0050CB10 /* Sources */, + 7D4C0A5D2C3ED21B0050CB10 /* Frameworks */, + 7D4C0A5E2C3ED21B0050CB10 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = InAppPurchaseManager; + productName = InAppPurchaseManager; + productReference = 7D4C0A602C3ED21B0050CB10 /* InAppPurchaseManager.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7D4C0A582C3ED21B0050CB10 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1540; + TargetAttributes = { + 7D4C0A5F2C3ED21B0050CB10 = { + CreatedOnToolsVersion = 15.4; + }; + }; + }; + buildConfigurationList = 7D4C0A5B2C3ED21B0050CB10 /* Build configuration list for PBXProject "InAppPurchaseManager" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7D4C0A572C3ED21B0050CB10; + productRefGroup = 7D4C0A612C3ED21B0050CB10 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7D4C0A5F2C3ED21B0050CB10 /* InAppPurchaseManager */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7D4C0A5E2C3ED21B0050CB10 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7D4C0A6C2C3ED21E0050CB10 /* Preview Assets.xcassets in Resources */, + 7D4C0A682C3ED21E0050CB10 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7D4C0A5C2C3ED21B0050CB10 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7D4C0A762C3ED3570050CB10 /* store.swift in Sources */, + 7D4C0A792C3EDEB70050CB10 /* SubscriptionView.swift in Sources */, + 7D4C0A662C3ED21B0050CB10 /* ContentView.swift in Sources */, + 7D4C0A642C3ED21B0050CB10 /* InAppPurchaseManagerApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7D4C0A6D2C3ED21E0050CB10 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7D4C0A6E2C3ED21E0050CB10 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + 7D4C0A702C3ED21E0050CB10 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = InAppPurchaseManager/InAppPurchaseManager.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"InAppPurchaseManager/Preview Content\""; + DEVELOPMENT_TEAM = GR99S2ZJZQ; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 14.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.wangchujiang.InAppPurchaseManager; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7D4C0A712C3ED21E0050CB10 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = InAppPurchaseManager/InAppPurchaseManager.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"InAppPurchaseManager/Preview Content\""; + DEVELOPMENT_TEAM = GR99S2ZJZQ; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 14.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.wangchujiang.InAppPurchaseManager; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7D4C0A5B2C3ED21B0050CB10 /* Build configuration list for PBXProject "InAppPurchaseManager" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7D4C0A6D2C3ED21E0050CB10 /* Debug */, + 7D4C0A6E2C3ED21E0050CB10 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7D4C0A6F2C3ED21E0050CB10 /* Build configuration list for PBXNativeTarget "InAppPurchaseManager" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7D4C0A702C3ED21E0050CB10 /* Debug */, + 7D4C0A712C3ED21E0050CB10 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7D4C0A582C3ED21B0050CB10 /* Project object */; +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcuserdata/wangchujiang.xcuserdatad/UserInterfaceState.xcuserstate b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/project.xcworkspace/xcuserdata/wangchujiang.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..6f966610e6248f54948d4aca8722e2169bff334c GIT binary patch literal 30640 zcmeHwcYG98_xId8Z9_>mAw8s#M#`padL^Cow&`uNNj4!6vLU+xqM~yxAW9KLK@=qk zB1KTJSFm8m0wSVFu^^x#2qG%#duApZ5)$xvo}bUFe>~(vHam0Y)^on++;h%7)7aVG zW;BI{en=q-Q#8d;EX7egHKx*gw!X{QX6UH$)^#;aYlCm4-X=q5rMIDRy1vO|w4u=a zwOXZBfhJeqqi;?bDD(lPpe)KXCY?zyphv7Rp~h0TYT!^#HY&>ZP_&Td7B=N2zVpQ`FPcGt{%xPUQE6^%*A6kR@(0cSR+JYWM z+t7COG*ZsI1b0-DL4~P#aXxr7vmCKjcaf%*5U>{9nZk+ zcqX2OO?WQu!Pnp$@lE(xm+fQMvk$R5*q!W4?91#c?5pf9_BHl(_6_z; zb~pPWdyxH%J;WYkzh=*{Kd@)nbL<87BFAtn=gPTp?wkkb$xY(CIB(8}^X2@wKu*oY zaq(ONm(FEyg>$w{^fg{|F+)dog+%4Qf?hbAhcMrFk z>*M;lE!I<8%2uKA$h(3;80xl&|Ntd;_oJ z_55^x2H(z`_-=kSe+_>fe*=FDKc8Q~-_9@N@8Tce*Ydr5AHRX$$Zz2v<)7rA;-BMp z@UQc4@Ne?(@bB?o@yGbD`Q!Wv{v`hm|1JL=e~SN}Kh2-vf8fvZ=lGu#w1QEv3QoZ* z6bcK)7==>dtZ-3GRJbbK6z&RtMSvnu5uylJq$$!B8H!BBR7I8|x6HevyS;rcHJ-Ah ztSBWlfwHeC&;-xW_ZX|;a{y1vy_?!~Mq?jkP1y)op!+CW$_^+H-6{BJmEMu+$XIo1 zRH!N}Iwe#Uk(!>SiVcm;RAq*yre|bCMumq)MroC{+36V-hOQaLPF<5e-O$uMQ{Q1S zx9m)LQ9&Ch7iuEqO1V+)ln3QWO%hmv6L>)(SO{Z;vBJ0wlsDx=`NHqXPy{}O@q(pb z1;3S0MEnfWD(%E}+B%vIbFz(@FgQ(9mtNmdKX^5>OE*)mRjS}Zmd=>p*4hQ~pt)Sv z-mN!gb{S?CXiD@(lc7u3*shmkMY_(U(<*%jD=5`9rs}#XbjI>FV;dBzXfsXIv~{$$ z>*0=8nIsl8j}xw>89Gc|hW2)Smo_yeGA1-KB109X&PZ29gr=!gu`%j&Rcu5|cvx6i zY)V8#gjVSe6{IwoK&)M%8l}^vz8DPcjk>OEb6>Pd$4mF5eh%JJK+O@c(H_y!9$`_D zu^wUS@JNqP_)$kjg?fZVghhH-n3p4#N~3}{QgKu~l|Us@Nz@c7nM$Ej1#7`Zm>}2+ zc7na&AUFz68(|qTs7z`ql|^M!Ij}T&un^8ds*om36|#gJSd@HmS(MN(%{0TD0^RJk zRvpZ*d};7&N|zpH*&0ffncCXhOl^8&MO(9Jnp`Zq!`KOu-OzQZ*x-{=vD)%B{hV}t zV|QySOtf-BzJ8{mt7mGLu5;R@tL8oowonJnWi+=9)N3AnB~?cSt)r@_YO02+61aHAt@PpsbKikZU!#iY8fy(fYU1FKlR4i0!?}wkhP&h*VWSprG&}? zO`)W)$y7V6KNN9%)%5I}>rxt0I&agZp zBNvIPWQo4BOK$|!(TTkf0)>D=YrM75tY#uiGpv6=SXG-zKT{eh&>rBPDWwV4!>Dft zAkfzvn?z+XN()T@z%DEu9JNB@Cu7@rJXv{v?@R%{oJg!4pZNl zu_6d|q;z%`b%RE#GwSno9Xg3zN4>11_E=ge$Botr{oGDnho}Kd-3(88&HcthU!)7r ztj)OI30G)lkDa~4zg*je>wbXRoF?`=k9E01eL%)VUHaL;cOD|f!MrM&J#OwEp8tA} zS1S>;;^o=reWkhCvQ`5@BqSDJtFSP-Hq>j4ubx4z?J)L@E^gwgka*Z}T>{2<2LNx&T9j)2T zKqGA}Z2-{nFji1^0aO=g^1Dr9hcCfHKea*xh<^cJ&G@hi79yw*)?>90B82tbd)rCkPt zNkALNj&pGF^!5u3l6A^`;{m*^Z6?^-*$=3XwT4bT=vsy@kzPPgGZ|*+J2Kn!?ai_j zkW?^`ONU*9^y6HPa0%=a|Hkl0Yj40DCQIk2vcKltl3SB(Jps3lI7D)(=vqRIcC0%>(XF_UiQqrIeKw zwafdWmBn{PSC^p+Dp3VP=e58`ayeiNkU)dLEsc0xNNAYHpO(@poi0^VD$bn5SOar* z`8{b?rF#-`IfGi}4~C6sP|@vMPJ4t;D zMu>}u1tWxvW$wrm`JzZbv?MS!q@r}xf@YvaXc-s}-jyM05VO?7Ad5mLuOh0=4D}rK zf=Iy63-P_wi$cOx30M^GFN1i0_0Pn6Vxe;T<&(ra#l)NEK>80KhlK*r{ z-i0Z7|Iel*<-ao}g}VRhlz1g~CQH*~o|_M;kEoztYM+qaOYIjjM4a{PHtM@TA8FBd zb?KYaKvipn4M4_R&`U&q%T71$k@mQsQU})xnX>#jL><1I$ASKjP=Xm623OPE@E6oq zV#8kw*}ar6Y;>Su7jai(EbM6S8Q2esQdmZ`L3weK`c9Ni-%#HQxk6qau%ozjmA9*d zkLT%iGXUb+4NWs(L*QOnGI(b|y%Kk)gBuHTkIn%h1#PB&q|Q@6Q5UG6sb8pHsf*Na z)bG?ELV-{y6bZ#biJ%cmg)*UBs1PbQgNA|;jTqo>4)I8VEYKJfaYw<7WLaA&~&xRfK+{pp-Z1;nAxf8YBL%-q>V)x ztjoa6$dAg~4XXjwT~cCu+V#~#Z+fKbTXfy+rXtbKYZO(>;krA_kKJYckl;|u7W zU?32uph#{pPuFAUHthx7&zZ79E?}m0g@y_=gEN$;?`V}av_q~*Agx3ozp5pgMDEC= zX2|_MN~PKz_4Ic0%%Ky8{~t0sUX;a1xYlH{HcSzC_rcsGR*~4D1r)F zkAhJM3PoW^jlu<;&?qzs&4ONNSr5n_g`!1#2f}O>rV*4Sv=Y=PlIXC7v6hDqt%C`~ zJW=wsELbSuIJgM(TQ@LGu(J#c53CWzcrNUOq|K)*&~XyoGpHzH9||M`lV?jCsI*`^64jkxqp1rt;LFL-$|yP` zF6q61CLNM}WT2+Y%Uch-E4EW(?m<~e9z1RSb_w?eb#9?cAi_;ThcF-hx?Z^PBQzaE zcsmSkCh9;2)QM)HE@VU)wr^(hT%Msx+AG&zQnqAPw;RNv643rYxzWql;mMi0wvJ21 zVUDCVC~Ps;dFh@oN9Yu;5#|X7p+>6=8C1WAO{QGoC4LsiiWh4>0Z;0U$zI)MaP}tsfQz;A%#jN#?wp(9K%qMBw^MTPSEu z+_%UO*VfgCZV@*nS1n`i!UC}iLbu%FsGCYz1|30*`b3el7cGH~FGY8NPPKgKs#clW zW&(fcW_Aj5g&u*@Dor9~#f5}~h|p>bnWO7yZJO3Sy$wD?TH8#j&Mt%K1`9FHX=^cs z=sG(?;EFh4z}k>z{cKY=j61|rKNsq3*Be7dvq^-EK1X+x65y%4`3tBN%O1!E;4>oj5`An%|EesFAgEiGcgjTGR`8 zJLHmR_4v(qaxGb18X)fuv)hn_>viA+wY*6+88VCQUtqo;^0}{zE z(JCD-(V4`}!6G{Y-f5N5GNnns!vVm=tD5f4PD9rSx*JyJ3Rb_7>wf~BMBkuqVf{~m z+3vJ(kI*kXDBKO}|Ax>jtQ)@mKcKT_kt#eOtTanHdHsJzmHp@!^eeh3tP)lWYcA2j z35gEw5$T{t5>UYsjt|Hc%zy?Y2={{i1Cnf1xneG9Ayst$RS0T;j#8VMq;J(3yNw#D zY#KRk9u3|c$xvCZNO;(8`M$DWOvM#y`n&!BWr1wwn&4@skmJmS&QUgfo+6IA8cr8 zG3tS_N7f{}VdPSx>HA7UO6fLDGju^iBS$Q10-1*PX3+4!Y%-!BbHI0)2Q|xf1DpVW zjT41!!fc6waWbl0hf{E>_+QvAJSP30t@KciGp}tn&ZF%6a1PEDo)Dhw!}+*CcuII) zG~_s^>)TB_d0FIbRchr-f(wa0RXu zo)w-Gd}_oQk+fF5vA%g=iz4qn<<8fk%C*95Yr7hARXVJv?E7&eZoY@?%`(PB}q5KUD#L-nn_u9 zdLQnhggv+$o}WGP`5V7l@oC|Ptn}^A<>}C#n(e|%UdhdCB}bod5ev&#n+3I zeI1@Bye7OpWU|XzfQBxgW`Jf*cOwvKTc@aX8wWgnBP0r*k51xS@j|4>x8p@1QFenw z*(baO66LJ0_cDosm*P7HCCUfF+ruOZz8fS8UWr%XdxUp{cZK%`B?`15ij3W|$Z#DE zdch}oMJZzzCl5;E}Td5-=ZXmH*Vf%2poyINl)& zizo1t_$mA}eg;2_pTp1N7x0V1N5X#LW8r}CiSVg#Q20zZBplv^cMb@PSMe@MSiAwk z;>duo_)<7635zrT6BbhZN3ap(-(MyyJ`#n+e&MKDSbQQ1i%;=E@xSo7@P+h$w$eh$ zngRF=d`yIwFY#BxSHiJA{53u(>x9L3__Wx-DO@TX7oP6JXK;mZ0>p*SWdg#Q z_A~eCC;Y1@6fWSO@h`$R!neYA{rDpO4TQoe;rqW`D9{XLMYAJ8{ph1}Hl5#*{q(By zKP=>G8Buf_>TwVE+dZ z_Rqkioft7~ur0X)-i*L}+5w%UooHvIrzg^`fcY1Meu9wjqcEQ!H{p-VP@ndoJqJ<$ zH{tv+)TjLb_36p9KOG?aB>W=$I*9tT104*ge?jLIbb6vtg_@5w4f~@4U0(1o5& z&mqW~Ae%nAhrWiO2?RNb$p5E1fvfH$%#GYY-vlsD3pAl`B*>N^JA&Z*&Gao896b&M zIsW}vz6bz%@koH)VB1v}Zp{4Y_OVMlu6gplBO;dH0Y#UMEE+g{p1rU!%AJjO$ip1umwzab($L4N-N)bAFdo*;i2>u>wp zuzth@20|@{10K$JGB7C$N;p5B*pZPz8|1Tgs7;Jm#UkHjZBm8e7 z!v7BV4*v;?mEc|c4G2Ge07V#fC90RgCo}h$2#)1K9ok&pHUxx3D6$7U>`WYo- z&Dao>M9>t1lKUB3#!kfd6oOL!c6?_hQdW%XNYH-fn+dPIax~}Swi&z1JWm^*1$<{b zps44_q7yze9NUzYsa}2f?TosD39*Ct&UiC^623FOBEEykr-Jbp@jYWCzT=JNl?i6T zBz$K=MSP!nm4_sY850d56-*34*$_L##6uSom_&$cYwCt*qmBXB)eyH5K{*8JMo0y4 z8|`FLnAD*TB!Y?w${p2(#AGqqvI~jHCkQmaJlTmvP@&wbLLf>8uICR*0!AZadBIh% z{AzwA^Ze8?ItadC>KQH5Ku`%m8iGpunMS6GX(p(QAczra5S?;C!#pXnNz)vFVfONw zox~uSMk_8wksG>=rMj+G{lHwNi3g6fO21KR*UHy4ZLJ+(x|Lg$r(?P}9Ww|j7iNFR zbbvD*T11XxT~&kDZ-S}_swAj_pn9$H|Bu_uOAOIJ-NO;{{LW^2AR>&J!^|b9 znxL9K<{IW&f@%q>6N1X+L6yrB0v?A^MtlY5k7NL4Ze(uKDqV-o-Q{c1&)m%1BDy}W zUTk!i{^(sYkL^}wp*b1}&Vw+En8os`EO}Hz6*>V(JE8JDv=uQAxM9TIqs90qvij|9P614;G1S1B4~Oqvyq?~ zA|qHs(7<3cnG}j7cVi26u#efwJVH=AL0y9(S=O+A%u|#v z^9(_q0&Ey&2|jgD>!moBTJhVZvtCO0Dyn$-I$#A;ceB1~a3Z~um)t7ZGR%we60>Wx z=3ay5-XO>*HfIuLk`+{84vrH;-XQkUL#k*n+KhRZ*$dI{%zMoH%m>UKf?)FkRNO<* zHS3rUnSFFHv!5U!Wp2nfrQ*`3a6OGT$?& znKR4}%vt6f^CNSfAOeT53A%}(n+dvwp!ozXAm~={IHUL@9%z()U>xF)c#u*40kR4d zC&zq9p&8U(qoG|dE=*oqW0x4`C`ZOio-p}T@s>^V8(_Q6%S*MT2wUY^gsaU%;Duju2deJ{^D6JF*0uW z6Ibl}V5IPnp$;r3JBA$xe9n#~=(b*VJVCc#h0j@Q;B(f7g}wVCf|d^QIcv{4kHUDY z3+2ta60}%=dY1@3gFNDu+*34^aoI_%?`Y5aQNFA{L3fCZyG-!8#9Cg-3mv5jAUsm$ zGOfser3Q)l%tH%d6RDsrY$zMXs@ZThf{kRO*l0F}jb-E5cs7Bc6$ITy5J2lnf>sd( zK)RZsdkMOapfv>DPtXGdt=+;Vu~XP&HU(iejZJ4W*i87A#b%3JlU{<>5gbpzZCXQc zGQlYXrx9E#U27&-FLSJ8iFDvYhIq4>g0LcyT?Ybi<$Ds18#4`E@=aIykgPe*LvOl- zlMrWGE8o>LP1B3VeZ5P%JAji-Z5>iTqZFrQg76SH`6C4gVvpZT0fca3Xv=f~R0m|a36?ni_Zg_ZmU>?4_w<3*7@vv5Ab!o88 zQ1N)C7)IT$hjXKsf}rKWq(UfIvs4>&8N$o}qoCDPfP@*H1~_PFl8PA!PM?yoh$Cw+hP$>Vp{2UT`t~AzC6JaB|Qc#WFz;+U}fuJn}OQ*fA8iygl#?WZ9e>ZO9KaVjo4`enw zSHu*MnHzgqkeQo>prMn0y*&Aw{-(%2b1w;dlh{iTS`Ysx;dkb0Ze}D6Tx3Rag z0E=4*dX%8;1U{_|AkNrc!sD{$~gL2oN_{Vx>*bVGsV6$U4vYXh=?8EF9b}Rb``zX7O1yX*Bpr;9X zh9EFGJV(&;1ie7eiv;Z;Xy+#OaoJ|aJ}ukq*ylyT_>!dJf#80{Y_oe;7KJ0DkOp_H zqeU=@KI{L*Y>8oMvVssiJZ6i13wD6)+XTHlV6$W2y`s&|j9B~FkHId)e#F8S=2e1r z^|1%oPY8OApf~<9Up#x5{amtGu}4LVl^9HPC5x50TgTaNK?!6}uqWAX2zryCw+MQ> zpZ$(KCEEDjA!zsCZsTKrq^#KUBMo<>*!b9=q3ACoi(b*j$Nt7qlDUrkLp0aD_vbUl zahx@|bwY=OzQoa}mD5mGT$nXfvp&eJ=fI%* z8$rJl^hZCpk=q2!iYWrF@xMF%ncD^&xP2rCjuQXOJpo0Z99eW^sIz(e&v4Jn%=#QK zE2jT^!d~Wfi_H28_bRuGdyRXYdxLwEdy9LUdxv0_V2)s(Ur13rX zgUGO_xibXY5ImueJIkFT*p^`Xzm8#l<}S(%`ztUkwgdXRQh3flw|LBRz_C2dGd$3n z1Hq02JN5HCuMj!bnP8W{onv_`%8FNxWW!Mcn)nG&)OKXiD+V<24m?=D|aH#Xhu)p9H2q?B2(F^F9Q75*#wj!iN$( ziC`~+z597JAI?V*4C7D{9Q+S+Me}jMZ9JI1Ax3M^70oB{Q_umXi{Qxw`w2_H|1A53 z=YF1NUa53`Dy$Tr!DkZePjEmVpT%br97u4`|H&_WRgW!S%$LX>TXQ$c_$qPE%lQhv zl3<*e8I~{~uu3 zmRA17_o;aEl+WZlherhPvoJ$&44m}@H{j?Y0Ha+s*Efd;L-Sh53GxBp%e4e2NTC7z zJpOt(8&v>_H~RQ_kaj?hO5+9oM#whA6M~a^`I`uy0O0+g#rwehC9#RzP&6K%Ru=;r^J^9{EA(IWe{C zh>C}o7aK4St)G7ohQ_ZWIIEXmPjI%lKBG?#zX|4kGykx7f?rJIAT9c#o!-X?&XJd6 zEB^>AhnQKikB3wA<~FwRU~uf^w-cP#%Rf%AltOj%HlT&4`DgfNtDp^|v{VEaK%h-1 z{EG<-4OhWum^vaOHasId4F1f}&eSy-jC17=t*&ckRD|4@=lK`F12&lSOkVeX{(1gI zDOacb-Q2^S{3{|*y~Mvva1p`9ef+EZE`m!4)`;^lS!zC19SY5drH95ugoQ<@Lt{eK z8QQkaX@(BH!6-NV@Ag!h(zp1B#i?wwI$&=jPNj5lw|w!&Lp#;m;G(&s@AIEf_8a*R z_&xky{zHBr{}I2R|Cm2Oa2dhn1XmCY5LZQTHNoJf1bC~1q_+G)%9}sLALftnNBPeo z#K4N+dhpd^Ex`>0>j-WnxCvBOpXxSaMtfVUm3{yI!#cYD4qdF5LM4Ac5 zFNR*uhQzjz#sS>akcvdUp-In`0t-4sPu|e7=Ey1V<;s_bIxedQ9~QIe4QW^mt7sR^ zq9a-cXC~WE3Xa%!c0)3SIO*#&1MrYUDAn?F zVG+TRkT9t!)nJ$b{@1YRpfDK-ew4CnnWz2&{~Ne}_@DV-_+R;p1h){}N<1%Fq!{4Y*as zv{T(P#Y9muS!?vIQu?8?w06C&qdY7!Gd!$Wc~TmcVk~vAUolQGUSUaa2f-$Sdj|dc z3TuTOh)RWxVuAt`V*|mR1kdVM*ee|P-w6i6V}vn^Lla?U_y~qI4OyfNU6K=84EeZ9 z!BmKi(&!<@mYhY||LUdXHl+9$uVg7MfTD^$23APnq3|B9^F9h+g&)D)1kWaTju7NE zW#BYy6XoH9DUUshAj(RiQUr^@CPsb~S~FuWPqp_KB$a$b=`?oS1lx(O{sEzJ@d;ju zDcL!>dHI@(%3AF}>T)^FBqVSg7^s|X7)}bOm;ekLfryPDmmCGUO4AK_eD%%x=Dl|I zmJUuXV&7*BPjuevC@{Uwkam0mfN~}zwf#uUXFJK#%i9O?(84thBnX4HS~A;ptx`tg z!QdcBItl5-rCijad4yw@@? zNEI9cVFGfymx7K4N!j`GJ3|I&ZzG_a89^bAEG*KcUmYGHNIBE{qoQMkaS%;pCrkh( zLass_#Nfja_EexrD-}DEsn?0|5E{J+!X#RaLy9<>iew zt=M*IhD%>sI-sJmFLSD#EF6+jLG9+6#Z1_SA*nlIz=L_Kp3Gz)It2pV>P@s*fY5?NPXSc7WWR$B=x~_hJ zHu~yH;A;b9Ew>p$ZIC`rRG0c1;qg(fUm+i-0djF(2Pv)>Ng0LLz^g+x!Yf0bre1*; zg@}nD--cI(d;zVNket$8c2QxL1yr(k0p>rYPs~P zkJact$T++fG7cX==g`lPZ{#=h2V@$y5OWP+c#`s-$;l`Kv1U`+=;tSG|NQtlqGk!J=;L5-U?L+WfNu^MPD#Gdp z6$;RDbp3EiO$jiC;x{u4MJVDSJsn_ZlpJw~#_#GiiG?&KNLl!&CB>jSsiar3 zLY^B*Q&D6OXey^Cu005vN_{CLDev*nnLI+(aiOt5B2LsKDhS?169vCG)I;msPW*$3dw8tdTA8oSvq*)tr5_hoS4?HU7~E=x|y*}(fUeBfOf z{_wU86&J#VfwLr%%jasjMcfnIdESwakls?!#T!BUzZ2dHyC~j*cTpVXe}K14I05>{DT)+Lidl;56$=y#6}KxEE0!u&DOM}) zQ{1mutLRhgQXEixV_|LKX5nYyZxLvrvIwz=v52!sut>5>6V$69hP@muC?4~x!H1y|s|2eG>o={xv_4~f&icId&(^~6MOV0W9{BD+WI z4%(fv``Lb?eT03reTV%#`#bHQw135Zzx_%3Z|zUnpSJ(mfpr+;VDI4R;N=kN5aytE zh;T@BNOnkdNOvf9sCQ^^Xmn_HXmOb4Fx_E}LyyC?4%a&f4mUa6;;_JBxx;#g=N;a1 z_{ibB!v#myah#*2qtemF(aF)p(bdu2(bF-?G25}mvDtB!qtUV3agJk;1(GG zPTx3v=j`r0*;(Zr;vD82?wstL>s;)taV~SNaGvgLbYAYf()mf}SDbe_zwZ2|^AYD0 z&ZnGzb>UsCT_(8Lxj48iaarlI#bvw88!jKX9CSJ4a%5ut#MX(%iPub=KXKK>-ihx_ z{9ximR|{8bS65eeS5H?j*VV55t{Yvqy1wRm-i>zS+!StO-Nw6Fxh1$|xD~kR-KM({ zw?4OZZtLAPxNUNK*lnxZqi);X-gevV_MY1ZZhPJKx$Sp5;`W8xS8iXsopU?ycERlz zcWZZNcRzQ3_ds`*`(5t$yRUWc^PoMH9yT7f9`^8hjp-i5qt9cV$9j(q9-BNK_Sow2 zsK<7Xw>@@yyyx+O$6k+p9{W9xczo?~!s8o{?>xTuxaje_C*_GfEj?X4T|M1BJw0PQ zGd!nyW_#v(HhLO7XL%YuyFD*XvY0e>()dYMlkT4M@T7y2PE7jUi}J!=j2Gvn@EYSa z&dbtE>1E^P=jHDe=%w-s@e1<__loq2_KNk2_e%7t_UiFk@&+}uFo|-*ZExUbBoUcpM^fR`z-c((&xCZ zg|CgTyRX_e!Z*=3-8b8}#8>OvVebDzI-z~n+`|kBU z=X>7wg6}WB7kz*Cqx`TR%w)=jZRI_KWq4_e=Df;+NuA;8)~V;#cZt z@*{pX`Q75Tz;A`$-F~b5R{L%9d(m&F-^+flPOh6geRBKcj>(<=7XJ4Bf&ME05dSd$ zaQ{gEX#ZIMc>hHIDgLGY<^Gla)&8~q_5Kb1jsDI4E&kK|r~5DPU+@2x|F;3kfT)1# zfS!O=0Z#~_&MO$Kq?RiGJ#y6 zS72tKCa^NFI z7ZedRH7Gl%BuE?76=VvU7j#?D(x7EQcLuErS{-y>(EUMMf?f|g9&|G3+o11*&IFwe zIv;c)=oi%lm7U5#<)m^^xvJb%lT{(AFjcrJQWdRAS7oZQR5_|9m0s1QGO1>(=BjQ{ zEl@2~-LC3WJ)+vCdQA01@YLYa;PT+g;F{p?f`19I3b6^X3vmo_32_VY4Dk-}3ke8O zg`|dLgiH;|4#^EE2q_9F2`LS!2&oFG37H$RGUU0C&q7hCUubUV^w5Q&>q8$2-5&Zx z=u@FPL*ER2C-lA0J)!$T_lF(`{WSD==y#!~L(hg@2>mtm_b@8VD=axIKddyYBCI;B zF047MHEeoVdss)<%CI-XPKKRTQ|bw7JGGlSP@SYsR_Cir)TQbQb*;Kyty4FtyVTw4 z8`TTc3)PF%%hY$O?^dr;Kcs$Gy<7dhdXIXa`eXGc>d(|i)Ss(=RsSB2!s&1}oDa7M zw+VL&pBU~QJ}KNgJS;pSJUTo!JU_fJyf(Z(ydk_X+z{RsZVI0rzBqh!_?qws!h0iv zBjO_xBc?>8M!XksFyc(axrm=4eu?-kl8U4wxk!u1agkP$-jRNh{*i%^s>o1yK~h8{ zymKcqJ~A<~IR8e_RGoo&dS{Ah;YGu?tQGHRHqqatEi+Vijsim2JE z>l^DI8x$KH8y}k#n;e@OTNT?FYlxi{YmDuVy)kxS?4sDEvCCuciM=oOf!My-b+LQn za9mJaWL!*Kd|YB&L0n~AOM0||Wz4<>9#*qpE>;iZJP65dPLldvygf5Mju z-z1z$IFoQL;n#%U6RAWxkxiVC=#dznn3$NEs7b6&tV?W2Y)YJ-I5W|Z*p+BXoS(Qf zaarR1i4P@iO5Bq8XyRju&nNCkd^z#e#McwwOx%-rF!AfeKa$2J*(Et9xg@zIc_sxU z1tkS1g(j(!B9cmy3`xtAHYYuu^k&jKN$(}?N!pk6anh$rhmwva{g8An>3q_Kq+gOQ zCjCBznu4b=Q`A!$r!1ZF;*=A~PRY5+*Ca1UzAbri@*T-{Cf}93F?oCPQ_0UJzmU8m z`JLpw$sZ*jNIsbSMe?!aC&3g z^l7bW)6?41deW{^&h4f$2f6Fjskc^u%7G&I(u_$9n#&a2OWPFhEVaEQ9PclBsIF@lDZz$`vTn+{BkRGe z4OyGBwq|Y1dOYi?tY@=c$l96pO4i3&pJsiQbvWy2)|XkwvW{n+%=#|t`>ZqBmf5Q8 z;%sB~%Ip`ikLFN0?l}oL897-wxjFecGGQMTJxso z&CKh}Gv>|CyFG77-W_?%^H$`o%)2M=-n=z=YxDZ@*5$pFcO;+5_s!4A@62D3|5*N> z{O|KG)pJW$YE&|k2zJZz$eeyruZb z;vK~=6~9uvtN8WeH;X?i{Q*vF&O(pY77M9#zvbf~QlH(c+jg7`#qt--d5;ZxRI*nG-u9>AVYG!M$ z)y&h}pdp$&G;1{5HBV@s);yOH&F`fyrE#V8r9$bt(zi-am5nb80!v9rSy@?SS#?=cS$mnGtgEcMY;M^#Weds{ zl`Sn>UbeDqb=jJ-2g;r=J6!f{*_pDlW#`L&E&HvUD#zv4kBu`c(#0swzV&>nj&mK2^E1@|DWh zD&MF)PRyuqGoK3XH9fXdQC=6W=&R2eoawLRZT;UzNV|DyJl|9wKdn*2sKM;9<13~ zv#sW_nkQ;ruGv-ddd*ukyKCO7`MBoOn$Kzu*L+)Zw&r}z&ovio=~}MVqIO)ZWo<}p zYwaDiYiifl_Sdej-B`Q1_T}2QYxmY3tUX+Ny!QLrb9JbWspIR$)QzvRs`IT2sf(>k zsGCt|s+(W8xbE({{<;lyo9njLJy!Q*-7|I1)g7z1t9PsSs}HCTuTQ9-QlD3^t#7Q? z*H5dTQQuKNtKL*Ur~aDy#q~?;m)EbTUs=Dpeog(_`u_R{>mRD$UjJtO=k-5o$7wya zf!Z`}t+q+qrd^_4p?yHRRr{3oY3;Mx*R}6!_i8`V9?%}tex*IG{YHCAdq#V zLux~J!?g`JHr(8>xM4-Z%7)bqYZ@MCc(~!Qh9?`IX?VWjm4??E-fVcM;oXLxbUwOb zUA3-O*QV>#8FjODJvu>mlWx9lq3(9w3f;ZBb-IW3&*@*(zpme>KdApge_H=r3)Mom za4i-s<65j*Cbqb@c(!=A__g@A1h%MJN?PW$^tQa+@?pzoEyr3;$QBHY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/xcuserdata/wangchujiang.xcuserdatad/xcschemes/xcschememanagement.plist b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/xcuserdata/wangchujiang.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..758ee82 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager.xcodeproj/xcuserdata/wangchujiang.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + InAppPurchaseManager.xcscheme_^#shared#^_ + + orderHint + 0 + + + SuppressBuildableAutocreation + + 7D4C0A5F2C3ED21B0050CB10 + + primary + + + + + diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AccentColor.colorset/Contents.json b/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..532cd72 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,63 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/Contents.json b/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/ContentView.swift b/examples/InAppPurchaseManager/InAppPurchaseManager/ContentView.swift new file mode 100644 index 0000000..c109c8e --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/ContentView.swift @@ -0,0 +1,28 @@ +// +// ContentView.swift +// InAppPurchaseManager +// +// Created by 王楚江 on 2024/7/10. +// + +import SwiftUI + +struct ContentView: View { + @EnvironmentObject private var entitlement: EntitlementManager + @State var showingSubscriptionView = false + var body: some View { + VStack { + if entitlement.hasPro == false { + Button("Subscription Purchase") { + showingSubscriptionView.toggle() + } + } else { + Text("You have subscribed to purchase") + } + } + .padding() + .sheet(isPresented: $showingSubscriptionView) { + SubscriptionView() + } + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManager.entitlements b/examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManager.entitlements new file mode 100644 index 0000000..f2ef3ae --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManager.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + + diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManagerApp.swift b/examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManagerApp.swift new file mode 100644 index 0000000..24b1901 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/InAppPurchaseManagerApp.swift @@ -0,0 +1,27 @@ +// +// InAppPurchaseManagerApp.swift +// InAppPurchaseManager +// +// Created by 王楚江 on 2024/7/10. +// + +import SwiftUI + +@main +struct InAppPurchaseManagerApp: App { + @StateObject private var entitlementManager: EntitlementManager + @StateObject private var subscriptionsManager: SubscriptionsManager + init() { + let entitlement = EntitlementManager() + let subscriptions = SubscriptionsManager(entitlementManager: entitlement) + self._entitlementManager = StateObject(wrappedValue: entitlement) + self._subscriptionsManager = StateObject(wrappedValue: subscriptions) + } + var body: some Scene { + WindowGroup { + ContentView() + .environmentObject(entitlementManager) + .environmentObject(subscriptionsManager) + } + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/Preview Content/Preview Assets.xcassets/Contents.json b/examples/InAppPurchaseManager/InAppPurchaseManager/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/SubscriptionView.swift b/examples/InAppPurchaseManager/InAppPurchaseManager/SubscriptionView.swift new file mode 100644 index 0000000..e218865 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/SubscriptionView.swift @@ -0,0 +1,61 @@ +// +// SubscriptionView.swift +// InAppPurchaseManager +// +// Created by 王楚江 on 2024/7/10. +// + +import SwiftUI +import StoreKit + +struct SubscriptionView: View { + @Environment(\.dismiss) var dismiss + @EnvironmentObject private var subscriptions: SubscriptionsManager + @State private var message: String = "" + let privacyPolicy = URL(string: "https://wangchujiang.com/copybook-generator/privacy-policy.html")! + let termsOfService = URL(string: "https://wangchujiang.com/copybook-generator/terms-of-service.html")! + var body: some View { + if !subscriptions.products.isEmpty { + VStack { + SubscriptionStoreView(productIDs: subscriptions.productIDs) + .storeButton(.visible, for: .policies) + .subscriptionStorePolicyDestination(url: privacyPolicy, for: .privacyPolicy) + .subscriptionStorePolicyDestination(url: termsOfService, for: .termsOfService) + .onInAppPurchaseCompletion(perform: { product, result in + if case .success(.success(let transaction)) = result { + print("Purchased successfully: \(transaction.signedDate)") + await subscriptions.updatePurchasedProducts() + dismiss() + } else { + print("Something else happened") + } + }) + Button(action: { + Task { + await subscriptions.restorePurchases() + dismiss() + } + }, label: { + Text("Restore Subscription") + }) + #if os(macOS) + .buttonStyle(.link) + #endif + .offset(y: -22) + } + .background(.background) + .frame(minWidth: 320, minHeight: 580) + .frame(maxWidth: 450) + } else { + VStack { + if message.isEmpty { + ProgressView().progressViewStyle(.circular).scaleEffect(1).ignoresSafeArea(.all) + } else { + Text(message).foregroundStyle(.red) + } + } + .padding(.horizontal) + .frame(minWidth: 230, minHeight: 120) + } + } +} diff --git a/examples/InAppPurchaseManager/InAppPurchaseManager/store.swift b/examples/InAppPurchaseManager/InAppPurchaseManager/store.swift new file mode 100644 index 0000000..7b18531 --- /dev/null +++ b/examples/InAppPurchaseManager/InAppPurchaseManager/store.swift @@ -0,0 +1,159 @@ +// +// store.swift +// InAppPurchaseManager +// +// Created by 王楚江 on 2024/7/10. +// + +import SwiftUI +import StoreKit + +/// 管理用户的权限状态 +class EntitlementManager: ObservableObject { + /// UserDefaults 实例,用于存储权限状态 + static let userDefaults = UserDefaults(suiteName: "com.wangchujiang.InAppPurchaseManager.vip")! + /// 使用 @AppStorage 将 hasPro 属性保存到 UserDefaults 中 + @AppStorage("hasPro", store: userDefaults) var hasPro: Bool = false +} + +/// 管理订阅产品和购买记录 +@MainActor class SubscriptionsManager: NSObject, ObservableObject { + /// 订阅产品的标识符数组 + let productIDs: [String] = [ + "com.wangchujiang.InAppPurchaseManager.monthly", + "com.wangchujiang.InAppPurchaseManager.yearly", + "com.wangchujiang.InAppPurchaseManager.lifetime" + ] + /// 记录已购买的产品标识符集合 + var purchasedProductIDs: Set = [] + /// 发布订阅产品信息 + @Published var products: [Product] = [] + /// 授权管理器 + private var entitlementManager: EntitlementManager? = nil + /// 更新任务 + private var updates: Task? = nil + /// 初始化方法,接收 EntitlementManager 实例作为参数 + init(entitlementManager: EntitlementManager) { + self.entitlementManager = entitlementManager + super.init() + // 监听交易更新 + self.updates = observeTransactionUpdates() + Task { + await self.loadProducts(action: { err, success in + + }) + } + // 添加自身作为 SKPaymentTransactionObserver + SKPaymentQueue.default().add(self) + } + // 析构方法,取消更新任务 + deinit { + updates?.cancel() + } + // MARK: - 观察交易更新 + /// 异步观察交易更新 + func observeTransactionUpdates() -> Task { + Task(priority: .background) { [unowned self] in + for await _ in Transaction.updates { + await self.updatePurchasedProducts() + } + } + } +} + +// MARK: - StoreKit2 API 扩展 +extension SubscriptionsManager { + // MARK: - 加载产品列表 + /// 异步加载产品列表 + func loadProducts(action: ((_ err: String?, _ success: Bool) -> Void)?) async { + do { + // 使用 Product.products(for:) 加载产品信息,并按价格排序 + self.products = try await Product.products(for: productIDs).sorted(by: { $0.price > $1.price }) + print("self.product: \(self.products)") + action?(nil, true) + } catch { + let errorString = String(localized: "Failed to get the product! Please check the network! \n\(error.localizedDescription)") + action?(errorString, false) + } + } + // MARK: - 购买产品 + /// 异步购买产品 + func buyProduct(_ product: Product) async { + do { + // 使用 product.purchase() 进行产品购买 + let result = try await product.purchase() + switch result { + case let .success(.verified(transaction)): + print("Successful purhcase 成功购买") + // 完成交易并更新已购买产品 + await transaction.finish() + await self.updatePurchasedProducts() + case let .success(.unverified(_, error)): + // Successful purchase but transaction/receipt can't be verified + // Could be a jailbroken phone + // 购买成功,但交易/收据无法验证 + // 可能是越狱手机 + print("Unverified purchase. Might be jailbroken. Error: \(error)") + break + case .pending: + // Transaction waiting on SCA (Strong Customer Authentication) or approval from Ask to Buy + // 等待 SCA(Strong Customer Authentication)或“要求购买”批准的交易 + break + case .userCancelled: + print("User cancelled!") + break + @unknown default: + print("Failed to purchase the product!") + break + } + } catch { + print("Failed to purchase the product!") + } + } + // MARK: - 更新已购买的产品 + /// 异步更新已购买的产品 + func updatePurchasedProducts() async { + /// 一系列最新交易,使用户有权进行应用内购买和订阅。 + for await result in Transaction.currentEntitlements { + guard case .verified(let transaction) = result else { + continue + } + if transaction.revocationDate == nil { + // 如果交易未被撤销,则将产品标识符添加到已购买集合中 + if !self.purchasedProductIDs.contains(transaction.productID) { + self.purchasedProductIDs.insert(transaction.productID) + } + } else { + // 如果交易被撤销,则从已购买集合中移除产品标识符 + self.purchasedProductIDs.remove(transaction.productID) + } + } + // 更新 EntitlementManager 的 hasPro 属性 + self.entitlementManager?.hasPro = !self.purchasedProductIDs.isEmpty + } + // MARK: - 恢复购买 + /// 异步恢复购买 + func restorePurchases() async { + do { + // 同步应用内购买信息 + try await AppStore.sync() + // 更新已购买的产品 + await updatePurchasedProducts() + } catch { + print(error) + } + } +} + +// MARK: - SKPaymentTransactionObserver 实现 +extension SubscriptionsManager: SKPaymentTransactionObserver { + // 支付队列更新交易 + func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { + print("Subscriptions Payment Queue! updated!") + } + // 应用内购买准备添加到支付队列 + func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool { + print("Subscriptions Payment Queue! Should Add Store Payment!") + return true + } +} diff --git a/examples/InAppPurchaseManager/Product.storekit b/examples/InAppPurchaseManager/Product.storekit new file mode 100644 index 0000000..ff4515c --- /dev/null +++ b/examples/InAppPurchaseManager/Product.storekit @@ -0,0 +1,166 @@ +{ + "identifier" : "8F58A673", + "nonRenewingSubscriptions" : [ + + ], + "products" : [ + + ], + "settings" : { + "_failTransactionsEnabled" : false, + "_locale" : "en_US", + "_storefront" : "USA", + "_storeKitErrors" : [ + { + "current" : null, + "enabled" : false, + "name" : "Load Products" + }, + { + "current" : null, + "enabled" : false, + "name" : "Purchase" + }, + { + "current" : null, + "enabled" : false, + "name" : "Verification" + }, + { + "current" : null, + "enabled" : false, + "name" : "App Store Sync" + }, + { + "current" : null, + "enabled" : false, + "name" : "Subscription Status" + }, + { + "current" : null, + "enabled" : false, + "name" : "App Transaction" + }, + { + "current" : null, + "enabled" : false, + "name" : "Manage Subscriptions Sheet" + }, + { + "current" : null, + "enabled" : false, + "name" : "Refund Request Sheet" + }, + { + "current" : null, + "enabled" : false, + "name" : "Offer Code Redeem Sheet" + } + ] + }, + "subscriptionGroups" : [ + { + "id" : "2F793903", + "localizations" : [ + + ], + "name" : "VIP Pro Example", + "subscriptions" : [ + { + "adHocOffers" : [ + + ], + "codeOffers" : [ + + ], + "displayPrice" : "0.99", + "familyShareable" : false, + "groupNumber" : 1, + "internalID" : "FF45B2EF", + "introductoryOffer" : null, + "localizations" : [ + { + "description" : "All Access Monthly", + "displayName" : "Pro Monthly", + "locale" : "en_US" + }, + { + "description" : "每月全部访问", + "displayName" : "专业月会员", + "locale" : "zh_CN" + } + ], + "productID" : "com.wangchujiang.InAppPurchaseManager.monthly", + "recurringSubscriptionPeriod" : "P1M", + "referenceName" : "Pro Monthly", + "subscriptionGroupID" : "2F793903", + "type" : "RecurringSubscription" + }, + { + "adHocOffers" : [ + + ], + "codeOffers" : [ + + ], + "displayPrice" : "12.99", + "familyShareable" : false, + "groupNumber" : 1, + "internalID" : "908E4B0F", + "introductoryOffer" : null, + "localizations" : [ + { + "description" : "All Access Annually", + "displayName" : "Pro Yearly", + "locale" : "en_US" + }, + { + "description" : "每年全部访问", + "displayName" : "专业年会员", + "locale" : "zh_CN" + } + ], + "productID" : "com.wangchujiang.InAppPurchaseManager.yearly", + "recurringSubscriptionPeriod" : "P1M", + "referenceName" : "Pro Yearly", + "subscriptionGroupID" : "2F793903", + "type" : "RecurringSubscription" + }, + { + "adHocOffers" : [ + + ], + "codeOffers" : [ + + ], + "displayPrice" : "66.99", + "familyShareable" : false, + "groupNumber" : 1, + "internalID" : "26539A2F", + "introductoryOffer" : null, + "localizations" : [ + { + "description" : "All Access Lifetime", + "displayName" : "Pro Lifetime", + "locale" : "en_US" + }, + { + "description" : "全部终生访问", + "displayName" : "专业终生版", + "locale" : "zh_CN" + } + ], + "productID" : "com.wangchujiang.InAppPurchaseManager.lifetime", + "recurringSubscriptionPeriod" : "P1M", + "referenceName" : "Pro Lifetime", + "subscriptionGroupID" : "2F793903", + "type" : "RecurringSubscription" + } + ] + } + ], + "version" : { + "major" : 3, + "minor" : 0 + } +}