فهرست منبع

Share iOS ViewController on tvOS

Andrea Bizzotto 8 سال پیش
والد
کامیت
07aa26c558

+ 4 - 0
SwiftyStoreKit-iOS-Demo/NetworkActivityIndicatorManager.swift

@@ -30,18 +30,22 @@ class NetworkActivityIndicatorManager: NSObject {
 
     class func networkOperationStarted() {
 
+        #if os(iOS)
         if loadingCount == 0 {
             UIApplication.shared.isNetworkActivityIndicatorVisible = true
         }
         loadingCount += 1
+        #endif
     }
 
     class func networkOperationFinished() {
+        #if os(iOS)
         if loadingCount > 0 {
             loadingCount -= 1
         }
         if loadingCount == 0 {
             UIApplication.shared.isNetworkActivityIndicatorVisible = false
         }
+        #endif
     }
 }

+ 2 - 0
SwiftyStoreKit-iOS-Demo/ViewController.swift

@@ -178,9 +178,11 @@ class ViewController: UIViewController {
         }
     }
 
+#if os(iOS)
     override var preferredStatusBarStyle: UIStatusBarStyle {
         return .lightContent
     }
+#endif
 }
 
 // MARK: User facing alerts

+ 0 - 283
SwiftyStoreKit-tvOS-Demo/ViewController.swift

@@ -1,283 +0,0 @@
-//
-//  ViewController.swift
-//  SwiftyStoreKit-tvOS-Demo
-//
-//  Created by Andrea Bizzotto on 15/03/2017.
-//  Copyright © 2017 musevisions. All rights reserved.
-//
-
-import UIKit
-import StoreKit
-import SwiftyStoreKit
-
-enum RegisteredPurchase: String {
-
-    case purchase1
-    case purchase2
-    case nonConsumablePurchase
-    case consumablePurchase
-    case autoRenewablePurchase
-    case nonRenewingPurchase
-}
-
-class ViewController: UIViewController {
-
-    let appBundleId = "com.musevisions.tvOS.SwiftyStoreKit"
-
-    let purchase1Suffix = RegisteredPurchase.purchase1
-    let purchase2Suffix = RegisteredPurchase.autoRenewablePurchase
-
-    // MARK: actions
-    @IBAction func getInfo1() {
-        getInfo(purchase1Suffix)
-    }
-    @IBAction func purchase1() {
-        purchase(purchase1Suffix)
-    }
-    @IBAction func verifyPurchase1() {
-        verifyPurchase(purchase1Suffix)
-    }
-    @IBAction func getInfo2() {
-        getInfo(purchase2Suffix)
-    }
-    @IBAction func purchase2() {
-        purchase(purchase2Suffix)
-    }
-    @IBAction func verifyPurchase2() {
-        verifyPurchase(purchase2Suffix)
-    }
-
-    func getInfo(_ purchase: RegisteredPurchase) {
-
-        SwiftyStoreKit.retrieveProductsInfo([appBundleId + "." + purchase.rawValue]) { result in
-
-            self.showAlert(self.alertForProductRetrievalInfo(result))
-        }
-    }
-
-    func purchase(_ purchase: RegisteredPurchase) {
-
-        SwiftyStoreKit.purchaseProduct(appBundleId + "." + purchase.rawValue, atomically: true) { result in
-
-            if case .success(let product) = result {
-                // Deliver content from server, then:
-                if product.needsFinishTransaction {
-                    SwiftyStoreKit.finishTransaction(product.transaction)
-                }
-            }
-            if let alert = self.alertForPurchaseResult(result) {
-                self.showAlert(alert)
-            }
-        }
-    }
-
-    @IBAction func restorePurchases() {
-
-        SwiftyStoreKit.restorePurchases(atomically: true) { results in
-
-            for product in results.restoredProducts {
-                // Deliver content from server, then:
-                if product.needsFinishTransaction {
-                    SwiftyStoreKit.finishTransaction(product.transaction)
-                }
-            }
-            self.showAlert(self.alertForRestorePurchases(results))
-        }
-    }
-
-    @IBAction func verifyReceipt() {
-
-        let appleValidator = AppleReceiptValidator(service: .production)
-        SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secret") { result in
-
-            self.showAlert(self.alertForVerifyReceipt(result))
-
-            if case .error(let error) = result {
-                if case .noReceiptData = error {
-                    self.refreshReceipt()
-                }
-            }
-        }
-    }
-
-    func verifyPurchase(_ purchase: RegisteredPurchase) {
-
-        let appleValidator = AppleReceiptValidator(service: .production)
-        SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secret") { result in
-
-            switch result {
-            case .success(let receipt):
-
-                let productId = self.appBundleId + "." + purchase.rawValue
-
-                switch purchase {
-                case .autoRenewablePurchase:
-                    let purchaseResult = SwiftyStoreKit.verifySubscription(
-                        type: .autoRenewable,
-                        productId: productId,
-                        inReceipt: receipt,
-                        validUntil: Date()
-                    )
-                    self.showAlert(self.alertForVerifySubscription(purchaseResult))
-                case .nonRenewingPurchase:
-                    let purchaseResult = SwiftyStoreKit.verifySubscription(
-                        type: .nonRenewing(validDuration: 60),
-                        productId: productId,
-                        inReceipt: receipt,
-                        validUntil: Date()
-                    )
-                    self.showAlert(self.alertForVerifySubscription(purchaseResult))
-                default:
-                    let purchaseResult = SwiftyStoreKit.verifyPurchase(
-                        productId: productId,
-                        inReceipt: receipt
-                    )
-                    self.showAlert(self.alertForVerifyPurchase(purchaseResult))
-                }
-
-            case .error(let error):
-                self.showAlert(self.alertForVerifyReceipt(result))
-                if case .noReceiptData = error {
-                    self.refreshReceipt()
-                }
-            }
-        }
-    }
-
-    func refreshReceipt() {
-
-        SwiftyStoreKit.refreshReceipt { result in
-
-            self.showAlert(self.alertForRefreshReceipt(result))
-        }
-    }
-
-}
-
-// MARK: User facing alerts
-extension ViewController {
-
-    func alertWithTitle(_ title: String, message: String) -> UIAlertController {
-
-        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
-        alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
-        return alert
-    }
-
-    func showAlert(_ alert: UIAlertController) {
-        guard let _ = self.presentedViewController else {
-            self.present(alert, animated: true, completion: nil)
-            return
-        }
-    }
-
-    func alertForProductRetrievalInfo(_ result: RetrieveResults) -> UIAlertController {
-
-        if let product = result.retrievedProducts.first {
-            let priceString = product.localizedPrice!
-            return alertWithTitle(product.localizedTitle, message: "\(product.localizedDescription) - \(priceString)")
-        } else if let invalidProductId = result.invalidProductIDs.first {
-            return alertWithTitle("Could not retrieve product info", message: "Invalid product identifier: \(invalidProductId)")
-        } else {
-            let errorString = result.error?.localizedDescription ?? "Unknown error. Please contact support"
-            return alertWithTitle("Could not retrieve product info", message: errorString)
-        }
-    }
-
-    func alertForPurchaseResult(_ result: PurchaseResult) -> UIAlertController? {
-        switch result {
-        case .success(let product):
-            print("Purchase Success: \(product.productId)")
-            return alertWithTitle("Thank You", message: "Purchase completed")
-        case .error(let error):
-            print("Purchase Failed: \(error)")
-            switch error.code {
-            case .unknown: return alertWithTitle("Purchase failed", message: "Unknown error. Please contact support")
-            case .clientInvalid: // client is not allowed to issue the request, etc.
-                return alertWithTitle("Purchase failed", message: "Not allowed to make the payment")
-            case .paymentCancelled: // user cancelled the request, etc.
-                return nil
-            case .paymentInvalid: // purchase identifier was invalid, etc.
-                return alertWithTitle("Purchase failed", message: "The purchase identifier was invalid")
-            case .paymentNotAllowed: // this device is not allowed to make the payment
-                return alertWithTitle("Purchase failed", message: "The device is not allowed to make the payment")
-            case .storeProductNotAvailable: // Product is not available in the current storefront
-                return alertWithTitle("Purchase failed", message: "The product is not available in the current storefront")
-            case .cloudServicePermissionDenied: // user has not allowed access to cloud service information
-                return alertWithTitle("Purchase failed", message: "Access to cloud service information is not allowed")
-            case .cloudServiceNetworkConnectionFailed: // the device could not connect to the nework
-                return alertWithTitle("Purchase failed", message: "Could not connect to the network")
-            }
-        }
-    }
-
-    func alertForRestorePurchases(_ results: RestoreResults) -> UIAlertController {
-
-        if results.restoreFailedProducts.count > 0 {
-            print("Restore Failed: \(results.restoreFailedProducts)")
-            return alertWithTitle("Restore failed", message: "Unknown error. Please contact support")
-        } else if results.restoredProducts.count > 0 {
-            print("Restore Success: \(results.restoredProducts)")
-            return alertWithTitle("Purchases Restored", message: "All purchases have been restored")
-        } else {
-            print("Nothing to Restore")
-            return alertWithTitle("Nothing to restore", message: "No previous purchases were found")
-        }
-    }
-
-    func alertForVerifyReceipt(_ result: VerifyReceiptResult) -> UIAlertController {
-
-        switch result {
-        case .success(let receipt):
-            print("Verify receipt Success: \(receipt)")
-            return alertWithTitle("Receipt verified", message: "Receipt verified remotly")
-        case .error(let error):
-            print("Verify receipt Failed: \(error)")
-            switch error {
-            case .noReceiptData :
-                return alertWithTitle("Receipt verification", message: "No receipt data, application will try to get a new one. Try again.")
-            default:
-                return alertWithTitle("Receipt verification", message: "Receipt verification failed")
-            }
-        }
-    }
-
-    func alertForVerifySubscription(_ result: VerifySubscriptionResult) -> UIAlertController {
-
-        switch result {
-        case .purchased(let expiresDate):
-            print("Product is valid until \(expiresDate)")
-            return alertWithTitle("Product is purchased", message: "Product is valid until \(expiresDate)")
-        case .expired(let expiresDate):
-            print("Product is expired since \(expiresDate)")
-            return alertWithTitle("Product expired", message: "Product is expired since \(expiresDate)")
-        case .notPurchased:
-            print("This product has never been purchased")
-            return alertWithTitle("Not purchased", message: "This product has never been purchased")
-        }
-    }
-
-    func alertForVerifyPurchase(_ result: VerifyPurchaseResult) -> UIAlertController {
-
-        switch result {
-        case .purchased:
-            print("Product is purchased")
-            return alertWithTitle("Product is purchased", message: "Product will not expire")
-        case .notPurchased:
-            print("This product has never been purchased")
-            return alertWithTitle("Not purchased", message: "This product has never been purchased")
-        }
-    }
-
-    func alertForRefreshReceipt(_ result: RefreshReceiptResult) -> UIAlertController {
-        switch result {
-        case .success(let receiptData):
-            print("Receipt refresh Success: \(receiptData.base64EncodedString)")
-            return alertWithTitle("Receipt refreshed", message: "Receipt refreshed successfully")
-        case .error(let error):
-            print("Receipt refresh Failed: \(error)")
-            return alertWithTitle("Receipt refresh failed", message: "Receipt refresh failed")
-        }
-    }
-
-}

+ 7 - 6
SwiftyStoreKit.xcodeproj/project.pbxproj

@@ -31,11 +31,12 @@
 		653722821DB8290A00C8F944 /* SKProduct+LocalizedPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653722801DB8282600C8F944 /* SKProduct+LocalizedPrice.swift */; };
 		653722831DB8290B00C8F944 /* SKProduct+LocalizedPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653722801DB8282600C8F944 /* SKProduct+LocalizedPrice.swift */; };
 		654287F11E79F5A000F61800 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 654287F01E79F5A000F61800 /* AppDelegate.swift */; };
-		654287F31E79F5A000F61800 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 654287F21E79F5A000F61800 /* ViewController.swift */; };
 		654287F61E79F5A000F61800 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 654287F41E79F5A000F61800 /* Main.storyboard */; };
 		654287F81E79F5A000F61800 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 654287F71E79F5A000F61800 /* Assets.xcassets */; };
 		654287FD1E79F75000F61800 /* SwiftyStoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54C0D52C1CF7404500F90BCE /* SwiftyStoreKit.framework */; };
 		654287FE1E79F75000F61800 /* SwiftyStoreKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 54C0D52C1CF7404500F90BCE /* SwiftyStoreKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		654288021E7B34E500F61800 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F7DF701DCD4DF000835D30 /* ViewController.swift */; };
