Advertisement
lcolli98

Untitled

Feb 24th, 2020
528
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 11.72 KB | None | 0 0
  1. //
  2. //  TopicsViewController.swift
  3. //  AeroBuddy
  4. //
  5. //  Created by Luke Collister on 26/09/2019.
  6. //  Copyright © 2019 Luke Collister. All rights reserved.
  7. //
  8.  
  9. /* This class should display the relevant topics only, based on the selection of subject from the previous TBVC */
  10.  
  11. import UIKit
  12. import StoreKit
  13.  
  14. class TopicsViewController: UITableViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver, TopicCellDelegate {
  15.  
  16.     // MARK: - Declarations
  17.     var subjectVar: Subject?
  18.     var productsSet = Set<String>()
  19.     var displayTopics = [Topic]()
  20.     var allTopics = [Topic]()
  21.     var ownedTopics = [Topic]()
  22.     var mytopic: Topic!
  23.     let workingDG = DispatchGroup()
  24.    
  25.    
  26.    
  27.     // MARK: - Buy Button Methods
  28.     func cellButtonTapped(cell: TopicCell) {
  29.         // Trigger an alert to buy the subject
  30.         let alert = UIAlertController(title: "Purchase Topic?", message: "You do not own this topic. Do you wish to purchase it?", preferredStyle: .alert)
  31.  
  32.         // Add the topic product identifier to the set
  33.         let buttonPosition: CGPoint = cell.convert(CGPoint.zero, to: self.tableView)
  34.         let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
  35.         productsSet.insert(displayTopics[indexPath!.row].product_identifier!)
  36.         print("PRODUCTS SET: ", productsSet)
  37.  
  38.         // Yes option
  39.         alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { action in
  40.            // IAP Code Here
  41.            if (SKPaymentQueue.canMakePayments()) {
  42.                let productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: self.productsSet)
  43.                productsRequest.delegate = self
  44.                productsRequest.start()
  45.                print("Fetching Products")
  46.            } else {
  47.                print("Can't make purchases")
  48.            }
  49.         }))
  50.         // No option
  51.         alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { action in
  52.             self.productsSet.removeAll()
  53.         }))
  54.  
  55.         self.present(alert, animated: true)
  56.         print("The topic with product identifier ", productsSet, " was selected!")
  57.     }
  58.    
  59.    
  60.    
  61.     // MARK: - IAP Methods
  62.     var product_identifier: String?
  63.    
  64.     func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
  65.         let count: Int = response.products.count
  66.         if (count > 0) {
  67.             let validProduct: SKProduct = response.products[0] as SKProduct
  68.             print(validProduct.localizedTitle)
  69.             print(validProduct.localizedDescription)
  70.             print(validProduct.price)
  71.             buyProduct(product: validProduct)
  72.         } else {
  73.             print("nothing")
  74.         }
  75.     }
  76.    
  77.     func buyProduct(product: SKProduct) {
  78.         print("Sending the Payment Request to Apple")
  79.         let payment = SKPayment(product: product)
  80.         SKPaymentQueue.default().add(payment)
  81.     }
  82.  
  83.     func request(_ request: SKRequest, didFailWithError error: Error) {
  84.         print("Error Fetching product information")
  85.     }
  86.  
  87.     func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
  88.         print("Received Payment Transaction Response from Apple")
  89.        
  90.         print("Transactions: ", transactions)
  91.  
  92.         for transaction: AnyObject in transactions {
  93.             if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction {
  94.                 switch trans.transactionState {
  95.                 case .purchased:
  96.                     print("Product Purchased")
  97.                     SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
  98.                     // Handle the purchase
  99.                     UserDefaults.standard.set(true , forKey: "purchased")
  100.                     // Get the receipt if it's available
  101.                     if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
  102.  
  103.                         do {
  104.                             let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
  105.                             print("RECEIPT DATA: ", receiptData)
  106.  
  107.                             let receiptString = receiptData.base64EncodedString(options: [])
  108.                             print("RECEIPT STRING: ", receiptString)
  109.  
  110.                             // Read receiptData
  111.                             // Create POST request
  112.                             let url = URL(string: "http://fe01.kilosierracharlie.me/verifypayment")!
  113.                             var request = URLRequest(url: url)
  114.                             request.httpMethod = "POST"
  115.                             request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
  116.                             let parameters: [String: Any] = [
  117.                                 "receipt": receiptString
  118.                             ]
  119.                             request.httpBody = parameters.percentEncoded()
  120.  
  121.                             // Send the data
  122.                             print("Before URLSession")
  123.                             let task = URLSession.shared.dataTask(with: request) { data, response, error in
  124.                                 guard let data = data, error == nil else {
  125.                                     print(error?.localizedDescription ?? "No data")
  126.                                     print("No data could be sent to the server. Please contact us.")
  127.                                     return
  128.                                 }
  129.                                 let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
  130.                                 if let responseJSON = responseJSON as? [String: Any] {
  131.                                     print(responseJSON)
  132.                                     //TO DO: Refresh if error false, else throw error
  133.                                 }
  134.                                 print("DATA: ", data)
  135.                             }
  136.                             print("Here")
  137.                             task.resume()
  138.                         }
  139.                         catch {
  140.                             print("Couldn't read receipt data with error: " + error.localizedDescription)
  141.                         }
  142.                     }
  143.                     break;
  144.                    
  145.                 case .failed:
  146.                     print("Purchased Failed")
  147.                     SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
  148.                     break;
  149.  
  150.                 case .restored:
  151.                     print("Already Purchased")
  152.                     SKPaymentQueue.default().restoreCompletedTransactions()
  153.  
  154.                     // Handle the purchase
  155.                     UserDefaults.standard.set(true , forKey: "purchased")
  156.                     //adView.hidden = true
  157.                     break;
  158.                 default:
  159.                     print("In default")
  160.                     break;
  161.                 }
  162.             }
  163.         }
  164.     }
  165.    
  166.    
  167.    
  168.     // MARK: - UITableViewMethods
  169.     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  170.        return self.displayTopics.count
  171.     }
  172.  
  173.  
  174.     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  175.        let cell = tableView.dequeueReusableCell(withIdentifier: "TopicCell", for: indexPath) as! TopicCell
  176.        cell.topic = displayTopics[indexPath.row]
  177.        if (cell.topic?.owned == false) {
  178.            cell.backgroundColor = UIColor(red: 90/255, green: 90/255, blue: 90/255, alpha: 1)
  179.        } else {
  180.            //cell.backgroundColor = default
  181.        }
  182.        cell.delegate = self
  183.        return cell
  184.     }
  185.  
  186.    
  187.     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  188.         if segue.identifier == "topicToContentSegue" {
  189.             if let destinationVC = segue.destination as? ContentViewController {
  190.                 destinationVC.topic = mytopic
  191.                 destinationVC.setup()
  192.             }
  193.         }
  194.     }
  195.  
  196.    
  197.     // When the cell is pressed
  198.     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  199.         // Determine which Topic was selected
  200.         let selectedTopic = displayTopics[indexPath.row]
  201.         mytopic = selectedTopic
  202.         print("Selected subject: ", displayTopics[indexPath.row])
  203.  
  204.         // If owned, load the topic
  205.         if (mytopic.owned == true) {
  206.             print("My topic is owned, go to segue")
  207.             performSegue(withIdentifier: "topicToContentSegue", sender: self)
  208.         } else {
  209.             print("My topic is not owned, show alert")
  210.             let alert = UIAlertController(title: "Locked Content", message: "You must purchase this topic to be able to view its content.", preferredStyle: .alert)
  211.             alert.addAction(UIAlertAction(title: "Return", style: .cancel, handler: { action in
  212.  
  213.             }))
  214.             self.present(alert, animated: true)
  215.         }
  216.     }
  217.  
  218.    
  219.    
  220.    
  221.     // MARK: - Default Methods
  222.     override func viewDidLoad() {
  223.         super.viewDidLoad()
  224.        
  225.         // Clear all arrays
  226.         displayTopics.removeAll()
  227.         allTopics.removeAll()
  228.         ownedTopics.removeAll()
  229.        
  230.         // Set the title based to the selected Course
  231.         self.title = subjectVar?.title
  232.        
  233.         // Get owned Topics
  234.         DispatchQueue.global(qos: .background).async {
  235.             self.workingDG.enter()
  236.             self.getAllTopics(endpoint: "topics")
  237.             self.workingDG.enter()
  238.             self.getAllTopics(endpoint: "topics/my")
  239.            
  240.             self.workingDG.notify(queue: .main) {
  241.                 for i in 0 ..< self.ownedTopics.count {
  242.                     self.ownedTopics[i].owned = true
  243.                 }
  244.  
  245.                 var idArray = [Int]()
  246.                 for topic in self.ownedTopics {
  247.                     idArray.append(topic.id)
  248.                 }
  249.                 for var topic in self.allTopics {
  250.                     topic.owned = idArray.contains(topic.id)
  251.                     // Display topics only in the selected subject
  252.                     if var topics = self.subjectVar!.topics {
  253.                         for top in topics {
  254.                             self.displayTopics.append(top)
  255.                         }
  256.                     }
  257.                 }
  258.                 self.tableView.reloadData()
  259.             }
  260.         }
  261.         SKPaymentQueue.default().add(self)
  262.     }
  263.    
  264.    
  265.    
  266.     // MARK: - JSON Methods
  267.     func getAllTopics(endpoint: String) {
  268.        let url = URL(string: "\(ServHandler.connectProtocol)://\(ServHandler.baseURL)/\(endpoint)")
  269.        let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in
  270.            guard error == nil else {
  271.                print("Error!")
  272.                return
  273.            }
  274.            guard let content = data else {
  275.                print("There is no data!")
  276.                return
  277.            }
  278.  
  279.            let decoder = JSONDecoder()
  280.            do {
  281.                for var topic in try decoder.decode([Topic].self, from: content) {
  282.                    if (endpoint == "topics") {
  283.                        topic.product_identifier = "com.aerobuddy.topic.\(topic.id)"
  284.                        self.allTopics.append(topic)
  285.                    }
  286.                    else {
  287.                        self.ownedTopics.append(topic)
  288.                    }
  289.                }
  290.                self.workingDG.leave()
  291.                return
  292.            }
  293.            catch {
  294.                print(error.localizedDescription)
  295.                print(error)
  296.                return
  297.            }
  298.        }
  299.        task.resume()
  300.     }
  301. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement