Category: App

  • Generic in Swift

    Generic in Swift

    Generic in Swift

    In the Swift programming language, the term “generic” refers to a type or function that can work with any type, rather than being tied to a specific type. This allows for greater flexibility and code reuse. For example, a generic function can be written to sort an array of any type, rather than having to write a separate sorting function for each type of array. Using generics can make your code more concise and easy to read, and can help you avoid code duplication.

    Here is an example of a generic function in Swift that sorts an array of elements:

    func sortArray<T: Comparable>(array: [T]) -> [T] {
        let sortedArray = array.sorted()
        return sortedArray
    }
    

    In this example, the sortArray function is a generic function that can sort an array of any type that conforms to the Comparable protocol. This means that the function can sort arrays of integers, strings, or any other type that can be compared using the < and > operators.

    Here is how you could use this function to sort an array of integers:

    let numbers = [10, -1, 3, 9, 2]
    let sortedNumbers = sortArray(array: numbers)
    

    The sortedNumbers constant would be equal to [-1, 2, 3, 9, 10] after this code is executed.

    Spread the love
  • Associated Type in Swift

    Associated Type in Swift

    Associated Type in Swift

    In Swift, an associated type is a placeholder name for a type that is used as part of the protocol. The actual type to be used for the associated type is not specified until the protocol is adopted. Associated types are often used to specify the type of values that a protocol can work with, without specifying the exact type of those values.

    Here’s an example of a protocol that uses an associated type:

    protocol Container {
        associatedtype Item
        var items: [Item] { get set }
        mutating func append(_ item: Item)
        var count: Int { get }
        subscript(i: Int) -> Item { get }
    }
    

    In this example, the Container protocol defines an associated type called Item, which represents the type of the items that the container can hold. The protocol also defines several methods and properties that operate on the items array, but the type of the items in the array is not specified. It is up to the type that adopts the Container protocol to specify the actual type to be used for the Item associated type.

    Here’s how the Container protocol might be adopted by a concrete type:

    struct IntStack: Container {
        // specify the actual type to be used for the Item associated type
        typealias Item = Int
    
        var items: [Int] = []
    
        mutating func append(_ item: Int) {
            items.append(item)
        }
    
        var count: Int {
            return items.count
        }
    
        subscript(i: Int) -> Int {
            return items[i]
        }
    }
    

    In this example, the IntStack type adopts the Container protocol and specifies that the Item associated type should be replaced with the Int type. This allows the IntStack type to use the Int type for the items in its items array, and to implement the methods and properties required by the Container protocol using the Int type.

    Spread the love
  • Decode Apple Receipt

    Decode Apple Receipt

    Decode Apple Receipt

    Verify with the server-side click here

    /**
     * ***********************************************************************
     *  SMINRANA CONFIDENTIAL
     *   __________________
     *
     * Copyright 2020  SMINRANA
     * All Rights Reserved.
     *
     * NOTICE:  All information contained herein is, and remains
     * the property of SMINRANA and its suppliers,
     * if any.  The intellectual and technical concepts contained
     * herein are proprietary to SMINRANA
     * and its suppliers and may be covered by U.S. and Foreign Patents,
     * patents in process, and are protected by trade secret or copyright law.
     * Dissemination of this information or reproduction of this material
     * is strictly forbidden unless prior written permission is obtained
     * from SMINRANA.
     * www.sminrana.com
     *
     */
    
    import SwiftUI
    import StoreKit
    import Combine
    
    class AppStorageManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    
        @AppStorage("username") var username: String = ""
        @AppStorage("password") var password: String = ""
        
        override init() {
            super.init()
            
            SKPaymentQueue.default().add(self)
        }
        
        @Published var products = [SKProduct]()
        
        func getProdcut(indetifiers: [String]) {
            print("Start requesting products ...")
            let request = SKProductsRequest(productIdentifiers: Set(indetifiers))
            request.delegate = self
            request.start()
        }
        
    
        // SKProductsRequestDelegate
    
        func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
            print("Did receive response \(response.products)")
                    
            if !response.products.isEmpty {
                for fetchedProduct in response.products {
                    DispatchQueue.main.async {
                        self.products.append(fetchedProduct)
                    }
                }
            }
            
            for invalidIdentifier in response.invalidProductIdentifiers {
                print("Invalid identifiers found: \(invalidIdentifier)")
            }
        }
        
        func request(_ request: SKRequest, didFailWithError error: Error) {
            print("Request did fail: \(error)")
        }
        
    
        // Transaction
        
        @Published var transactionState: SKPaymentTransactionState?
        
        func purchaseProduct(product: SKProduct) {
            if SKPaymentQueue.canMakePayments() {
                let payment = SKPayment(product: product)
                SKPaymentQueue.default().add(payment)
            } else {
                print("User can't make payment.")
            }
        }
    
        func restorePurchase() {
            SKPaymentQueue.default().restoreCompletedTransactions()
        }
        
        struct PaymentReceiptResponseModel: Codable {
            var status: Int
            var email: String?
            var password: String?
            var message: String?
        }
        
        // SKPaymentTransactionObserver
    
    
        // This gets called when transaction purchased by user
        func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
            for transaction in transactions {
                switch transaction.transactionState {
                case .purchasing:
                    self.transactionState = .purchasing
                case .purchased:
                    print("===============Purchased================")
                    UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
    
                    if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
                        FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
    
                        do {
                            let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
                            let receiptString = receiptData.base64EncodedString(options: [])
                            
                           // Send receiptString to server for further verification
                        }
                        catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
                    }
    
                case .restored:
                    UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
    
                    queue.finishTransaction(transaction)
                    print("==================RESTORED State=============")
                    self.transactionState = .restored
                case .failed, .deferred:
                    print("Payment Queue Error: \(String(describing: transaction.error))")
                    queue.finishTransaction(transaction)
                    self.transactionState = .failed
                default:
                    print(">>>> something else")
                    queue.finishTransaction(transaction)
                }
            }
        }
        
        // This gets called when a transaction restored by user
        func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
            print("===============Restored================")
            if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
                FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
    
                do {
                    let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
                    let receiptString = receiptData.base64EncodedString(options: [])
                    
                    // Send receiptString to server for further verification
                }
                catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
            }
        }
        
      
    }
    
    Spread the love