changeset 154:8afba86ab8dd

Refactor code
author Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
date Wed, 25 Aug 2021 10:43:12 +0100
parents 2590ee472aa9
children 681f2cbe8c7f
files Simoleon/Functions/NetworkRequest.swift Simoleon/Functions/Read.swift Simoleon/Functions/ReadConfig.swift Simoleon/Functions/SimpleSuccess.swift Simoleon/Helpers/ListModifier.swift Simoleon/Jobs/CurrenciesController.swift Simoleon/Jobs/FileController.swift Simoleon/Jobs/HapticsController.swift Simoleon/Jobs/NetworkController.swift Simoleon/Models/CurrencyDetailsModel.swift Simoleon/Models/CurrencyQuoteModel.swift Simoleon/Settings.swift Simoleon/SimoleonApp.swift SimoleonTests/SimoleonTests.swift
diffstat 14 files changed, 195 insertions(+), 126 deletions(-) [+]
line wrap: on
line diff
--- a/Simoleon/Functions/NetworkRequest.swift	Mon Aug 23 17:14:47 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-//
-//  Request.swift
-//  Simoleon
-//
-//  Created by Dennis Concepción Martín on 20/07/2021.
-//
-
-import SwiftUI
-
-func networkRequest<T: Decodable>(url: String, model: T.Type, completion: @escaping (_ result: T) -> Void) {
-    
-    // We take some model data T.Type
-    guard let url = URL(string: url) else {
-        print("Invalid URL")
-        return
-    }
-    
-    let request = URLRequest(url: url)
-    URLSession.shared.dataTask(with: request) { data, response, error in
-        if let data = data {
-            do {
-                // Decode response with the model passed
-                let decodedResponse = try JSONDecoder().decode(model, from: data)
-                DispatchQueue.main.async {
-                    completion(decodedResponse)
-                }
-                return
-            } catch {
-                // Return error regarding the escaping code
-                print(error)
-            }
-        }
-        // Error with the request
-        print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
-    }
-    .resume()
-}
--- a/Simoleon/Functions/Read.swift	Mon Aug 23 17:14:47 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-//
-//  ParseJson.swift
-//  Simoleon
-//
-//  Created by Dennis Concepción Martín on 11/07/2021.
-//
-
-import Foundation
-
-
-// Read JSON File
-func read<T: Decodable>(json filename: String) throws -> T {
-    let data: Data
-    
-    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
-    else {
-        throw JsonErrors.fileMissing
-    }
-    
-    do {
-        data = try Data(contentsOf: file)
-    } catch {
-        throw JsonErrors.loadFailed(cause: error.localizedDescription)
-    }
-    
-    do {
-        let decoder = JSONDecoder()
-        return try decoder.decode(T.self, from: data)
-    } catch {
-        throw JsonErrors.parseFailed(cause: error.localizedDescription)
-    }
-}
--- a/Simoleon/Functions/ReadConfig.swift	Mon Aug 23 17:14:47 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-//
-//  ReadConfig.swift
-//  Simoleon
-//
-//  Created by Dennis Concepción Martín on 20/07/2021.
-//
-
-import SwiftUI
-
-func readConfig(_ key: String) -> String? {
-    return (Bundle.main.infoDictionary?[key] as? String)?
-        .replacingOccurrences(of: "\\", with: "")
-}
--- a/Simoleon/Functions/SimpleSuccess.swift	Mon Aug 23 17:14:47 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-//
-//  SimpleSuccess.swift
-//  Simoleon
-//
-//  Created by Dennis Concepción Martín on 20/07/2021.
-//
-
-import SwiftUI
-
-// Haptics
-func simpleSuccess() {
-    let generator = UINotificationFeedbackGenerator()
-    generator.notificationOccurred(.success)
-}
--- a/Simoleon/Helpers/ListModifier.swift	Mon Aug 23 17:14:47 2021 +0100
+++ b/Simoleon/Helpers/ListModifier.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -12,10 +12,11 @@
             content
                 .id(UUID())
                 .listStyle(PlainListStyle())
-                .gesture(DragGesture()
+                .gesture(
+                    DragGesture()
                             .onChanged({ _ in
                                 UIApplication.shared.dismissKeyboard()
-                            })
+                        })
                 )
         }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Jobs/CurrenciesController.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -0,0 +1,54 @@
+//
+//  GetCompatibleCurrencies.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 24/8/21.
+//
+
+import Foundation
+
+class CurrenciesController {
+    let fileController = FileController()
+    
+    func get(currenciesCompatibleWith currencySymbol: String?, currencies: Bool?) -> [String] {
+        // If currencies not false -> return all currencies
+        guard currencies == false else { return allCurrencies() }
+        
+        // This block won't be executed if the previous check fails
+        return compatibleCurrencies(with: currencySymbol!)
+    }
+    
+    /*
+     * Input all currencies supported by vendor
+     * Return individual currency symbols without duplicates
+     */
+    private func allCurrencies() -> [String] {
+        let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json")
+        
+        var currencies = Set<String>()
+        for currencyPairSupported in currencyPairsSupported {
+            let currency = currencyPairSupported.components(separatedBy: "/")[0]
+            currencies.insert(currency)
+        }
+        
+        return Array(currencies)
+    }
+    
+    /*
+     * Given the first symbol of the currency pair
+     * Return all compatible symbols
+     */
+    private func compatibleCurrencies(with currencySymbol: String) -> [String] {
+        let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json")
+        
+        var currencies = [String]()
+        for currencyPairSupported in currencyPairsSupported {
+            if currencyPairSupported.hasPrefix(currencySymbol) {
+                let compatibleCurrency = currencyPairSupported.components(separatedBy: "/")[1]
+                currencies.append(compatibleCurrency)
+            }
+        }
+        
+        return currencies
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Jobs/FileController.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -0,0 +1,44 @@
+//
+//  ReadConfig.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 20/07/2021.
+//
+
+import Foundation
+
+class FileController {
+    
+    /*
+     Read configuration variables from Config.xconfig
+     */
+    func readConfigVariable(withKey: String) -> String? {
+        return (Bundle.main.infoDictionary?[withKey] as? String)?
+            .replacingOccurrences(of: "\\", with: "")
+    }
+    
+    /*
+     Decode and read json file
+     */
+    func read<T: Decodable>(json filename: String) throws -> T {
+        let data: Data
+        
+        guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
+        else {
+            throw JsonErrors.fileMissing
+        }
+        
+        do {
+            data = try Data(contentsOf: file)
+        } catch {
+            throw JsonErrors.loadFailed(cause: error.localizedDescription)
+        }
+        
+        do {
+            let decoder = JSONDecoder()
+            return try decoder.decode(T.self, from: data)
+        } catch {
+            throw JsonErrors.parseFailed(cause: error.localizedDescription)
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Jobs/HapticsController.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -0,0 +1,19 @@
+//
+//  SimpleSuccess.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 20/07/2021.
+//
+
+import SwiftUI
+
+class HapticsController {
+    
+    /*
+     Default haptic for success action
+     */
+    func simpleSuccess() {
+        let generator = UINotificationFeedbackGenerator()
+        generator.notificationOccurred(.success)
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Jobs/NetworkController.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -0,0 +1,43 @@
+//
+//  Request.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 20/07/2021.
+//
+
+import Foundation
+
+class NetworkController {
+    
+    /*
+     Get http response and decode it with specified model
+     */
+    func httpRequest<T: Decodable>(url: String, model: T.Type, completion: @escaping (_ result: T) -> Void) {
+        
+        // We take some model data T.Type
+        guard let url = URL(string: url) else {
+            print("Invalid URL")
+            return
+        }
+        
+        let request = URLRequest(url: url)
+        URLSession.shared.dataTask(with: request) { data, response, error in
+            if let data = data {
+                do {
+                    // Decode response with the model passed
+                    let decodedResponse = try JSONDecoder().decode(model, from: data)
+                    DispatchQueue.main.async {
+                        completion(decodedResponse)
+                    }
+                    return
+                } catch {
+                    // Return error regarding the escaping code
+                    print(error)
+                }
+            }
+            // Error with the request
+            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
+        }
+        .resume()
+    }
+}
--- a/Simoleon/Models/CurrencyDetailsModel.swift	Mon Aug 23 17:14:47 2021 +0100
+++ b/Simoleon/Models/CurrencyDetailsModel.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -7,7 +7,6 @@
 
 import Foundation
 
-
 struct CurrencyDetailsModel: Codable {
     var name: String
     var flag: String
--- a/Simoleon/Models/CurrencyQuoteModel.swift	Mon Aug 23 17:14:47 2021 +0100
+++ b/Simoleon/Models/CurrencyQuoteModel.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -5,7 +5,7 @@
 //  Created by Dennis Concepción Martín on 15/07/2021.
 //
 
-import SwiftUI
+import Foundation
 
 struct CurrencyQuoteModel: Codable, Hashable {
     var symbol: String?
--- a/Simoleon/Settings.swift	Mon Aug 23 17:14:47 2021 +0100
+++ b/Simoleon/Settings.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -20,6 +20,8 @@
     @State private var showingAlert = false
     @State private var searchCurrency = ""
     
+    let fileController = FileController()
+    
     /*
      If searched currency string is empty:
      * Show all currencies
@@ -27,7 +29,7 @@
      * Show filtered list of currencies containing searched currency string
      */
     var searchResults: [String] {
-        let currencyPairsSupported: [String] = try! read(json: "CurrencyPairsSupported.json")
+        let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json")
         if searchCurrency.isEmpty {
             return currencyPairsSupported.sorted()
         } else {
@@ -114,11 +116,11 @@
              * View is appearing after user selected another default currency
              * Save it to core data
              */
-            if selectedDefaultCurrency == "" {
-                selectedDefaultCurrency = defaultCurrency.first?.pair ?? "USD/GBP"
-            } else {
-                setCoreData()
-            }
+//            if selectedDefaultCurrency == "" {
+//                selectedDefaultCurrency = defaultCurrency.first?.pair ?? "USD/GBP"
+//            } else {
+//                setCoreData()
+//            }
         }
         .listStyle(InsetGroupedListStyle())
         .navigationTitle("Settings")
@@ -131,21 +133,21 @@
     }
      
     // Save default currency to core data
-    private func setCoreData() {
-        if defaultCurrency.isEmpty {  // If it's empty -> add record
-            let defaultCurrency = DefaultCurrency(context: viewContext)
-            defaultCurrency.pair = selectedDefaultCurrency
-            
-            do {
-                try viewContext.save()
-            } catch {
-                print(error.localizedDescription)
-            }
-        } else {  // If not, update record
-            defaultCurrency.first?.pair = selectedDefaultCurrency
-            try? viewContext.save()
-        }
-    }
+//    private func setCoreData() {
+//        if defaultCurrency.isEmpty {  // If it's empty -> add record
+//            let defaultCurrency = DefaultCurrency(context: viewContext)
+//            defaultCurrency.pair = selectedDefaultCurrency
+//            
+//            do {
+//                try viewContext.save()
+//            } catch {
+//                print(error.localizedDescription)
+//            }
+//        } else {  // If not, update record
+//            defaultCurrency.first?.pair = selectedDefaultCurrency
+//            try? viewContext.save()
+//        }
+//    }
     
     // Check if user subscription is active
     private func checkEntitlement() {
--- a/Simoleon/SimoleonApp.swift	Mon Aug 23 17:14:47 2021 +0100
+++ b/Simoleon/SimoleonApp.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -12,9 +12,11 @@
 struct SimoleonApp: App {
     @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
     let persistenceController = PersistenceController.shared
+    let fileController = FileController()
     
     init() {
-        Purchases.configure(withAPIKey: "\(readConfig("PURCHASES_KEY")!)")
+        let apiKey = fileController.readConfigVariable(withKey: "PURCHASES_KEY")!
+        Purchases.configure(withAPIKey: apiKey)
     }
     
     var body: some Scene {
--- a/SimoleonTests/SimoleonTests.swift	Mon Aug 23 17:14:47 2021 +0100
+++ b/SimoleonTests/SimoleonTests.swift	Wed Aug 25 10:43:12 2021 +0100
@@ -9,6 +9,7 @@
 @testable import Simoleon
 
 class SimoleonTests: XCTestCase {
+    let fileController = FileController()
 
     override func setUpWithError() throws {
         // Put setup code here. This method is called before the invocation of each test method in the class.
@@ -20,18 +21,18 @@
     }
     
     func testReadJson() throws {
-        let currencyPairsSupported: [String]? = try? read(json: "CurrencyPairsSupported.json")
+        let currencyPairsSupported: [String]? = try? fileController.read(json: "CurrencyPairsSupported.json")
         XCTAssertNotNil(currencyPairsSupported, "An error occurred while reading CurrencyPairsSupported.json")
         
-        let currencyDetails: [String: CurrencyDetailsModel]? = try? read(json: "CurrencyDetails.json")
+        let currencyDetails: [String: CurrencyDetailsModel]? = try? fileController.read(json: "CurrencyDetails.json")
         XCTAssertNotNil(currencyDetails, "An error occurred while reading CurrencyDetails.json")
     }
     
     func testCurrencyExistence() throws {
-        let currencyDetails: [String: CurrencyDetailsModel] = try! read(json: "CurrencyDetails.json")
+        let currencyDetails: [String: CurrencyDetailsModel] = try! fileController.read(json: "CurrencyDetails.json")
         
         // Remove duplicates from currency pairs supported
-        let currencyPairsSupported: [String] = try! read(json: "CurrencyPairsSupported.json")
+        let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json")
         var currenciesSupported = Set<String>()
         
         for currencyPairSupported in currencyPairsSupported {