+		654288061E7B3A8800F61800 /* NetworkActivityIndicatorManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F7DF6F1DCD4DF000835D30 /* NetworkActivityIndicatorManager.swift */; };
 		658A08371E2EC24E0074A98F /* PaymentQueueController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658A08361E2EC24E0074A98F /* PaymentQueueController.swift */; };
 		658A08381E2EC24E0074A98F /* PaymentQueueController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658A08361E2EC24E0074A98F /* PaymentQueueController.swift */; };
 		658A08391E2EC24E0074A98F /* PaymentQueueController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658A08361E2EC24E0074A98F /* PaymentQueueController.swift */; };
@@ -168,7 +169,6 @@
 		653722801DB8282600C8F944 /* SKProduct+LocalizedPrice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SKProduct+LocalizedPrice.swift"; sourceTree = "<group>"; };
 		654287EE1E79F5A000F61800 /* SwiftyStoreKit-tvOSDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SwiftyStoreKit-tvOSDemo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		654287F01E79F5A000F61800 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
-		654287F21E79F5A000F61800 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
 		654287F51E79F5A000F61800 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
 		654287F71E79F5A000F61800 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		654287F91E79F5A000F61800 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -317,7 +317,6 @@
 			isa = PBXGroup;
 			children = (
 				654287F01E79F5A000F61800 /* AppDelegate.swift */,
-				654287F21E79F5A000F61800 /* ViewController.swift */,
 				654287F41E79F5A000F61800 /* Main.storyboard */,
 				654287F71E79F5A000F61800 /* Assets.xcassets */,
 				654287F91E79F5A000F61800 /* Info.plist */,
@@ -754,8 +753,9 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				654287F31E79F5A000F61800 /* ViewController.swift in Sources */,
+				654288021E7B34E500F61800 /* ViewController.swift in Sources */,
 				654287F11E79F5A000F61800 /* AppDelegate.swift in Sources */,
+				654288061E7B3A8800F61800 /* NetworkActivityIndicatorManager.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1102,7 +1102,7 @@
 				DEVELOPMENT_TEAM = M54ZVB688G;
 				INFOPLIST_FILE = "SwiftyStoreKit-tvOS-Demo/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				PRODUCT_BUNDLE_IDENTIFIER = com.musevisions.tvOS.SwiftyStoreKitDemo;
+				PRODUCT_BUNDLE_IDENTIFIER = com.musevisions.iOS.SwiftyStoreDemo;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = appletvos;
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
@@ -1123,7 +1123,7 @@
 				DEVELOPMENT_TEAM = M54ZVB688G;
 				INFOPLIST_FILE = "SwiftyStoreKit-tvOS-Demo/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				PRODUCT_BUNDLE_IDENTIFIER = com.musevisions.tvOS.SwiftyStoreKitDemo;
+				PRODUCT_BUNDLE_IDENTIFIER = com.musevisions.iOS.SwiftyStoreDemo;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = appletvos;
 				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -1293,6 +1293,7 @@
 				654287FB1E79F5A000F61800 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
 		};
 		658A08461E2EC5120074A98F /* Build configuration list for PBXNativeTarget "SwiftyStoreKitTests" */ = {
 			isa = XCConfigurationList;