Commit 580f1c88 by Demid Merzlyakov

IOS-155: Add SwiftyStoreKit.

parent 93871b28
...@@ -47,6 +47,7 @@ def application_pods ...@@ -47,6 +47,7 @@ def application_pods
pod 'Nuke' pod 'Nuke'
pod 'Nuke-WebP-Plugin' pod 'Nuke-WebP-Plugin'
pod 'pop', :git => 'https://github.com/facebook/pop.git' pod 'pop', :git => 'https://github.com/facebook/pop.git'
pod 'SwiftyStoreKit'
end end
#-------Targets------- #-------Targets-------
......
...@@ -187,6 +187,7 @@ PODS: ...@@ -187,6 +187,7 @@ PODS:
- PromisesObjC (2.0.0) - PromisesObjC (2.0.0)
- SnapKit (5.0.1) - SnapKit (5.0.1)
- Swarm (1.0.7) - Swarm (1.0.7)
- SwiftyStoreKit (0.16.1)
- XMLCoder (0.12.0) - XMLCoder (0.12.0)
DEPENDENCIES: DEPENDENCIES:
...@@ -214,6 +215,7 @@ DEPENDENCIES: ...@@ -214,6 +215,7 @@ DEPENDENCIES:
- pop (from `https://github.com/facebook/pop.git`) - pop (from `https://github.com/facebook/pop.git`)
- SnapKit - SnapKit
- "Swarm (from `git@gitlab.pinsightmedia.com:oneweather/wdt-skywisetilekit-ios.git`, branch `develop`)" - "Swarm (from `git@gitlab.pinsightmedia.com:oneweather/wdt-skywisetilekit-ios.git`, branch `develop`)"
- SwiftyStoreKit
- XMLCoder (~> 0.12.0) - XMLCoder (~> 0.12.0)
SPEC REPOS: SPEC REPOS:
...@@ -255,6 +257,7 @@ SPEC REPOS: ...@@ -255,6 +257,7 @@ SPEC REPOS:
- PKHUD - PKHUD
- PromisesObjC - PromisesObjC
- SnapKit - SnapKit
- SwiftyStoreKit
- XMLCoder - XMLCoder
EXTERNAL SOURCES: EXTERNAL SOURCES:
...@@ -318,8 +321,9 @@ SPEC CHECKSUMS: ...@@ -318,8 +321,9 @@ SPEC CHECKSUMS:
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58 PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
Swarm: 95393cd52715744c94e3a8475bc20b4de5d79f35 Swarm: 95393cd52715744c94e3a8475bc20b4de5d79f35
SwiftyStoreKit: 6b9c08810269f030586dac1fae8e75871a82e84a
XMLCoder: f884dfa894a6f8b7dce465e4f6c02963bf17e028 XMLCoder: f884dfa894a6f8b7dce465e4f6c02963bf17e028
PODFILE CHECKSUM: 6b610cb290828c2f023d33cbffc4c28fdf79c46b PODFILE CHECKSUM: 5d3b85c236b1f773ceda818cf9086033176d00ae
COCOAPODS: 1.10.2 COCOAPODS: 1.10.2
...@@ -187,6 +187,7 @@ PODS: ...@@ -187,6 +187,7 @@ PODS:
- PromisesObjC (2.0.0) - PromisesObjC (2.0.0)
- SnapKit (5.0.1) - SnapKit (5.0.1)
- Swarm (1.0.7) - Swarm (1.0.7)
- SwiftyStoreKit (0.16.1)
- XMLCoder (0.12.0) - XMLCoder (0.12.0)
DEPENDENCIES: DEPENDENCIES:
...@@ -214,6 +215,7 @@ DEPENDENCIES: ...@@ -214,6 +215,7 @@ DEPENDENCIES:
- pop (from `https://github.com/facebook/pop.git`) - pop (from `https://github.com/facebook/pop.git`)
- SnapKit - SnapKit
- "Swarm (from `git@gitlab.pinsightmedia.com:oneweather/wdt-skywisetilekit-ios.git`, branch `develop`)" - "Swarm (from `git@gitlab.pinsightmedia.com:oneweather/wdt-skywisetilekit-ios.git`, branch `develop`)"
- SwiftyStoreKit
- XMLCoder (~> 0.12.0) - XMLCoder (~> 0.12.0)
SPEC REPOS: SPEC REPOS:
...@@ -255,6 +257,7 @@ SPEC REPOS: ...@@ -255,6 +257,7 @@ SPEC REPOS:
- PKHUD - PKHUD
- PromisesObjC - PromisesObjC
- SnapKit - SnapKit
- SwiftyStoreKit
- XMLCoder - XMLCoder
EXTERNAL SOURCES: EXTERNAL SOURCES:
...@@ -318,8 +321,9 @@ SPEC CHECKSUMS: ...@@ -318,8 +321,9 @@ SPEC CHECKSUMS:
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58 PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
Swarm: 95393cd52715744c94e3a8475bc20b4de5d79f35 Swarm: 95393cd52715744c94e3a8475bc20b4de5d79f35
SwiftyStoreKit: 6b9c08810269f030586dac1fae8e75871a82e84a
XMLCoder: f884dfa894a6f8b7dce465e4f6c02963bf17e028 XMLCoder: f884dfa894a6f8b7dce465e4f6c02963bf17e028
PODFILE CHECKSUM: 6b610cb290828c2f023d33cbffc4c28fdf79c46b PODFILE CHECKSUM: 5d3b85c236b1f773ceda818cf9086033176d00ae
COCOAPODS: 1.10.2 COCOAPODS: 1.10.2
This source diff could not be displayed because it is too large. You can view the blob instead.
Copyright (c) 2015-2016 Andrea Bizzotto bizz84@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// InAppReceipt.swift
// SwiftyStoreKit
//
// Created by phimage on 22/12/15.
// Copyright (c) 2015 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
// https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
public class AppleReceiptValidator: ReceiptValidator {
public enum VerifyReceiptURLType: String {
case production = "https://buy.itunes.apple.com/verifyReceipt"
case sandbox = "https://sandbox.itunes.apple.com/verifyReceipt"
}
/// You should always verify your receipt first with the `production` service
/// Note: will auto change to `.sandbox` and validate again if received a 21007 status code from Apple
public var service: VerifyReceiptURLType
private let sharedSecret: String?
/**
* Reference Apple Receipt Validator
* - Parameter service: Either .production or .sandbox
* - Parameter sharedSecret: Only used for receipts that contain auto-renewable subscriptions. Your app’s shared secret (a hexadecimal string).
*/
public init(service: VerifyReceiptURLType = .production, sharedSecret: String? = nil) {
self.service = service
self.sharedSecret = sharedSecret
}
public func validate(receiptData: Data, completion: @escaping (VerifyReceiptResult) -> Void) {
let storeURL = URL(string: service.rawValue)! // safe (until no more)
let storeRequest = NSMutableURLRequest(url: storeURL)
storeRequest.httpMethod = "POST"
let receipt = receiptData.base64EncodedString(options: [])
let requestContents: NSMutableDictionary = [ "receipt-data": receipt ]
// password if defined
if let password = sharedSecret {
requestContents.setValue(password, forKey: "password")
}
// Encore request body
do {
storeRequest.httpBody = try JSONSerialization.data(withJSONObject: requestContents, options: [])
} catch let e {
completion(.error(error: .requestBodyEncodeError(error: e)))
return
}
// Remote task
let task = URLSession.shared.dataTask(with: storeRequest as URLRequest) { data, _, error -> Void in
// there is an error
if let networkError = error {
completion(.error(error: .networkError(error: networkError)))
return
}
// there is no data
guard let safeData = data else {
completion(.error(error: .noRemoteData))
return
}
// cannot decode data
guard let receiptInfo = try? JSONSerialization.jsonObject(with: safeData, options: .mutableLeaves) as? ReceiptInfo ?? [:] else {
let jsonStr = String(data: safeData, encoding: String.Encoding.utf8)
completion(.error(error: .jsonDecodeError(string: jsonStr)))
return
}
// get status from info
if let status = receiptInfo["status"] as? Int {
/*
* http://stackoverflow.com/questions/16187231/how-do-i-know-if-an-in-app-purchase-receipt-comes-from-the-sandbox
* How do I verify my receipt (iOS)?
* Always verify your receipt first with the production URL; proceed to verify
* with the sandbox URL if you receive a 21007 status code. Following this
* approach ensures that you do not have to switch between URLs while your
* application is being tested or reviewed in the sandbox or is live in the
* App Store.
* Note: The 21007 status code indicates that this receipt is a sandbox receipt,
* but it was sent to the production service for verification.
*/
let receiptStatus = ReceiptStatus(rawValue: status) ?? ReceiptStatus.unknown
if case .testReceipt = receiptStatus {
self.service = .sandbox
self.validate(receiptData: receiptData, completion: completion)
} else {
if receiptStatus.isValid {
completion(.success(receipt: receiptInfo))
} else {
completion(.error(error: .receiptInvalid(receipt: receiptInfo, status: receiptStatus)))
}
}
} else {
completion(.error(error: .receiptInvalid(receipt: receiptInfo, status: ReceiptStatus.none)))
}
}
task.resume()
}
}
//
// CompleteTransactionsController.swift
// SwiftyStoreKit
//
// Copyright (c) 2017 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import StoreKit
struct CompleteTransactions {
let atomically: Bool
let callback: ([Purchase]) -> Void
init(atomically: Bool, callback: @escaping ([Purchase]) -> Void) {
self.atomically = atomically
self.callback = callback
}
}
class CompleteTransactionsController: TransactionController {
var completeTransactions: CompleteTransactions?
func processTransactions(_ transactions: [SKPaymentTransaction], on paymentQueue: PaymentQueue) -> [SKPaymentTransaction] {
guard let completeTransactions = completeTransactions else {
print("SwiftyStoreKit.completeTransactions() should be called once when the app launches.")
return transactions
}
var unhandledTransactions: [SKPaymentTransaction] = []
var purchases: [Purchase] = []
for transaction in transactions {
let transactionState = transaction.transactionState
if transactionState != .purchasing {
let willFinishTransaction = completeTransactions.atomically || transactionState == .failed
let purchase = Purchase(productId: transaction.payment.productIdentifier, quantity: transaction.payment.quantity, transaction: transaction, originalTransaction: transaction.original, needsFinishTransaction: !willFinishTransaction)
purchases.append(purchase)
if willFinishTransaction {
print("Finishing transaction for payment \"\(transaction.payment.productIdentifier)\" with state: \(transactionState.debugDescription)")
paymentQueue.finishTransaction(transaction)
}
} else {
unhandledTransactions.append(transaction)
}
}
if purchases.count > 0 {
completeTransactions.callback(purchases)
}
return unhandledTransactions
}
}
//
// InAppPurchaseProductRequest.swift
// SwiftyStoreKit
//
// Copyright (c) 2015 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import StoreKit
typealias InAppProductRequestCallback = (RetrieveResults) -> Void
public protocol InAppRequest: class {
func start()
func cancel()
}
protocol InAppProductRequest: InAppRequest { }
class InAppProductQueryRequest: NSObject, InAppProductRequest, SKProductsRequestDelegate {
private let callback: InAppProductRequestCallback
private let request: SKProductsRequest
deinit {
request.delegate = nil
}
init(productIds: Set<String>, callback: @escaping InAppProductRequestCallback) {
self.callback = callback
request = SKProductsRequest(productIdentifiers: productIds)
super.init()
request.delegate = self
}
func start() {
request.start()
}
func cancel() {
request.cancel()
}
// MARK: SKProductsRequestDelegate
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let retrievedProducts = Set<SKProduct>(response.products)
let invalidProductIDs = Set<String>(response.invalidProductIdentifiers)
performCallback(RetrieveResults(retrievedProducts: retrievedProducts,
invalidProductIDs: invalidProductIDs, error: nil))
}
func requestDidFinish(_ request: SKRequest) {
}
func request(_ request: SKRequest, didFailWithError error: Error) {
performCallback(RetrieveResults(retrievedProducts: Set<SKProduct>(), invalidProductIDs: Set<String>(), error: error))
}
private func performCallback(_ results: RetrieveResults) {
DispatchQueue.main.async {
self.callback(results)
}
}
}
//
// InAppReceiptRefreshRequest.swift
// SwiftyStoreKit
//
// Created by phimage on 23/12/15.
// Copyright (c) 2015 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import StoreKit
import Foundation
class InAppReceiptRefreshRequest: NSObject, SKRequestDelegate, InAppRequest {
enum ResultType {
case success
case error(e: Error)
}
typealias RequestCallback = (ResultType) -> Void
typealias ReceiptRefresh = (_ receiptProperties: [String: Any]?, _ callback: @escaping RequestCallback) -> InAppReceiptRefreshRequest
class func refresh(_ receiptProperties: [String: Any]? = nil, callback: @escaping RequestCallback) -> InAppReceiptRefreshRequest {
let request = InAppReceiptRefreshRequest(receiptProperties: receiptProperties, callback: callback)
request.start()
return request
}
let refreshReceiptRequest: SKReceiptRefreshRequest
let callback: RequestCallback
deinit {
refreshReceiptRequest.delegate = nil
}
init(receiptProperties: [String: Any]? = nil, callback: @escaping RequestCallback) {
self.callback = callback
self.refreshReceiptRequest = SKReceiptRefreshRequest(receiptProperties: receiptProperties)
super.init()
self.refreshReceiptRequest.delegate = self
}
func start() {
self.refreshReceiptRequest.start()
}
func cancel() {
self.refreshReceiptRequest.cancel()
}
func requestDidFinish(_ request: SKRequest) {
/*if let resoreRequest = request as? SKReceiptRefreshRequest {
let receiptProperties = resoreRequest.receiptProperties ?? [:]
for (k, v) in receiptProperties {
print("\(k): \(v)")
}
}*/
performCallback(.success)
}
func request(_ request: SKRequest, didFailWithError error: Error) {
// XXX could here check domain and error code to return typed exception
performCallback(.error(e: error))
}
private func performCallback(_ result: ResultType) {
DispatchQueue.main.async {
self.callback(result)
}
}
}
//
// InAppReceiptVerificator.swift
// SwiftyStoreKit
//
// Created by Andrea Bizzotto on 16/05/2017.
// Copyright (c) 2017 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
class InAppReceiptVerificator: NSObject {
let appStoreReceiptURL: URL?
init(appStoreReceiptURL: URL? = Bundle.main.appStoreReceiptURL) {
self.appStoreReceiptURL = appStoreReceiptURL
}
var appStoreReceiptData: Data? {
guard let receiptDataURL = appStoreReceiptURL,
let data = try? Data(contentsOf: receiptDataURL) else {
return nil
}
return data
}
private var receiptRefreshRequest: InAppReceiptRefreshRequest?
/**
* Verify application receipt.
* - Parameter validator: Validator to check the encrypted receipt and return the receipt in readable format
* - Parameter forceRefresh: If true, refreshes the receipt even if one already exists.
* - Parameter refresh: closure to perform receipt refresh (this is made explicit for testability)
* - Parameter completion: handler for result
*/
@discardableResult
public func verifyReceipt(using validator: ReceiptValidator,
forceRefresh: Bool,
refresh: InAppReceiptRefreshRequest.ReceiptRefresh = InAppReceiptRefreshRequest.refresh,
completion: @escaping (VerifyReceiptResult) -> Void) -> InAppRequest? {
return fetchReceipt(forceRefresh: forceRefresh, refresh: refresh) { result in
switch result {
case .success(let receiptData):
self.verify(receiptData: receiptData, using: validator, completion: completion)
case .error(let error):
completion(.error(error: error))
}
}
}
/**
* Fetch application receipt. This method does two things:
* * If the receipt is missing, refresh it
* * If the receipt is available or is refreshed, validate it
* - Parameter forceRefresh: If true, refreshes the receipt even if one already exists.
* - Parameter refresh: closure to perform receipt refresh (this is made explicit for testability)
* - Parameter completion: handler for result
*/
@discardableResult
public func fetchReceipt(forceRefresh: Bool,
refresh: InAppReceiptRefreshRequest.ReceiptRefresh = InAppReceiptRefreshRequest.refresh,
completion: @escaping (FetchReceiptResult) -> Void) -> InAppRequest? {
if let receiptData = appStoreReceiptData, forceRefresh == false {
completion(.success(receiptData: receiptData))
return nil
} else {
receiptRefreshRequest = refresh(nil) { result in
self.receiptRefreshRequest = nil
switch result {
case .success:
if let receiptData = self.appStoreReceiptData {
completion(.success(receiptData: receiptData))
} else {
completion(.error(error: .noReceiptData))
}
case .error(let e):
completion(.error(error: .networkError(error: e)))
}
}
return receiptRefreshRequest
}
}
/**
* - Parameter receiptData: encrypted receipt data
* - Parameter validator: Validator to check the encrypted receipt and return the receipt in readable format
* - Parameter completion: handler for result
*/
private func verify(receiptData: Data, using validator: ReceiptValidator, completion: @escaping (VerifyReceiptResult) -> Void) {
validator.validate(receiptData: receiptData) { result in
DispatchQueue.main.async {
completion(result)
}
}
}
}
//
// OS.swift
// SwiftyStoreKit
//
// Copyright (c) 2020 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import StoreKit
// MARK: - Missing SKMutablePayment init with product on macOS
#if os(OSX)
extension SKMutablePayment {
convenience init(product: SKProduct) {
self.init()
self.productIdentifier = product.productIdentifier
}
}
#endif
// MARK: - Missing SKError on watchOS
#if os(watchOS) && swift(<5.3)
public struct SKError: Error {
public typealias Code = SKErrorCode
let _nsError: NSError
init(_nsError: NSError) {
self._nsError = _nsError
}
var code: Code {
return Code(rawValue: _nsError.code) ?? .unknown
}
static var unknown: Code = .unknown
static var paymentInvalid: Code = .paymentInvalid
}
#endif
//
// PaymentsController.swift
// SwiftyStoreKit
//
// Copyright (c) 2017 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import StoreKit
struct Payment: Hashable {
let product: SKProduct
let paymentDiscount: PaymentDiscount?
let quantity: Int
let atomically: Bool
let applicationUsername: String
let simulatesAskToBuyInSandbox: Bool
let callback: (TransactionResult) -> Void
func hash(into hasher: inout Hasher) {
hasher.combine(product)
hasher.combine(quantity)
hasher.combine(atomically)
hasher.combine(applicationUsername)
hasher.combine(simulatesAskToBuyInSandbox)
}
static func == (lhs: Payment, rhs: Payment) -> Bool {
return lhs.product.productIdentifier == rhs.product.productIdentifier
}
}
public struct PaymentDiscount {
let discount: AnyObject?
@available(iOS 12.2, tvOS 12.2, OSX 10.14.4, watchOS 6.2, macCatalyst 13.0, *)
public init(discount: SKPaymentDiscount) {
self.discount = discount
}
private init() {
self.discount = nil
}
}
class PaymentsController: TransactionController {
private var payments: [Payment] = []
private func findPaymentIndex(withProductIdentifier identifier: String) -> Int? {
for payment in payments where payment.product.productIdentifier == identifier {
return payments.firstIndex(of: payment)
}
return nil
}
func hasPayment(_ payment: Payment) -> Bool {
return findPaymentIndex(withProductIdentifier: payment.product.productIdentifier) != nil
}
func append(_ payment: Payment) {
payments.append(payment)
}
func processTransaction(_ transaction: SKPaymentTransaction, on paymentQueue: PaymentQueue) -> Bool {
let transactionProductIdentifier = transaction.payment.productIdentifier
guard let paymentIndex = findPaymentIndex(withProductIdentifier: transactionProductIdentifier) else {
return false
}
let payment = payments[paymentIndex]
let transactionState = transaction.transactionState
if transactionState == .purchased {
let purchase = PurchaseDetails(productId: transactionProductIdentifier, quantity: transaction.payment.quantity, product: payment.product, transaction: transaction, originalTransaction: transaction.original, needsFinishTransaction: !payment.atomically)
payment.callback(.purchased(purchase: purchase))
if payment.atomically {
paymentQueue.finishTransaction(transaction)
}
payments.remove(at: paymentIndex)
return true
}
if transactionState == .restored {
print("Unexpected restored transaction for payment \(transactionProductIdentifier)")
let purchase = PurchaseDetails(productId: transactionProductIdentifier, quantity: transaction.payment.quantity, product: payment.product, transaction: transaction, originalTransaction: transaction.original, needsFinishTransaction: !payment.atomically)
payment.callback(.purchased(purchase: purchase))
if payment.atomically {
paymentQueue.finishTransaction(transaction)
}
payments.remove(at: paymentIndex)
return true
}
if transactionState == .failed {
payment.callback(.failed(error: transactionError(for: transaction.error as NSError?)))
paymentQueue.finishTransaction(transaction)
payments.remove(at: paymentIndex)
return true
}
return false
}
func transactionError(for error: NSError?) -> SKError {
let message = "Unknown error"
let altError = NSError(domain: SKErrorDomain, code: SKError.unknown.rawValue, userInfo: [ NSLocalizedDescriptionKey: message ])
let nsError = error ?? altError
return SKError(_nsError: nsError)
}
func processTransactions(_ transactions: [SKPaymentTransaction], on paymentQueue: PaymentQueue) -> [SKPaymentTransaction] {
return transactions.filter { !processTransaction($0, on: paymentQueue) }
}
}
//
// ProductsInfoController.swift
// SwiftyStoreKit
//
// Copyright (c) 2015 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import StoreKit
protocol InAppProductRequestBuilder: class {
func request(productIds: Set<String>, callback: @escaping InAppProductRequestCallback) -> InAppProductRequest
}
class InAppProductQueryRequestBuilder: InAppProductRequestBuilder {
func request(productIds: Set<String>, callback: @escaping InAppProductRequestCallback) -> InAppProductRequest {
return InAppProductQueryRequest(productIds: productIds, callback: callback)
}
}
class ProductsInfoController: NSObject {
struct InAppProductQuery {
let request: InAppProductRequest
var completionHandlers: [InAppProductRequestCallback]
}
let inAppProductRequestBuilder: InAppProductRequestBuilder
init(inAppProductRequestBuilder: InAppProductRequestBuilder = InAppProductQueryRequestBuilder()) {
self.inAppProductRequestBuilder = inAppProductRequestBuilder
}
// As we can have multiple inflight requests, we store them in a dictionary by product ids
private var inflightRequests: [Set<String>: InAppProductQuery] = [:]
@discardableResult
func retrieveProductsInfo(_ productIds: Set<String>, completion: @escaping (RetrieveResults) -> Void) -> InAppProductRequest {
if inflightRequests[productIds] == nil {
let request = inAppProductRequestBuilder.request(productIds: productIds) { results in
if let query = self.inflightRequests[productIds] {
for completion in query.completionHandlers {
completion(results)
}
self.inflightRequests[productIds] = nil
} else {
// should not get here, but if it does it seems reasonable to call the outer completion block
completion(results)
}
}
inflightRequests[productIds] = InAppProductQuery(request: request, completionHandlers: [completion])
request.start()
return request
} else {
inflightRequests[productIds]!.completionHandlers.append(completion)
return inflightRequests[productIds]!.request
}
}
}
//
// RestorePurchasesController.swift
// SwiftyStoreKit
//
// Copyright (c) 2017 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import StoreKit
struct RestorePurchases {
let atomically: Bool
let applicationUsername: String?
let callback: ([TransactionResult]) -> Void
init(atomically: Bool, applicationUsername: String? = nil, callback: @escaping ([TransactionResult]) -> Void) {
self.atomically = atomically
self.applicationUsername = applicationUsername
self.callback = callback
}
}
class RestorePurchasesController: TransactionController {
public var restorePurchases: RestorePurchases?
private var restoredPurchases: [TransactionResult] = []
func processTransaction(_ transaction: SKPaymentTransaction, atomically: Bool, on paymentQueue: PaymentQueue) -> Purchase? {
let transactionState = transaction.transactionState
if transactionState == .restored {
let transactionProductIdentifier = transaction.payment.productIdentifier
let purchase = Purchase(productId: transactionProductIdentifier, quantity: transaction.payment.quantity, transaction: transaction, originalTransaction: transaction.original, needsFinishTransaction: !atomically)
if atomically {
paymentQueue.finishTransaction(transaction)
}
return purchase
}
return nil
}
func processTransactions(_ transactions: [SKPaymentTransaction], on paymentQueue: PaymentQueue) -> [SKPaymentTransaction] {
guard let restorePurchases = restorePurchases else {
return transactions
}
var unhandledTransactions: [SKPaymentTransaction] = []
for transaction in transactions {
if let restoredPurchase = processTransaction(transaction, atomically: restorePurchases.atomically, on: paymentQueue) {
restoredPurchases.append(.restored(purchase: restoredPurchase))
} else {
unhandledTransactions.append(transaction)
}
}
return unhandledTransactions
}
func restoreCompletedTransactionsFailed(withError error: Error) {
guard let restorePurchases = restorePurchases else {
print("Callback already called. Returning")
return
}
restoredPurchases.append(.failed(error: SKError(_nsError: error as NSError)))
restorePurchases.callback(restoredPurchases)
// Reset state after error received
restoredPurchases = []
self.restorePurchases = nil
}
func restoreCompletedTransactionsFinished() {
guard let restorePurchases = restorePurchases else {
print("Callback already called. Returning")
return
}
restorePurchases.callback(restoredPurchases)
// Reset state after error transactions finished
restoredPurchases = []
self.restorePurchases = nil
}
}
//
// SKProduct+LocalizedPrice.swift
// SwiftyStoreKit
//
// Created by Andrea Bizzotto on 19/10/2016.
// Copyright (c) 2015 Andrea Bizzotto (bizz84@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import StoreKit
public extension SKProduct {
var localizedPrice: String? {
return priceFormatter(locale: priceLocale).string(from: price)
}
private func priceFormatter(locale: Locale) -> NumberFormatter {
let formatter = NumberFormatter()
formatter.locale = locale
formatter.numberStyle = .currency
return formatter
}
@available(iOSApplicationExtension 11.2, iOS 11.2, OSX 10.13.2, tvOS 11.2, watchOS 6.2, macCatalyst 13.0, *)
var localizedSubscriptionPeriod: String {
guard let subscriptionPeriod = self.subscriptionPeriod else { return "" }
let dateComponents: DateComponents
switch subscriptionPeriod.unit {
case .day: dateComponents = DateComponents(day: subscriptionPeriod.numberOfUnits)
case .week: dateComponents = DateComponents(weekOfMonth: subscriptionPeriod.numberOfUnits)
case .month: dateComponents = DateComponents(month: subscriptionPeriod.numberOfUnits)
case .year: dateComponents = DateComponents(year: subscriptionPeriod.numberOfUnits)
@unknown default:
print("WARNING: SwiftyStoreKit localizedSubscriptionPeriod does not handle all SKProduct.PeriodUnit cases.")
// Default to month units in the unlikely event a different unit type is added to a future OS version
dateComponents = DateComponents(month: subscriptionPeriod.numberOfUnits)
}
return DateComponentsFormatter.localizedString(from: dateComponents, unitsStyle: .short) ?? ""
}
}
//
// SKProductDiscount+LocalizedPrice.swift
// SwiftyStoreKit
//
// Created by Sam Spencer on 5/29/20.
// Copyright © 2020 Sam Spencer. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import StoreKit
@available(iOSApplicationExtension 11.2, iOS 11.2, OSX 10.13.2, tvOS 11.2, watchOS 4.2, macCatalyst 13.0, *)
public extension SKProductDiscount {
/// The formatted discount price of the product using the local currency.
var localizedPrice: String? {
return priceFormatter(locale: priceLocale).string(from: price)
}
private func priceFormatter(locale: Locale) -> NumberFormatter {
let formatter = NumberFormatter()
formatter.locale = locale
formatter.numberStyle = .currency
return formatter
}
/// The formatted, localized period / date for the product discount.
/// - note: The subscription period for the discount is independent of the product's regular subscription period, and does not have to match in units or duration.
var localizedSubscriptionPeriod: String {
let dateComponents: DateComponents
switch subscriptionPeriod.unit {
case .day: dateComponents = DateComponents(day: subscriptionPeriod.numberOfUnits)
case .week: dateComponents = DateComponents(weekOfMonth: subscriptionPeriod.numberOfUnits)
case .month: dateComponents = DateComponents(month: subscriptionPeriod.numberOfUnits)
case .year: dateComponents = DateComponents(year: subscriptionPeriod.numberOfUnits)
@unknown default:
print("WARNING: SwiftyStoreKit localizedSubscriptionPeriod does not handle all SKProduct.PeriodUnit cases.")
// Default to month units in the unlikely event a different unit type is added to a future OS version
dateComponents = DateComponents(month: subscriptionPeriod.numberOfUnits)
}
return DateComponentsFormatter.localizedString(from: dateComponents, unitsStyle: .full) ?? ""
}
}
...@@ -2779,6 +2779,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ...@@ -2779,6 +2779,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
## SwiftyStoreKit
Copyright (c) 2015-2016 Andrea Bizzotto bizz84@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## libwebp ## libwebp
Copyright (c) 2010, Google Inc. All rights reserved. Copyright (c) 2010, Google Inc. All rights reserved.
......
...@@ -3008,6 +3008,23 @@ THE SOFTWARE. ...@@ -3008,6 +3008,23 @@ THE SOFTWARE.
</dict> </dict>
<dict> <dict>
<key>FooterText</key> <key>FooterText</key>
<string>Copyright (c) 2015-2016 Andrea Bizzotto bizz84@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>SwiftyStoreKit</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2010, Google Inc. All rights reserved. <string>Copyright (c) 2010, Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
......
...@@ -27,6 +27,7 @@ ${BUILT_PRODUCTS_DIR}/Nuke-WebP-Plugin/NukeWebPPlugin.framework ...@@ -27,6 +27,7 @@ ${BUILT_PRODUCTS_DIR}/Nuke-WebP-Plugin/NukeWebPPlugin.framework
${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework ${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework
${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework ${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework
${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework ${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework
${BUILT_PRODUCTS_DIR}/SwiftyStoreKit/SwiftyStoreKit.framework
${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework ${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework
${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework ${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework
${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework ${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework
......
...@@ -26,6 +26,7 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NukeWebPPlugin.framework ...@@ -26,6 +26,7 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NukeWebPPlugin.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PKHUD.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PKHUD.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Swarm.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Swarm.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyStoreKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MoPubSDK.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MoPubSDK.framework
......
...@@ -27,6 +27,7 @@ ${BUILT_PRODUCTS_DIR}/Nuke-WebP-Plugin/NukeWebPPlugin.framework ...@@ -27,6 +27,7 @@ ${BUILT_PRODUCTS_DIR}/Nuke-WebP-Plugin/NukeWebPPlugin.framework
${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework ${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework
${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework ${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework
${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework ${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework
${BUILT_PRODUCTS_DIR}/SwiftyStoreKit/SwiftyStoreKit.framework
${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework ${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework
${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework ${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework
${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework ${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework
......
...@@ -26,6 +26,7 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NukeWebPPlugin.framework ...@@ -26,6 +26,7 @@ ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NukeWebPPlugin.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PKHUD.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PKHUD.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Swarm.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Swarm.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyStoreKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MoPubSDK.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MoPubSDK.framework
......
...@@ -203,6 +203,7 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then ...@@ -203,6 +203,7 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework" install_framework "${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework" install_framework "${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SwiftyStoreKit/SwiftyStoreKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework" install_framework "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework"
install_framework "${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework" install_framework "${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework"
install_framework "${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework" install_framework "${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework"
...@@ -239,6 +240,7 @@ if [[ "$CONFIGURATION" == "Release" ]]; then ...@@ -239,6 +240,7 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework" install_framework "${BUILT_PRODUCTS_DIR}/PKHUD/PKHUD.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework" install_framework "${BUILT_PRODUCTS_DIR}/Swarm/Swarm.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SwiftyStoreKit/SwiftyStoreKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework" install_framework "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework"
install_framework "${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework" install_framework "${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework"
install_framework "${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework" install_framework "${BUILT_PRODUCTS_DIR}/mopub-ios-sdk/MoPubSDK.framework"
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.16.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_SwiftyStoreKit : NSObject
@end
@implementation PodsDummy_SwiftyStoreKit
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double SwiftyStoreKitVersionNumber;
FOUNDATION_EXPORT const unsigned char SwiftyStoreKitVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyStoreKit
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyStoreKit
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module SwiftyStoreKit {
umbrella header "SwiftyStoreKit-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyStoreKit
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SwiftyStoreKit
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment