changeset 22:3596690dda73

Add Config files and implementing Settings
author Dennis Concepción Martín <dennisconcepcionmartin@gmail.com>
date Tue, 20 Jul 2021 09:02:51 +0100
parents c3dda63f50ed
children 699b5bb619db
files .gitignore ConfigTemplate.xcconfig Simoleon.xcodeproj/project.pbxproj Simoleon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved Simoleon.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate Simoleon/Assets.xcassets/TwitterLogo.imageset/Contents.json Simoleon/Assets.xcassets/TwitterLogo.imageset/TwitterLogo@x1.png Simoleon/Assets.xcassets/TwitterLogo.imageset/TwitterLogo@x2.png Simoleon/Assets.xcassets/TwitterLogo.imageset/TwitterLogo@x3.png Simoleon/ContentView.swift Simoleon/Conversion.swift Simoleon/Favourites.swift Simoleon/Functions/ReadConfig.swift Simoleon/Functions/Request.swift Simoleon/Helpers/FavouriteButton.swift Simoleon/Helpers/Sidebar.swift Simoleon/Info.plist Simoleon/Settings.swift
diffstat 18 files changed, 205 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/.gitignore	Mon Jul 19 19:27:12 2021 +0100
+++ b/.gitignore	Tue Jul 20 09:02:51 2021 +0100
@@ -1,1 +1,2 @@
 .DS_Store
+Config.xcconfig
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfigTemplate.xcconfig	Tue Jul 20 09:02:51 2021 +0100
@@ -0,0 +1,9 @@
+//
+//  ConfigTemplate.xcconfig
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 20/07/2021.
+//
+
+// Configuration settings file format documentation can be found at:
+// https://help.apple.com/xcode/#/dev745c5c974
--- a/Simoleon.xcodeproj/project.pbxproj	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon.xcodeproj/project.pbxproj	Tue Jul 20 09:02:51 2021 +0100
@@ -3,12 +3,15 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 52;
+	objectVersion = 50;
 	objects = {
 
 /* Begin PBXBuildFile section */
 		9555933A269B0AB8000FD726 /* ParseJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95559339269B0AB8000FD726 /* ParseJson.swift */; };
 		9555933D269B0E0A000FD726 /* CurrencyMetadata.json in Resources */ = {isa = PBXBuildFile; fileRef = 9555933C269B0E0A000FD726 /* CurrencyMetadata.json */; };
+		957065E226A5FE0400523E68 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 957065E126A5FE0400523E68 /* Settings.swift */; };
+		9585BB1226A6B71B00E3193E /* ReadConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9585BB1126A6B71B00E3193E /* ReadConfig.swift */; };
+		9585BB1426A6B7F400E3193E /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9585BB1326A6B7F400E3193E /* Request.swift */; };
 		95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9426A03ECB00613729 /* ContentView.swift */; };
 		95AEBC9B26A04A4200613729 /* CurrencyMetadataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9A26A04A4200613729 /* CurrencyMetadataModel.swift */; };
 		95AEBC9D26A04D4600613729 /* CurrencyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9C26A04D4600613729 /* CurrencyRow.swift */; };
@@ -18,7 +21,6 @@
 		95B54F4A26A4A450001DC0D8 /* ConversionBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4926A4A450001DC0D8 /* ConversionBox.swift */; };
 		95B54F4F26A4AC52001DC0D8 /* ContentViewPad.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F4E26A4AC52001DC0D8 /* ContentViewPad.swift */; };
 		95B54F5126A4ACAC001DC0D8 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B54F5026A4ACAC001DC0D8 /* Sidebar.swift */; };
-		95C02C8B269B61680061DD6D /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 95C02C8A269B61680061DD6D /* Alamofire */; };
 		95C5179126A5DC8E00BC2B24 /* ConditionalWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C5179026A5DC8E00BC2B24 /* ConditionalWrapper.swift */; };
 		95C5179926A5EC9F00BC2B24 /* FavouriteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C5179826A5EC9F00BC2B24 /* FavouriteButton.swift */; };
 		95C5179C26A5EFBE00BC2B24 /* Favourite+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C5179A26A5EFBE00BC2B24 /* Favourite+CoreDataClass.swift */; };
@@ -57,6 +59,11 @@
 /* Begin PBXFileReference section */
 		95559339269B0AB8000FD726 /* ParseJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseJson.swift; sourceTree = "<group>"; };
 		9555933C269B0E0A000FD726 /* CurrencyMetadata.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = CurrencyMetadata.json; sourceTree = "<group>"; };
+		957065E126A5FE0400523E68 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
+		9585BB0F26A6B58500E3193E /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
+		9585BB1026A6B5ED00E3193E /* ConfigTemplate.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ConfigTemplate.xcconfig; sourceTree = "<group>"; };
+		9585BB1126A6B71B00E3193E /* ReadConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadConfig.swift; sourceTree = "<group>"; };
+		9585BB1326A6B7F400E3193E /* Request.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
 		95AEBC9426A03ECB00613729 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
 		95AEBC9A26A04A4200613729 /* CurrencyMetadataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyMetadataModel.swift; sourceTree = "<group>"; };
 		95AEBC9C26A04D4600613729 /* CurrencyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyRow.swift; sourceTree = "<group>"; };
@@ -96,7 +103,6 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				95C02C8B269B61680061DD6D /* Alamofire in Frameworks */,
 				95E7643A269E0037008E9F31 /* CloudKit.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -133,6 +139,8 @@
 			isa = PBXGroup;
 			children = (
 				95559339269B0AB8000FD726 /* ParseJson.swift */,
+				9585BB1126A6B71B00E3193E /* ReadConfig.swift */,
+				9585BB1326A6B7F400E3193E /* Request.swift */,
 			);
 			path = Functions;
 			sourceTree = "<group>";
@@ -149,6 +157,8 @@
 		95C5B21B2697752600941585 = {
 			isa = PBXGroup;
 			children = (
+				9585BB1026A6B5ED00E3193E /* ConfigTemplate.xcconfig */,
+				9585BB0F26A6B58500E3193E /* Config.xcconfig */,
 				95C5B2262697752600941585 /* Simoleon */,
 				95C5B23D2697752700941585 /* SimoleonTests */,
 				95C5B2482697752700941585 /* SimoleonUITests */,
@@ -176,6 +186,7 @@
 				95B54F4E26A4AC52001DC0D8 /* ContentViewPad.swift */,
 				95B54F4326A4842C001DC0D8 /* Conversion.swift */,
 				95C5179E26A5F34200BC2B24 /* Favourites.swift */,
+				957065E126A5FE0400523E68 /* Settings.swift */,
 				95C5B22B2697752700941585 /* Assets.xcassets */,
 				95C5B2302697752700941585 /* Persistence.swift */,
 				95C5B2352697752700941585 /* Info.plist */,
@@ -255,7 +266,6 @@
 			);
 			name = Simoleon;
 			packageProductDependencies = (
-				95C02C8A269B61680061DD6D /* Alamofire */,
 			);
 			productName = Simoleon;
 			productReference = 95C5B2242697752600941585 /* Simoleon.app */;
@@ -329,7 +339,6 @@
 			);
 			mainGroup = 95C5B21B2697752600941585;
 			packageReferences = (
-				95C02C89269B61680061DD6D /* XCRemoteSwiftPackageReference "Alamofire" */,
 			);
 			productRefGroup = 95C5B2252697752600941585 /* Products */;
 			projectDirPath = "";
@@ -379,6 +388,7 @@
 				95C5179926A5EC9F00BC2B24 /* FavouriteButton.swift in Sources */,
 				95C5179C26A5EFBE00BC2B24 /* Favourite+CoreDataClass.swift in Sources */,
 				95C5B2312697752700941585 /* Persistence.swift in Sources */,
+				9585BB1226A6B71B00E3193E /* ReadConfig.swift in Sources */,
 				95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */,
 				95AEBC9B26A04A4200613729 /* CurrencyMetadataModel.swift in Sources */,
 				9555933A269B0AB8000FD726 /* ParseJson.swift in Sources */,
@@ -390,6 +400,8 @@
 				95AEBC9D26A04D4600613729 /* CurrencyRow.swift in Sources */,
 				95AEBCA326A0900E00613729 /* CurrencyQuoteModel.swift in Sources */,
 				95B54F4F26A4AC52001DC0D8 /* ContentViewPad.swift in Sources */,
+				9585BB1426A6B7F400E3193E /* Request.swift in Sources */,
+				957065E226A5FE0400523E68 /* Settings.swift in Sources */,
 				95B54F4426A4842C001DC0D8 /* Conversion.swift in Sources */,
 				95C5B2342697752700941585 /* Simoleon.xcdatamodeld in Sources */,
 				95C5179126A5DC8E00BC2B24 /* ConditionalWrapper.swift in Sources */,
@@ -493,6 +505,7 @@
 		};
 		95C5B24D2697752700941585 /* Release */ = {
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9585BB0F26A6B58500E3193E /* Config.xcconfig */;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;
@@ -548,6 +561,7 @@
 		};
 		95C5B24F2697752700941585 /* Debug */ = {
 			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9585BB0F26A6B58500E3193E /* Config.xcconfig */;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -721,25 +735,6 @@
 		};
 /* End XCConfigurationList section */
 
-/* Begin XCRemoteSwiftPackageReference section */
-		95C02C89269B61680061DD6D /* XCRemoteSwiftPackageReference "Alamofire" */ = {
-			isa = XCRemoteSwiftPackageReference;
-			repositoryURL = "https://github.com/Alamofire/Alamofire.git";
-			requirement = {
-				kind = upToNextMajorVersion;
-				minimumVersion = 5.4.3;
-			};
-		};
-/* End XCRemoteSwiftPackageReference section */
-
-/* Begin XCSwiftPackageProductDependency section */
-		95C02C8A269B61680061DD6D /* Alamofire */ = {
-			isa = XCSwiftPackageProductDependency;
-			package = 95C02C89269B61680061DD6D /* XCRemoteSwiftPackageReference "Alamofire" */;
-			productName = Alamofire;
-		};
-/* End XCSwiftPackageProductDependency section */
-
 /* Begin XCVersionGroup section */
 		95C5B2322697752700941585 /* Simoleon.xcdatamodeld */ = {
 			isa = XCVersionGroup;
--- a/Simoleon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved	Mon Jul 19 19:27:12 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-{
-  "object": {
-    "pins": [
-      {
-        "package": "Alamofire",
-        "repositoryURL": "https://github.com/Alamofire/Alamofire.git",
-        "state": {
-          "branch": null,
-          "revision": "f96b619bcb2383b43d898402283924b80e2c4bae",
-          "version": "5.4.3"
-        }
-      }
-    ]
-  },
-  "version": 1
-}
Binary file Simoleon.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Assets.xcassets/TwitterLogo.imageset/Contents.json	Tue Jul 20 09:02:51 2021 +0100
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "TwitterLogo@x1.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "TwitterLogo@x2.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "TwitterLogo@x3.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
Binary file Simoleon/Assets.xcassets/TwitterLogo.imageset/TwitterLogo@x1.png has changed
Binary file Simoleon/Assets.xcassets/TwitterLogo.imageset/TwitterLogo@x2.png has changed
Binary file Simoleon/Assets.xcassets/TwitterLogo.imageset/TwitterLogo@x3.png has changed
--- a/Simoleon/ContentView.swift	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon/ContentView.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -23,7 +23,7 @@
                 }
                 .tag(Tab.favourites)
             
-            Text("Settings")
+            Settings()
                 .tabItem {
                     Label("Settings", systemImage: "gear")
                 }
--- a/Simoleon/Conversion.swift	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon/Conversion.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -25,7 +25,7 @@
                     Button(action: { showingCurrencySelector = true }) {
                         RoundedRectangle(cornerRadius: 25)
                             .foregroundColor(Color(.secondarySystemBackground))
-                            .frame(height: 75)
+                            .frame(height: 65)
                             .overlay(CurrencyRow(currencyPair: currencyPair).padding(.horizontal))
                     }
                     
@@ -52,39 +52,32 @@
                 CurrencySelector(currencyPair: $currencyPair, showingCurrencySelector: $showingCurrencySelector)
             }
         }
+        .navigationTitle("Conversion")
+        .toolbar {
+            ToolbarItem(placement: .cancellationAction) {
+                if isEditing {
+                    Button("Cancel", action: {
+                        UIApplication.shared.dismissKeyboard()
+                        isEditing = false
+                    })
+                }
+            }
+        }
         .if(UIDevice.current.userInterfaceIdiom == .phone) { content in
-            NavigationView {
-                content
-                    .navigationTitle("Conversion")
-                    .toolbar {
-                        ToolbarItem(placement: .cancellationAction) {
-                            if isEditing {
-                                Button("Cancel", action: {
-                                    UIApplication.shared.dismissKeyboard()
-                                    isEditing = false
-                                })
-                            }
-                        }
-                    }
-            }
+            NavigationView { content }
         }
     }
     
     private func request(_ currencyPair: String) {
-        let url = "https://api.1forge.com/quotes?pairs=\(currencyPair)&api_key=BFWeJQ3jJtqqpDv5ArNis59pAlFcQ4KF"
+        let url = "\(readConfig("API_URL")!)quotes?pairs=\(currencyPair)&api_key=\(readConfig("API_KEY")!)"
         
-        AF.request(url).responseDecodable(of: [CurrencyQuoteModel].self) { response in
+        Simoleon.request(url: url, model: [CurrencyQuoteModel].self) { response in
             self.showingConversion = false
-            
-            if let currencyQuotes = response.value {
-                if let price = currencyQuotes.first?.price {
-                    self.price = price
-                    self.showingConversion =  true
-                } else {
-//                    Handle error
-                }
+            if let price = response.first?.price {
+                self.price = price
+                self.showingConversion =  true
             } else {
-//               Handle error
+                // Handle error
             }
         }
     }
--- a/Simoleon/Favourites.swift	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon/Favourites.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -21,16 +21,14 @@
             }
             .onDelete(perform: removeFromFavourites)
         }
+        .navigationTitle("Favourites")
+        .toolbar {
+            #if os(iOS)
+            EditButton()
+            #endif
+        }
         .if(UIDevice.current.userInterfaceIdiom == .phone) { content in
-            NavigationView {
-                content
-                    .navigationTitle("Favourites")
-                    .toolbar {
-                        #if os(iOS)
-                        EditButton()
-                        #endif
-                    }
-            }
+            NavigationView { content }
         }
     }
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Functions/ReadConfig.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -0,0 +1,13 @@
+//
+//  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: "")
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Functions/Request.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -0,0 +1,35 @@
+//
+//  Request.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 20/07/2021.
+//
+
+import SwiftUI
+
+func request<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/Helpers/FavouriteButton.swift	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon/Helpers/FavouriteButton.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -22,7 +22,7 @@
         }) {
             RoundedRectangle(cornerRadius: 25)
                 .foregroundColor(Color(.secondarySystemBackground))
-                .frame(width: 75, height: 75)
+                .frame(width: 65, height: 65)
                 .overlay(
                     Image(systemName: generateStar())
                         .font(.system(size: 28))
--- a/Simoleon/Helpers/Sidebar.swift	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon/Helpers/Sidebar.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -14,11 +14,11 @@
                 Label("Convert", systemImage: "arrow.counterclockwise.circle")
             }
             
-            NavigationLink(destination: Text("Favourites")) {
+            NavigationLink(destination: Favourites()) {
                 Label("Favourites", systemImage: "star")
             }
             
-            NavigationLink(destination: Text("Settings")) {
+            NavigationLink(destination: Settings()) {
                 Label("Settings", systemImage: "gear")
             }
         }
--- a/Simoleon/Info.plist	Mon Jul 19 19:27:12 2021 +0100
+++ b/Simoleon/Info.plist	Tue Jul 20 09:02:51 2021 +0100
@@ -41,6 +41,10 @@
 	<array>
 		<string>UIInterfaceOrientationPortrait</string>
 	</array>
+	<key>API_KEY</key>
+	<string>$(API_KEY)</string>
+	<key>API_URL</key>
+	<string>$(API_URL)</string>
 	<key>UISupportedInterfaceOrientations~ipad</key>
 	<array>
 		<string>UIInterfaceOrientationPortrait</string>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Simoleon/Settings.swift	Tue Jul 20 09:02:51 2021 +0100
@@ -0,0 +1,71 @@
+//
+//  Settings.swift
+//  Simoleon
+//
+//  Created by Dennis Concepción Martín on 19/07/2021.
+//
+
+import SwiftUI
+
+struct Settings: View {
+    let currencyPairs: [String] = parseJson("CurrencyPairs.json")
+    @State private var selectedCurrencyPair = "USD/GBP"
+    
+    var body: some View {
+        List {
+            Section(header: Text("Preferences")) {
+                Picker("Default currency", selection: $selectedCurrencyPair) {
+                    ForEach(currencyPairs.sorted(), id: \.self) { currencyPair in
+                        Text(currencyPair)
+                    }
+                }
+            }
+            
+            Section(header: Text("Stay in touch")) {
+                HStack {
+                    Image(systemName: "heart.fill")
+                        .foregroundColor(Color(.systemRed))
+                        .imageScale(.large)
+                    
+                    Text("Rate Simoleon")
+                }
+                
+                Link(destination: URL(string: "https://dennistech.io")!) {
+                    HStack {
+                        Image("TwitterLogo")
+                            .resizable()
+                            .frame(width: 30, height: 30)
+                        
+                        Text("Follow on Twitter")
+                    }
+                }
+                
+                Link(destination: URL(string: "https://dennistech.io/contact")!) {
+                    HStack {
+                        Image(systemName: "envelope.circle.fill")
+                            .renderingMode(.original)
+                            .imageScale(.large)
+                        
+                        Text("Contact")
+                    }
+                }
+            }
+            
+            Section(header: Text("About")) {
+                Link("Website", destination: URL(string: "https://dennistech.io")!)
+                Link("Privacy Policy", destination: URL(string: "https://dennistech.io")!)
+            }
+        }
+        .listStyle(InsetGroupedListStyle())
+        .navigationTitle("Settings")
+        .if(UIDevice.current.userInterfaceIdiom == .phone) { content in
+            NavigationView { content }
+        }
+    }
+}
+
+struct Settings_Previews: PreviewProvider {
+    static var previews: some View {
+        Settings()
+    }
+}