├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── Package.swift ├── README.md ├── RRSettingsKit.png ├── RRSettingsKit.xcodeproj ├── RRSettingsKitTests_Info.plist ├── RRSettingsKit_Info.plist ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ ├── WorkspaceSettings.xcsettings │ │ └── swiftpm │ │ └── Package.resolved └── xcshareddata │ └── xcschemes │ ├── RRSettingsKit.xcscheme │ ├── RRSettingsKitExample.xcscheme │ └── RRSettingsKitTests.xcscheme ├── RRSettingsKitExample ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── ContentView.swift ├── Info.plist ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json └── RRSettingsKitExampleApp.swift ├── Sources └── RRSettingsKit │ ├── MailView.swift │ ├── RRSettingsKit.swift │ └── SettingsRow.swift ├── Tests ├── LinuxMain.swift └── RRSettingsKitTests │ ├── RRSettingsKitTests.swift │ └── XCTestManifests.swift └── codemagic.yaml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: ["https://paypal.me/RRiyam"] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Rudrank Riyam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.5 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "RRSettingsKit", 8 | platforms: [.iOS(.v15)], 9 | products: [ 10 | // Products define the executables and libraries a package produces, and make them visible to other packages. 11 | .library( 12 | name: "RRSettingsKit", 13 | type: .dynamic, 14 | targets: ["RRSettingsKit"]), 15 | ], 16 | dependencies: [ 17 | .package(url: "https://github.com/rudrankriyam/RRComponentsKit.git", .branch("main")) 18 | // Dependencies declare other packages that this package depends on. 19 | // .package(url: /* package url */, from: "1.0.0"), 20 | ], 21 | targets: [ 22 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 23 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 24 | .target( 25 | name: "RRSettingsKit", 26 | dependencies: ["RRComponentsKit"]), 27 | .testTarget( 28 | name: "RRSettingsKitTests", 29 | dependencies: ["RRSettingsKit"]), 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![RRSettingsKit Logo](./RRSettingsKit.png?style=centerme) 2 | 3 | A beautiful settings screen created in SwiftUI. It is based on my [Gradient Game!](https://apps.apple.com/app/id1479784361) 4 | 5 | ## Support 6 | 7 | Love this project? Check out my books to explore more of AI and iOS development: 8 | - [Exploring AI for iOS Development](https://academy.rudrank.com/product/ai) 9 | - [Exploring AI-Assisted Coding for iOS Development](https://academy.rudrank.com/product/ai-assisted-coding) 10 | 11 | Your support helps to keep this project growing! 12 | 13 | ## Features 14 | - \[x] Customisable 15 | - \[x] iOS compatibility 16 | - \[x] Landscape compatibility 17 | - \[x] iPad compatibility 18 | - \[x] Dark mode 19 | - \[ ] Hover Effect for iPad 20 | - \[ ] Mac compatibility 21 | 22 | ## Requirements 23 | - iOS 15.0+ / macOS 10.15+ [soon] 24 | 25 | ## Usage 26 | 27 | ### SettingsRow 28 | 29 | It takes the image, title and action as the parameter. You can customise it to your liking. 30 | 31 | For example, this row is for writing a review, with a function in the closure. 32 | 33 | ```Swift 34 | RRSettingsKit.SettingsRow(imageName: "pencil.and.outline", title: "Write a review") { 35 | self.settingsViewModel.writeReview() 36 | } 37 | ``` 38 | 39 | More documentation coming soon with Version 0.1.0 40 | 41 | ## Contribution 42 | 43 | You are free to add more features to it, or refactor the code! I will be more than happy to accept PRs. 44 | 45 | Contact - [Rudrank Riyam](https://twitter.com/rudrankriyam) 46 | -------------------------------------------------------------------------------- /RRSettingsKit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rryam/RRSettingsKit/2a6a0207c41f09b6a2c687191bbde2389afed1e4/RRSettingsKit.png -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/RRSettingsKitTests_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | BNDL 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/RRSettingsKit_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | "RRSettingsKit::RRSettingsKitPackageTests::ProductTarget" /* RRSettingsKitPackageTests */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = OBJ_32 /* Build configuration list for PBXAggregateTarget "RRSettingsKitPackageTests" */; 13 | buildPhases = ( 14 | ); 15 | dependencies = ( 16 | OBJ_35 /* PBXTargetDependency */, 17 | ); 18 | name = RRSettingsKitPackageTests; 19 | productName = RRSettingsKitPackageTests; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | 0A43200D2611D44700BF1EF9 /* SettingsRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A43200C2611D44700BF1EF9 /* SettingsRow.swift */; }; 25 | 0A4320202611DB8200BF1EF9 /* RRComponentsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 0A43201F2611DB8200BF1EF9 /* RRComponentsKit */; }; 26 | 0A4320212611DB8200BF1EF9 /* RRComponentsKit in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 0A43201F2611DB8200BF1EF9 /* RRComponentsKit */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 27 | 0A4320AC2611DDBE00BF1EF9 /* RRSettingsKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "RRSettingsKit::RRSettingsKit::Product" /* RRSettingsKit.framework */; }; 28 | 0A4320AD2611DDBE00BF1EF9 /* RRSettingsKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = "RRSettingsKit::RRSettingsKit::Product" /* RRSettingsKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 29 | 0A71C4D12533AACF00D0E65F /* RRSettingsKitExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A71C4D02533AACF00D0E65F /* RRSettingsKitExampleApp.swift */; }; 30 | 0A71C4D32533AACF00D0E65F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A71C4D22533AACF00D0E65F /* ContentView.swift */; }; 31 | 0A71C4D52533AAD000D0E65F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A71C4D42533AAD000D0E65F /* Assets.xcassets */; }; 32 | 0A71C4D82533AAD000D0E65F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A71C4D72533AAD000D0E65F /* Preview Assets.xcassets */; }; 33 | 0A8025BE26E3D9A5005AF372 /* RRComponentsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 0A8025BD26E3D9A5005AF372 /* RRComponentsKit */; }; 34 | 0A8025BF26E3D9A5005AF372 /* RRComponentsKit in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 0A8025BD26E3D9A5005AF372 /* RRComponentsKit */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 35 | 0A8025C126E3DD9C005AF372 /* MailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8025C026E3DD9C005AF372 /* MailView.swift */; }; 36 | OBJ_23 /* RRSettingsKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* RRSettingsKit.swift */; }; 37 | OBJ_30 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; }; 38 | OBJ_41 /* RRSettingsKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* RRSettingsKitTests.swift */; }; 39 | OBJ_42 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* XCTestManifests.swift */; }; 40 | OBJ_44 /* RRSettingsKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "RRSettingsKit::RRSettingsKit::Product" /* RRSettingsKit.framework */; }; 41 | /* End PBXBuildFile section */ 42 | 43 | /* Begin PBXContainerItemProxy section */ 44 | 0A4320AE2611DDBE00BF1EF9 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = OBJ_1 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = "RRSettingsKit::RRSettingsKit"; 49 | remoteInfo = RRSettingsKit; 50 | }; 51 | 0A71C4C52533A04900D0E65F /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = OBJ_1 /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = "RRSettingsKit::RRSettingsKitTests"; 56 | remoteInfo = RRSettingsKitTests; 57 | }; 58 | 0A71C4C72533A04900D0E65F /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = OBJ_1 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = "RRSettingsKit::RRSettingsKit"; 63 | remoteInfo = RRSettingsKit; 64 | }; 65 | /* End PBXContainerItemProxy section */ 66 | 67 | /* Begin PBXCopyFilesBuildPhase section */ 68 | 0A4320072611D42A00BF1EF9 /* Embed Frameworks */ = { 69 | isa = PBXCopyFilesBuildPhase; 70 | buildActionMask = 2147483647; 71 | dstPath = ""; 72 | dstSubfolderSpec = 10; 73 | files = ( 74 | 0A4320212611DB8200BF1EF9 /* RRComponentsKit in Embed Frameworks */, 75 | ); 76 | name = "Embed Frameworks"; 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 0A4320B02611DDBE00BF1EF9 /* Embed Frameworks */ = { 80 | isa = PBXCopyFilesBuildPhase; 81 | buildActionMask = 2147483647; 82 | dstPath = ""; 83 | dstSubfolderSpec = 10; 84 | files = ( 85 | 0A4320AD2611DDBE00BF1EF9 /* RRSettingsKit.framework in Embed Frameworks */, 86 | 0A8025BF26E3D9A5005AF372 /* RRComponentsKit in Embed Frameworks */, 87 | ); 88 | name = "Embed Frameworks"; 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | /* End PBXCopyFilesBuildPhase section */ 92 | 93 | /* Begin PBXFileReference section */ 94 | 0A43200C2611D44700BF1EF9 /* SettingsRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRow.swift; sourceTree = ""; }; 95 | 0A71C4CE2533AACF00D0E65F /* RRSettingsKitExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RRSettingsKitExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96 | 0A71C4D02533AACF00D0E65F /* RRSettingsKitExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RRSettingsKitExampleApp.swift; sourceTree = ""; }; 97 | 0A71C4D22533AACF00D0E65F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 98 | 0A71C4D42533AAD000D0E65F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 99 | 0A71C4D72533AAD000D0E65F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 100 | 0A71C4D92533AAD000D0E65F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 101 | 0A8025C026E3DD9C005AF372 /* MailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailView.swift; sourceTree = ""; }; 102 | OBJ_12 /* RRSettingsKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RRSettingsKitTests.swift; sourceTree = ""; }; 103 | OBJ_13 /* XCTestManifests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = ""; }; 104 | OBJ_17 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 105 | OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 106 | OBJ_9 /* RRSettingsKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RRSettingsKit.swift; sourceTree = ""; }; 107 | "RRSettingsKit::RRSettingsKit::Product" /* RRSettingsKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RRSettingsKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 108 | "RRSettingsKit::RRSettingsKitTests::Product" /* RRSettingsKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = RRSettingsKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 109 | /* End PBXFileReference section */ 110 | 111 | /* Begin PBXFrameworksBuildPhase section */ 112 | 0A71C4CB2533AACF00D0E65F /* Frameworks */ = { 113 | isa = PBXFrameworksBuildPhase; 114 | buildActionMask = 2147483647; 115 | files = ( 116 | 0A4320AC2611DDBE00BF1EF9 /* RRSettingsKit.framework in Frameworks */, 117 | 0A8025BE26E3D9A5005AF372 /* RRComponentsKit in Frameworks */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | OBJ_24 /* Frameworks */ = { 122 | isa = PBXFrameworksBuildPhase; 123 | buildActionMask = 0; 124 | files = ( 125 | 0A4320202611DB8200BF1EF9 /* RRComponentsKit in Frameworks */, 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | OBJ_43 /* Frameworks */ = { 130 | isa = PBXFrameworksBuildPhase; 131 | buildActionMask = 0; 132 | files = ( 133 | OBJ_44 /* RRSettingsKit.framework in Frameworks */, 134 | ); 135 | runOnlyForDeploymentPostprocessing = 0; 136 | }; 137 | /* End PBXFrameworksBuildPhase section */ 138 | 139 | /* Begin PBXGroup section */ 140 | 0A43201E2611DB8200BF1EF9 /* Frameworks */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | ); 144 | name = Frameworks; 145 | sourceTree = ""; 146 | }; 147 | 0A71C4CF2533AACF00D0E65F /* RRSettingsKitExample */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 0A71C4D02533AACF00D0E65F /* RRSettingsKitExampleApp.swift */, 151 | 0A71C4D22533AACF00D0E65F /* ContentView.swift */, 152 | 0A71C4D42533AAD000D0E65F /* Assets.xcassets */, 153 | 0A71C4D92533AAD000D0E65F /* Info.plist */, 154 | 0A71C4D62533AAD000D0E65F /* Preview Content */, 155 | ); 156 | path = RRSettingsKitExample; 157 | sourceTree = ""; 158 | }; 159 | 0A71C4D62533AAD000D0E65F /* Preview Content */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 0A71C4D72533AAD000D0E65F /* Preview Assets.xcassets */, 163 | ); 164 | path = "Preview Content"; 165 | sourceTree = ""; 166 | }; 167 | OBJ_10 /* Tests */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | OBJ_11 /* RRSettingsKitTests */, 171 | ); 172 | name = Tests; 173 | sourceTree = SOURCE_ROOT; 174 | }; 175 | OBJ_11 /* RRSettingsKitTests */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | OBJ_12 /* RRSettingsKitTests.swift */, 179 | OBJ_13 /* XCTestManifests.swift */, 180 | ); 181 | name = RRSettingsKitTests; 182 | path = Tests/RRSettingsKitTests; 183 | sourceTree = SOURCE_ROOT; 184 | }; 185 | OBJ_14 /* Products */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | "RRSettingsKit::RRSettingsKit::Product" /* RRSettingsKit.framework */, 189 | "RRSettingsKit::RRSettingsKitTests::Product" /* RRSettingsKitTests.xctest */, 190 | 0A71C4CE2533AACF00D0E65F /* RRSettingsKitExample.app */, 191 | ); 192 | name = Products; 193 | sourceTree = BUILT_PRODUCTS_DIR; 194 | }; 195 | OBJ_5 = { 196 | isa = PBXGroup; 197 | children = ( 198 | OBJ_6 /* Package.swift */, 199 | OBJ_7 /* Sources */, 200 | OBJ_10 /* Tests */, 201 | 0A71C4CF2533AACF00D0E65F /* RRSettingsKitExample */, 202 | OBJ_14 /* Products */, 203 | OBJ_17 /* README.md */, 204 | 0A43201E2611DB8200BF1EF9 /* Frameworks */, 205 | ); 206 | sourceTree = ""; 207 | }; 208 | OBJ_7 /* Sources */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | OBJ_8 /* RRSettingsKit */, 212 | ); 213 | name = Sources; 214 | sourceTree = SOURCE_ROOT; 215 | }; 216 | OBJ_8 /* RRSettingsKit */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | OBJ_9 /* RRSettingsKit.swift */, 220 | 0A43200C2611D44700BF1EF9 /* SettingsRow.swift */, 221 | 0A8025C026E3DD9C005AF372 /* MailView.swift */, 222 | ); 223 | name = RRSettingsKit; 224 | path = Sources/RRSettingsKit; 225 | sourceTree = SOURCE_ROOT; 226 | }; 227 | /* End PBXGroup section */ 228 | 229 | /* Begin PBXNativeTarget section */ 230 | 0A71C4CD2533AACF00D0E65F /* RRSettingsKitExample */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = 0A71C4DC2533AAD000D0E65F /* Build configuration list for PBXNativeTarget "RRSettingsKitExample" */; 233 | buildPhases = ( 234 | 0A71C4CA2533AACF00D0E65F /* Sources */, 235 | 0A71C4CB2533AACF00D0E65F /* Frameworks */, 236 | 0A71C4CC2533AACF00D0E65F /* Resources */, 237 | 0A4320B02611DDBE00BF1EF9 /* Embed Frameworks */, 238 | ); 239 | buildRules = ( 240 | ); 241 | dependencies = ( 242 | 0A4320AF2611DDBE00BF1EF9 /* PBXTargetDependency */, 243 | ); 244 | name = RRSettingsKitExample; 245 | packageProductDependencies = ( 246 | 0A8025BD26E3D9A5005AF372 /* RRComponentsKit */, 247 | ); 248 | productName = RRSettingsKitExample; 249 | productReference = 0A71C4CE2533AACF00D0E65F /* RRSettingsKitExample.app */; 250 | productType = "com.apple.product-type.application"; 251 | }; 252 | "RRSettingsKit::RRSettingsKit" /* RRSettingsKit */ = { 253 | isa = PBXNativeTarget; 254 | buildConfigurationList = OBJ_19 /* Build configuration list for PBXNativeTarget "RRSettingsKit" */; 255 | buildPhases = ( 256 | OBJ_22 /* Sources */, 257 | OBJ_24 /* Frameworks */, 258 | 0A4320072611D42A00BF1EF9 /* Embed Frameworks */, 259 | ); 260 | buildRules = ( 261 | ); 262 | dependencies = ( 263 | ); 264 | name = RRSettingsKit; 265 | packageProductDependencies = ( 266 | 0A43201F2611DB8200BF1EF9 /* RRComponentsKit */, 267 | ); 268 | productName = RRSettingsKit; 269 | productReference = "RRSettingsKit::RRSettingsKit::Product" /* RRSettingsKit.framework */; 270 | productType = "com.apple.product-type.framework"; 271 | }; 272 | "RRSettingsKit::RRSettingsKitTests" /* RRSettingsKitTests */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = OBJ_37 /* Build configuration list for PBXNativeTarget "RRSettingsKitTests" */; 275 | buildPhases = ( 276 | OBJ_40 /* Sources */, 277 | OBJ_43 /* Frameworks */, 278 | ); 279 | buildRules = ( 280 | ); 281 | dependencies = ( 282 | OBJ_45 /* PBXTargetDependency */, 283 | ); 284 | name = RRSettingsKitTests; 285 | productName = RRSettingsKitTests; 286 | productReference = "RRSettingsKit::RRSettingsKitTests::Product" /* RRSettingsKitTests.xctest */; 287 | productType = "com.apple.product-type.bundle.unit-test"; 288 | }; 289 | "RRSettingsKit::SwiftPMPackageDescription" /* RRSettingsKitPackageDescription */ = { 290 | isa = PBXNativeTarget; 291 | buildConfigurationList = OBJ_26 /* Build configuration list for PBXNativeTarget "RRSettingsKitPackageDescription" */; 292 | buildPhases = ( 293 | OBJ_29 /* Sources */, 294 | ); 295 | buildRules = ( 296 | ); 297 | dependencies = ( 298 | ); 299 | name = RRSettingsKitPackageDescription; 300 | productName = RRSettingsKitPackageDescription; 301 | productType = "com.apple.product-type.framework"; 302 | }; 303 | /* End PBXNativeTarget section */ 304 | 305 | /* Begin PBXProject section */ 306 | OBJ_1 /* Project object */ = { 307 | isa = PBXProject; 308 | attributes = { 309 | LastSwiftMigration = 9999; 310 | LastSwiftUpdateCheck = 1220; 311 | LastUpgradeCheck = 1320; 312 | TargetAttributes = { 313 | 0A71C4CD2533AACF00D0E65F = { 314 | CreatedOnToolsVersion = 12.2; 315 | ProvisioningStyle = Automatic; 316 | }; 317 | }; 318 | }; 319 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "RRSettingsKit" */; 320 | compatibilityVersion = "Xcode 3.2"; 321 | developmentRegion = en; 322 | hasScannedForEncodings = 0; 323 | knownRegions = ( 324 | en, 325 | Base, 326 | ); 327 | mainGroup = OBJ_5; 328 | packageReferences = ( 329 | 0A4320032611D42A00BF1EF9 /* XCRemoteSwiftPackageReference "RRComponentsKit" */, 330 | ); 331 | productRefGroup = OBJ_14 /* Products */; 332 | projectDirPath = ""; 333 | projectRoot = ""; 334 | targets = ( 335 | "RRSettingsKit::RRSettingsKit" /* RRSettingsKit */, 336 | "RRSettingsKit::SwiftPMPackageDescription" /* RRSettingsKitPackageDescription */, 337 | "RRSettingsKit::RRSettingsKitPackageTests::ProductTarget" /* RRSettingsKitPackageTests */, 338 | "RRSettingsKit::RRSettingsKitTests" /* RRSettingsKitTests */, 339 | 0A71C4CD2533AACF00D0E65F /* RRSettingsKitExample */, 340 | ); 341 | }; 342 | /* End PBXProject section */ 343 | 344 | /* Begin PBXResourcesBuildPhase section */ 345 | 0A71C4CC2533AACF00D0E65F /* Resources */ = { 346 | isa = PBXResourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | 0A71C4D82533AAD000D0E65F /* Preview Assets.xcassets in Resources */, 350 | 0A71C4D52533AAD000D0E65F /* Assets.xcassets in Resources */, 351 | ); 352 | runOnlyForDeploymentPostprocessing = 0; 353 | }; 354 | /* End PBXResourcesBuildPhase section */ 355 | 356 | /* Begin PBXSourcesBuildPhase section */ 357 | 0A71C4CA2533AACF00D0E65F /* Sources */ = { 358 | isa = PBXSourcesBuildPhase; 359 | buildActionMask = 2147483647; 360 | files = ( 361 | 0A71C4D32533AACF00D0E65F /* ContentView.swift in Sources */, 362 | 0A71C4D12533AACF00D0E65F /* RRSettingsKitExampleApp.swift in Sources */, 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | }; 366 | OBJ_22 /* Sources */ = { 367 | isa = PBXSourcesBuildPhase; 368 | buildActionMask = 0; 369 | files = ( 370 | OBJ_23 /* RRSettingsKit.swift in Sources */, 371 | 0A8025C126E3DD9C005AF372 /* MailView.swift in Sources */, 372 | 0A43200D2611D44700BF1EF9 /* SettingsRow.swift in Sources */, 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | OBJ_29 /* Sources */ = { 377 | isa = PBXSourcesBuildPhase; 378 | buildActionMask = 0; 379 | files = ( 380 | OBJ_30 /* Package.swift in Sources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | OBJ_40 /* Sources */ = { 385 | isa = PBXSourcesBuildPhase; 386 | buildActionMask = 0; 387 | files = ( 388 | OBJ_41 /* RRSettingsKitTests.swift in Sources */, 389 | OBJ_42 /* XCTestManifests.swift in Sources */, 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | /* End PBXSourcesBuildPhase section */ 394 | 395 | /* Begin PBXTargetDependency section */ 396 | 0A4320AF2611DDBE00BF1EF9 /* PBXTargetDependency */ = { 397 | isa = PBXTargetDependency; 398 | target = "RRSettingsKit::RRSettingsKit" /* RRSettingsKit */; 399 | targetProxy = 0A4320AE2611DDBE00BF1EF9 /* PBXContainerItemProxy */; 400 | }; 401 | OBJ_35 /* PBXTargetDependency */ = { 402 | isa = PBXTargetDependency; 403 | target = "RRSettingsKit::RRSettingsKitTests" /* RRSettingsKitTests */; 404 | targetProxy = 0A71C4C52533A04900D0E65F /* PBXContainerItemProxy */; 405 | }; 406 | OBJ_45 /* PBXTargetDependency */ = { 407 | isa = PBXTargetDependency; 408 | target = "RRSettingsKit::RRSettingsKit" /* RRSettingsKit */; 409 | targetProxy = 0A71C4C72533A04900D0E65F /* PBXContainerItemProxy */; 410 | }; 411 | /* End PBXTargetDependency section */ 412 | 413 | /* Begin XCBuildConfiguration section */ 414 | 0A71C4DA2533AAD000D0E65F /* Debug */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ALWAYS_SEARCH_USER_PATHS = NO; 418 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 419 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 420 | CLANG_ANALYZER_NONNULL = YES; 421 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 422 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 423 | CLANG_CXX_LIBRARY = "libc++"; 424 | CLANG_ENABLE_MODULES = YES; 425 | CLANG_ENABLE_OBJC_WEAK = YES; 426 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 427 | CLANG_WARN_BOOL_CONVERSION = YES; 428 | CLANG_WARN_COMMA = YES; 429 | CLANG_WARN_CONSTANT_CONVERSION = YES; 430 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 431 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 432 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 433 | CLANG_WARN_EMPTY_BODY = YES; 434 | CLANG_WARN_ENUM_CONVERSION = YES; 435 | CLANG_WARN_INFINITE_RECURSION = YES; 436 | CLANG_WARN_INT_CONVERSION = YES; 437 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 438 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 439 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 440 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 441 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 442 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 443 | CLANG_WARN_STRICT_PROTOTYPES = YES; 444 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 445 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 446 | CLANG_WARN_UNREACHABLE_CODE = YES; 447 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 448 | CODE_SIGN_STYLE = Automatic; 449 | DEVELOPMENT_ASSET_PATHS = "\"RRSettingsKitExample/Preview Content\""; 450 | ENABLE_PREVIEWS = YES; 451 | ENABLE_STRICT_OBJC_MSGSEND = YES; 452 | ENABLE_TESTABILITY = YES; 453 | GCC_C_LANGUAGE_STANDARD = gnu11; 454 | GCC_DYNAMIC_NO_PIC = NO; 455 | GCC_NO_COMMON_BLOCKS = YES; 456 | GCC_PREPROCESSOR_DEFINITIONS = ( 457 | "DEBUG=1", 458 | "$(inherited)", 459 | ); 460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 462 | GCC_WARN_UNDECLARED_SELECTOR = YES; 463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 464 | GCC_WARN_UNUSED_FUNCTION = YES; 465 | GCC_WARN_UNUSED_VARIABLE = YES; 466 | INFOPLIST_FILE = RRSettingsKitExample/Info.plist; 467 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 468 | LD_RUNPATH_SEARCH_PATHS = ( 469 | "$(inherited)", 470 | "@executable_path/Frameworks", 471 | ); 472 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 473 | MTL_FAST_MATH = YES; 474 | PRODUCT_BUNDLE_IDENTIFIER = com.rudrankriyam.RRSettingsKitExample; 475 | PRODUCT_NAME = "$(TARGET_NAME)"; 476 | SDKROOT = iphoneos; 477 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 478 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 479 | SWIFT_VERSION = 5.0; 480 | TARGETED_DEVICE_FAMILY = "1,2"; 481 | }; 482 | name = Debug; 483 | }; 484 | 0A71C4DB2533AAD000D0E65F /* Release */ = { 485 | isa = XCBuildConfiguration; 486 | buildSettings = { 487 | ALWAYS_SEARCH_USER_PATHS = NO; 488 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 489 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 490 | CLANG_ANALYZER_NONNULL = YES; 491 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 492 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 493 | CLANG_CXX_LIBRARY = "libc++"; 494 | CLANG_ENABLE_MODULES = YES; 495 | CLANG_ENABLE_OBJC_WEAK = YES; 496 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 497 | CLANG_WARN_BOOL_CONVERSION = YES; 498 | CLANG_WARN_COMMA = YES; 499 | CLANG_WARN_CONSTANT_CONVERSION = YES; 500 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 501 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 502 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 503 | CLANG_WARN_EMPTY_BODY = YES; 504 | CLANG_WARN_ENUM_CONVERSION = YES; 505 | CLANG_WARN_INFINITE_RECURSION = YES; 506 | CLANG_WARN_INT_CONVERSION = YES; 507 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 508 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 509 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 510 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 511 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 512 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 513 | CLANG_WARN_STRICT_PROTOTYPES = YES; 514 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 515 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 516 | CLANG_WARN_UNREACHABLE_CODE = YES; 517 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 518 | CODE_SIGN_STYLE = Automatic; 519 | COPY_PHASE_STRIP = NO; 520 | DEVELOPMENT_ASSET_PATHS = "\"RRSettingsKitExample/Preview Content\""; 521 | ENABLE_NS_ASSERTIONS = NO; 522 | ENABLE_PREVIEWS = YES; 523 | ENABLE_STRICT_OBJC_MSGSEND = YES; 524 | GCC_C_LANGUAGE_STANDARD = gnu11; 525 | GCC_NO_COMMON_BLOCKS = YES; 526 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 527 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 528 | GCC_WARN_UNDECLARED_SELECTOR = YES; 529 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 530 | GCC_WARN_UNUSED_FUNCTION = YES; 531 | GCC_WARN_UNUSED_VARIABLE = YES; 532 | INFOPLIST_FILE = RRSettingsKitExample/Info.plist; 533 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 534 | LD_RUNPATH_SEARCH_PATHS = ( 535 | "$(inherited)", 536 | "@executable_path/Frameworks", 537 | ); 538 | MTL_ENABLE_DEBUG_INFO = NO; 539 | MTL_FAST_MATH = YES; 540 | PRODUCT_BUNDLE_IDENTIFIER = com.rudrankriyam.RRSettingsKitExample; 541 | PRODUCT_NAME = "$(TARGET_NAME)"; 542 | SDKROOT = iphoneos; 543 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 544 | SWIFT_VERSION = 5.0; 545 | TARGETED_DEVICE_FAMILY = "1,2"; 546 | VALIDATE_PRODUCT = YES; 547 | }; 548 | name = Release; 549 | }; 550 | OBJ_20 /* Debug */ = { 551 | isa = XCBuildConfiguration; 552 | buildSettings = { 553 | ENABLE_TESTABILITY = YES; 554 | FRAMEWORK_SEARCH_PATHS = ( 555 | "$(inherited)", 556 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 557 | ); 558 | HEADER_SEARCH_PATHS = "$(inherited)"; 559 | INFOPLIST_FILE = RRSettingsKit.xcodeproj/RRSettingsKit_Info.plist; 560 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 561 | LD_RUNPATH_SEARCH_PATHS = ( 562 | "$(inherited)", 563 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx", 564 | ); 565 | MACOSX_DEPLOYMENT_TARGET = 11.0; 566 | MARKETING_VERSION = 1.0.2; 567 | OTHER_CFLAGS = "$(inherited)"; 568 | OTHER_LDFLAGS = "$(inherited)"; 569 | OTHER_SWIFT_FLAGS = "$(inherited)"; 570 | PRODUCT_BUNDLE_IDENTIFIER = RRSettingsKit; 571 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 572 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 573 | SDKROOT = iphoneos; 574 | SKIP_INSTALL = YES; 575 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 576 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 577 | SWIFT_VERSION = 5.0; 578 | TARGET_NAME = RRSettingsKit; 579 | TVOS_DEPLOYMENT_TARGET = 12.0; 580 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 581 | }; 582 | name = Debug; 583 | }; 584 | OBJ_21 /* Release */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | ENABLE_TESTABILITY = YES; 588 | FRAMEWORK_SEARCH_PATHS = ( 589 | "$(inherited)", 590 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 591 | ); 592 | HEADER_SEARCH_PATHS = "$(inherited)"; 593 | INFOPLIST_FILE = RRSettingsKit.xcodeproj/RRSettingsKit_Info.plist; 594 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 595 | LD_RUNPATH_SEARCH_PATHS = ( 596 | "$(inherited)", 597 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx", 598 | ); 599 | MACOSX_DEPLOYMENT_TARGET = 11.0; 600 | MARKETING_VERSION = 1.0.2; 601 | OTHER_CFLAGS = "$(inherited)"; 602 | OTHER_LDFLAGS = "$(inherited)"; 603 | OTHER_SWIFT_FLAGS = "$(inherited)"; 604 | PRODUCT_BUNDLE_IDENTIFIER = RRSettingsKit; 605 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 606 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 607 | SDKROOT = iphoneos; 608 | SKIP_INSTALL = YES; 609 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 610 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 611 | SWIFT_VERSION = 5.0; 612 | TARGET_NAME = RRSettingsKit; 613 | TVOS_DEPLOYMENT_TARGET = 12.0; 614 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 615 | }; 616 | name = Release; 617 | }; 618 | OBJ_27 /* Debug */ = { 619 | isa = XCBuildConfiguration; 620 | buildSettings = { 621 | LD = /usr/bin/true; 622 | MACOSX_DEPLOYMENT_TARGET = 11.0; 623 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -package-description-version 5.3.0"; 624 | SDKROOT = iphoneos; 625 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 626 | SWIFT_VERSION = 5.0; 627 | }; 628 | name = Debug; 629 | }; 630 | OBJ_28 /* Release */ = { 631 | isa = XCBuildConfiguration; 632 | buildSettings = { 633 | LD = /usr/bin/true; 634 | MACOSX_DEPLOYMENT_TARGET = 11.0; 635 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -package-description-version 5.3.0"; 636 | SDKROOT = iphoneos; 637 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 638 | SWIFT_VERSION = 5.0; 639 | }; 640 | name = Release; 641 | }; 642 | OBJ_3 /* Debug */ = { 643 | isa = XCBuildConfiguration; 644 | buildSettings = { 645 | CLANG_ENABLE_OBJC_ARC = YES; 646 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 647 | CLANG_WARN_BOOL_CONVERSION = YES; 648 | CLANG_WARN_COMMA = YES; 649 | CLANG_WARN_CONSTANT_CONVERSION = YES; 650 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 651 | CLANG_WARN_EMPTY_BODY = YES; 652 | CLANG_WARN_ENUM_CONVERSION = YES; 653 | CLANG_WARN_INFINITE_RECURSION = YES; 654 | CLANG_WARN_INT_CONVERSION = YES; 655 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 656 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 657 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 658 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 659 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 660 | CLANG_WARN_STRICT_PROTOTYPES = YES; 661 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 662 | CLANG_WARN_UNREACHABLE_CODE = YES; 663 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 664 | COMBINE_HIDPI_IMAGES = YES; 665 | COPY_PHASE_STRIP = NO; 666 | DEBUG_INFORMATION_FORMAT = dwarf; 667 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 668 | ENABLE_NS_ASSERTIONS = YES; 669 | ENABLE_STRICT_OBJC_MSGSEND = YES; 670 | ENABLE_TESTABILITY = YES; 671 | GCC_NO_COMMON_BLOCKS = YES; 672 | GCC_OPTIMIZATION_LEVEL = 0; 673 | GCC_PREPROCESSOR_DEFINITIONS = ( 674 | "$(inherited)", 675 | "SWIFT_PACKAGE=1", 676 | "DEBUG=1", 677 | ); 678 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 679 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 680 | GCC_WARN_UNDECLARED_SELECTOR = YES; 681 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 682 | GCC_WARN_UNUSED_FUNCTION = YES; 683 | GCC_WARN_UNUSED_VARIABLE = YES; 684 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 685 | MACOSX_DEPLOYMENT_TARGET = 11.0; 686 | ONLY_ACTIVE_ARCH = YES; 687 | OTHER_SWIFT_FLAGS = "$(inherited) -DXcode"; 688 | PRODUCT_NAME = "$(TARGET_NAME)"; 689 | SDKROOT = macosx; 690 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; 691 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE DEBUG"; 692 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 693 | USE_HEADERMAP = NO; 694 | }; 695 | name = Debug; 696 | }; 697 | OBJ_33 /* Debug */ = { 698 | isa = XCBuildConfiguration; 699 | buildSettings = { 700 | SDKROOT = iphoneos; 701 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 702 | }; 703 | name = Debug; 704 | }; 705 | OBJ_34 /* Release */ = { 706 | isa = XCBuildConfiguration; 707 | buildSettings = { 708 | SDKROOT = iphoneos; 709 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 710 | }; 711 | name = Release; 712 | }; 713 | OBJ_38 /* Debug */ = { 714 | isa = XCBuildConfiguration; 715 | buildSettings = { 716 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 717 | CLANG_ENABLE_MODULES = YES; 718 | FRAMEWORK_SEARCH_PATHS = ( 719 | "$(inherited)", 720 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 721 | ); 722 | HEADER_SEARCH_PATHS = "$(inherited)"; 723 | INFOPLIST_FILE = RRSettingsKit.xcodeproj/RRSettingsKitTests_Info.plist; 724 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 725 | LD_RUNPATH_SEARCH_PATHS = ( 726 | "$(inherited)", 727 | "@loader_path/../Frameworks", 728 | "@loader_path/Frameworks", 729 | ); 730 | MACOSX_DEPLOYMENT_TARGET = 11.0; 731 | OTHER_CFLAGS = "$(inherited)"; 732 | OTHER_LDFLAGS = "$(inherited)"; 733 | OTHER_SWIFT_FLAGS = "$(inherited)"; 734 | SDKROOT = iphoneos; 735 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 736 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 737 | SWIFT_VERSION = 5.0; 738 | TARGET_NAME = RRSettingsKitTests; 739 | TVOS_DEPLOYMENT_TARGET = 12.0; 740 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 741 | }; 742 | name = Debug; 743 | }; 744 | OBJ_39 /* Release */ = { 745 | isa = XCBuildConfiguration; 746 | buildSettings = { 747 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 748 | CLANG_ENABLE_MODULES = YES; 749 | FRAMEWORK_SEARCH_PATHS = ( 750 | "$(inherited)", 751 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 752 | ); 753 | HEADER_SEARCH_PATHS = "$(inherited)"; 754 | INFOPLIST_FILE = RRSettingsKit.xcodeproj/RRSettingsKitTests_Info.plist; 755 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 756 | LD_RUNPATH_SEARCH_PATHS = ( 757 | "$(inherited)", 758 | "@loader_path/../Frameworks", 759 | "@loader_path/Frameworks", 760 | ); 761 | MACOSX_DEPLOYMENT_TARGET = 11.0; 762 | OTHER_CFLAGS = "$(inherited)"; 763 | OTHER_LDFLAGS = "$(inherited)"; 764 | OTHER_SWIFT_FLAGS = "$(inherited)"; 765 | SDKROOT = iphoneos; 766 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 767 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 768 | SWIFT_VERSION = 5.0; 769 | TARGET_NAME = RRSettingsKitTests; 770 | TVOS_DEPLOYMENT_TARGET = 12.0; 771 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 772 | }; 773 | name = Release; 774 | }; 775 | OBJ_4 /* Release */ = { 776 | isa = XCBuildConfiguration; 777 | buildSettings = { 778 | CLANG_ENABLE_OBJC_ARC = YES; 779 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 780 | CLANG_WARN_BOOL_CONVERSION = YES; 781 | CLANG_WARN_COMMA = YES; 782 | CLANG_WARN_CONSTANT_CONVERSION = YES; 783 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 784 | CLANG_WARN_EMPTY_BODY = YES; 785 | CLANG_WARN_ENUM_CONVERSION = YES; 786 | CLANG_WARN_INFINITE_RECURSION = YES; 787 | CLANG_WARN_INT_CONVERSION = YES; 788 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 789 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 790 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 791 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 792 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 793 | CLANG_WARN_STRICT_PROTOTYPES = YES; 794 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 795 | CLANG_WARN_UNREACHABLE_CODE = YES; 796 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 797 | COMBINE_HIDPI_IMAGES = YES; 798 | COPY_PHASE_STRIP = YES; 799 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 800 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 801 | ENABLE_STRICT_OBJC_MSGSEND = YES; 802 | GCC_NO_COMMON_BLOCKS = YES; 803 | GCC_OPTIMIZATION_LEVEL = s; 804 | GCC_PREPROCESSOR_DEFINITIONS = ( 805 | "$(inherited)", 806 | "SWIFT_PACKAGE=1", 807 | ); 808 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 809 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 810 | GCC_WARN_UNDECLARED_SELECTOR = YES; 811 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 812 | GCC_WARN_UNUSED_FUNCTION = YES; 813 | GCC_WARN_UNUSED_VARIABLE = YES; 814 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 815 | MACOSX_DEPLOYMENT_TARGET = 11.0; 816 | ONLY_ACTIVE_ARCH = YES; 817 | OTHER_SWIFT_FLAGS = "$(inherited) -DXcode"; 818 | PRODUCT_NAME = "$(TARGET_NAME)"; 819 | SDKROOT = macosx; 820 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; 821 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE"; 822 | SWIFT_COMPILATION_MODE = wholemodule; 823 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 824 | USE_HEADERMAP = NO; 825 | }; 826 | name = Release; 827 | }; 828 | /* End XCBuildConfiguration section */ 829 | 830 | /* Begin XCConfigurationList section */ 831 | 0A71C4DC2533AAD000D0E65F /* Build configuration list for PBXNativeTarget "RRSettingsKitExample" */ = { 832 | isa = XCConfigurationList; 833 | buildConfigurations = ( 834 | 0A71C4DA2533AAD000D0E65F /* Debug */, 835 | 0A71C4DB2533AAD000D0E65F /* Release */, 836 | ); 837 | defaultConfigurationIsVisible = 0; 838 | defaultConfigurationName = Release; 839 | }; 840 | OBJ_19 /* Build configuration list for PBXNativeTarget "RRSettingsKit" */ = { 841 | isa = XCConfigurationList; 842 | buildConfigurations = ( 843 | OBJ_20 /* Debug */, 844 | OBJ_21 /* Release */, 845 | ); 846 | defaultConfigurationIsVisible = 0; 847 | defaultConfigurationName = Release; 848 | }; 849 | OBJ_2 /* Build configuration list for PBXProject "RRSettingsKit" */ = { 850 | isa = XCConfigurationList; 851 | buildConfigurations = ( 852 | OBJ_3 /* Debug */, 853 | OBJ_4 /* Release */, 854 | ); 855 | defaultConfigurationIsVisible = 0; 856 | defaultConfigurationName = Release; 857 | }; 858 | OBJ_26 /* Build configuration list for PBXNativeTarget "RRSettingsKitPackageDescription" */ = { 859 | isa = XCConfigurationList; 860 | buildConfigurations = ( 861 | OBJ_27 /* Debug */, 862 | OBJ_28 /* Release */, 863 | ); 864 | defaultConfigurationIsVisible = 0; 865 | defaultConfigurationName = Release; 866 | }; 867 | OBJ_32 /* Build configuration list for PBXAggregateTarget "RRSettingsKitPackageTests" */ = { 868 | isa = XCConfigurationList; 869 | buildConfigurations = ( 870 | OBJ_33 /* Debug */, 871 | OBJ_34 /* Release */, 872 | ); 873 | defaultConfigurationIsVisible = 0; 874 | defaultConfigurationName = Release; 875 | }; 876 | OBJ_37 /* Build configuration list for PBXNativeTarget "RRSettingsKitTests" */ = { 877 | isa = XCConfigurationList; 878 | buildConfigurations = ( 879 | OBJ_38 /* Debug */, 880 | OBJ_39 /* Release */, 881 | ); 882 | defaultConfigurationIsVisible = 0; 883 | defaultConfigurationName = Release; 884 | }; 885 | /* End XCConfigurationList section */ 886 | 887 | /* Begin XCRemoteSwiftPackageReference section */ 888 | 0A4320032611D42A00BF1EF9 /* XCRemoteSwiftPackageReference "RRComponentsKit" */ = { 889 | isa = XCRemoteSwiftPackageReference; 890 | repositoryURL = "https://github.com/rudrankriyam/RRComponentsKit.git"; 891 | requirement = { 892 | branch = main; 893 | kind = branch; 894 | }; 895 | }; 896 | /* End XCRemoteSwiftPackageReference section */ 897 | 898 | /* Begin XCSwiftPackageProductDependency section */ 899 | 0A43201F2611DB8200BF1EF9 /* RRComponentsKit */ = { 900 | isa = XCSwiftPackageProductDependency; 901 | package = 0A4320032611D42A00BF1EF9 /* XCRemoteSwiftPackageReference "RRComponentsKit" */; 902 | productName = RRComponentsKit; 903 | }; 904 | 0A8025BD26E3D9A5005AF372 /* RRComponentsKit */ = { 905 | isa = XCSwiftPackageProductDependency; 906 | package = 0A4320032611D42A00BF1EF9 /* XCRemoteSwiftPackageReference "RRComponentsKit" */; 907 | productName = RRComponentsKit; 908 | }; 909 | /* End XCSwiftPackageProductDependency section */ 910 | }; 911 | rootObject = OBJ_1 /* Project object */; 912 | } 913 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "RRComponentsKit", 6 | "repositoryURL": "https://github.com/rudrankriyam/RRComponentsKit.git", 7 | "state": { 8 | "branch": "main", 9 | "revision": "d8f66e7575593762f0549ee99e6907650fd58096", 10 | "version": null 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/xcshareddata/xcschemes/RRSettingsKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/xcshareddata/xcschemes/RRSettingsKitExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /RRSettingsKit.xcodeproj/xcshareddata/xcschemes/RRSettingsKitTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 37 | 38 | 44 | 45 | 47 | 48 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /RRSettingsKitExample/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /RRSettingsKitExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /RRSettingsKitExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RRSettingsKitExample/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // RRSettingsKitExample 4 | // 5 | // Created by Rudrank Riyam on 12/10/20. 6 | // 7 | 8 | import SwiftUI 9 | import RRSettingsKit 10 | 11 | struct ContentView: View { 12 | var body: some View { 13 | NavigationView { 14 | ScrollView { 15 | AboutRow(title: "💜 the game? share!", accessibilityTitle: "Love the game? share!") 16 | 17 | SettingsRow(imageName: "square.and.arrow.up", title: "Share") 18 | 19 | SettingsActionRow(imageName: "square.and.arrow.up", title: "Share") { 20 | // Add share action here 21 | } 22 | 23 | SettingsNavigationRow(imageName: "square.and.arrow.up", title: "Share", destination: ContentView()) 24 | 25 | WriteReviewRow(appURL: "https://apps.apple.com/us/app/gradient-game/id1479784361") 26 | 27 | TwitterRow(title: "Tweet about it", twitterAppURL: "twitter://user?screen_name=gradientsgame", twitterWebURL: "https://www.twitter.com/gradientsgame") 28 | 29 | AppVersionRow(version: "0.1.0") 30 | } 31 | .accentColor(.red) 32 | .navigationTitle("Settings") 33 | } 34 | } 35 | } 36 | 37 | struct ContentView_Previews: PreviewProvider { 38 | static var previews: some View { 39 | ContentView() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /RRSettingsKitExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSApplicationQueriesSchemes 6 | 7 | item 0 8 | twitter 9 | CFBundleDevelopmentRegion 10 | $(DEVELOPMENT_LANGUAGE) 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UIApplicationSceneManifest 28 | 29 | UIApplicationSupportsMultipleScenes 30 | 31 | 32 | UIApplicationSupportsIndirectInputEvents 33 | 34 | UILaunchScreen 35 | 36 | UIRequiredDeviceCapabilities 37 | 38 | armv7 39 | 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UISupportedInterfaceOrientations~ipad 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationPortraitUpsideDown 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /RRSettingsKitExample/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RRSettingsKitExample/RRSettingsKitExampleApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RRSettingsKitExampleApp.swift 3 | // RRSettingsKitExample 4 | // 5 | // Created by Rudrank Riyam on 12/10/20. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct RRSettingsKitExampleApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/RRSettingsKit/MailView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MailView.swift 3 | // MailView 4 | // 5 | // Created by Rudrank Riyam on 04/09/21. 6 | // 7 | 8 | import SwiftUI 9 | import MessageUI 10 | 11 | public struct MailRowObject { 12 | public var receiver: String 13 | public var subject: String 14 | public var body: String 15 | 16 | public init(receiver: String, subject: String, body: String) { 17 | self.receiver = receiver 18 | self.subject = subject 19 | self.body = body 20 | } 21 | } 22 | 23 | public struct MailRow: View { 24 | private var imageName: String 25 | private var title: String 26 | private var object: MailRowObject 27 | private var addOverlay: Bool 28 | 29 | @State private var showMailView = false 30 | @State private var showFailureAlert = false 31 | @State private var result: Result? = nil 32 | 33 | public init(image: String, title: String, addOverlay: Bool = true, object: MailRowObject) { 34 | self.imageName = image 35 | self.title = title 36 | self.object = object 37 | self.addOverlay = addOverlay 38 | } 39 | 40 | public var body: some View { 41 | SettingsActionRow(imageName: imageName, title: title, addOverlay: addOverlay) { 42 | if MFMailComposeViewController.canSendMail() { 43 | showMailView.toggle() 44 | } else if let emailURL = createEmailURL(to: object.receiver, subject: object.subject, body: object.body) { 45 | UIApplication.shared.open(emailURL) 46 | } else { 47 | showFailureAlert = true 48 | } 49 | } 50 | .alert(isPresented: $showFailureAlert) { 51 | Alert(title: Text("No Mail Accounts"), message: Text("Please set up a Mail account in order to send email"), dismissButton: .default(Text("OK"))) 52 | } 53 | .sheet(isPresented: $showMailView) { 54 | MailView(isShowing: $showMailView, result: $result, subject: object.subject, message: object.body, recipientEmail: object.receiver) 55 | } 56 | } 57 | 58 | private func createEmailURL(to: String, subject: String, body: String) -> URL? { 59 | let subjectEncoded = subject.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)! 60 | let bodyEncoded = body.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)! 61 | 62 | let gmailUrl = URL(string: "googlegmail://co?to=\(to)&subject=\(subjectEncoded)&body=\(bodyEncoded)") 63 | let outlookUrl = URL(string: "ms-outlook://compose?to=\(to)&subject=\(subjectEncoded)") 64 | let yahooMail = URL(string: "ymail://mail/compose?to=\(to)&subject=\(subjectEncoded)&body=\(bodyEncoded)") 65 | let sparkUrl = URL(string: "readdle-spark://compose?recipient=\(to)&subject=\(subjectEncoded)&body=\(bodyEncoded)") 66 | 67 | if let gmailUrl = gmailUrl, UIApplication.shared.canOpenURL(gmailUrl) { return gmailUrl } 68 | else if let outlookUrl = outlookUrl, UIApplication.shared.canOpenURL(outlookUrl) { return outlookUrl } 69 | else if let yahooMail = yahooMail, UIApplication.shared.canOpenURL(yahooMail){ return yahooMail } 70 | else if let sparkUrl = sparkUrl, UIApplication.shared.canOpenURL(sparkUrl) { return sparkUrl } 71 | return nil 72 | } 73 | } 74 | 75 | 76 | struct MailView: UIViewControllerRepresentable { 77 | @Binding var isShowing: Bool 78 | @Binding var result: Result? 79 | let subject: String 80 | let message: String 81 | let recipientEmail: String 82 | 83 | class Coordinator: NSObject, MFMailComposeViewControllerDelegate { 84 | @Binding var isShowing: Bool 85 | @Binding var result: Result? 86 | 87 | init(isShowing: Binding, result: Binding?>) { 88 | _isShowing = isShowing 89 | _result = result 90 | } 91 | 92 | func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { 93 | defer { isShowing = false } 94 | guard error == nil else { 95 | self.result = .failure(error!) 96 | return 97 | } 98 | self.result = .success(result) 99 | } 100 | } 101 | 102 | func makeCoordinator() -> Coordinator { 103 | return Coordinator(isShowing: $isShowing, result: $result) 104 | } 105 | 106 | func makeUIViewController(context: UIViewControllerRepresentableContext) -> MFMailComposeViewController { 107 | let mailViewController = MFMailComposeViewController() 108 | mailViewController.setToRecipients([recipientEmail]) 109 | mailViewController.setSubject(subject) 110 | mailViewController.setMessageBody(message, isHTML: false) 111 | mailViewController.mailComposeDelegate = context.coordinator 112 | return mailViewController 113 | } 114 | 115 | func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: UIViewControllerRepresentableContext) { 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /Sources/RRSettingsKit/RRSettingsKit.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | public struct AboutRow: View { 4 | private var title: String 5 | private var accessibilityTitle: String 6 | private var style: UIFont.TextStyle 7 | 8 | /// A view for about description. 9 | /// - Parameters: 10 | /// - title: The title of the row. For example, the title can be "Made with ❤️ by Rudrank Riyam". 11 | /// - accessibilityTitle: The accessibility label for the row. 12 | /// - style: The font text style. The default value is caption1. 13 | /// For example, the label can be "Made with love by Rudrank Riyam". 14 | public init(title: String, accessibilityTitle: String, style: UIFont.TextStyle = .caption1) { 15 | self.title = title 16 | self.accessibilityTitle = accessibilityTitle 17 | self.style = style 18 | } 19 | 20 | public var body: some View { 21 | Text(title.uppercased()) 22 | .font(type: .poppins, weight: .regular, style: style) 23 | .kerning(1) 24 | .multilineTextAlignment(.center) 25 | .frame(minWidth: 100, maxWidth: .infinity, alignment: .center) 26 | .accessibility(label: Text(accessibilityTitle)) 27 | .padding(.top) 28 | } 29 | } 30 | 31 | public struct TwitterRow: View { 32 | var imageName: String 33 | var title: String 34 | var twitterAppURL: String 35 | var twitterWebURL: String 36 | var addOverlay: Bool 37 | 38 | /// A view for making the user write a review of the app on the store. 39 | /// - Parameters: 40 | /// - imageName: The icon for the settings row. 41 | /// - title: The title of the settings row. 42 | /// - twitterAppURL: The deeplink to directly open in the Twitter app. 43 | /// - twitterWebURL: The link to open in the browser if the app is not available. 44 | public init(imageName: String = "textbox", title: String, twitterAppURL: String, twitterWebURL: String, addOverlay: Bool = true) { 45 | self.title = title 46 | self.imageName = imageName 47 | self.twitterAppURL = twitterAppURL 48 | self.twitterWebURL = twitterWebURL 49 | self.addOverlay = addOverlay 50 | } 51 | 52 | public var body: some View { 53 | SettingsActionRow(imageName: imageName, title: title, addOverlay: addOverlay, action: { 54 | openTwitter(appURL: twitterAppURL, webURL: twitterWebURL) 55 | }) 56 | } 57 | 58 | private func openTwitter(appURL: String, webURL: String) { 59 | if let appURL = URL(string: appURL), UIApplication.shared.canOpenURL(appURL) { 60 | UIApplication.shared.open(appURL, options: [:], completionHandler: nil) 61 | } else { 62 | guard let webURL = URL(string: webURL) else { return } 63 | UIApplication.shared.open(webURL, options: [:], completionHandler: nil) 64 | } 65 | } 66 | } 67 | 68 | public struct WriteReviewRow: View { 69 | var imageName: String 70 | var title: String 71 | var appURL: String 72 | var addOverlay: Bool 73 | 74 | /// A view for making the user write a review of the app on the store. 75 | /// - Parameters: 76 | /// - imageName: The icon for the settings row. 77 | /// - title: The title of the settings row. 78 | /// - appURL: The URL of the app. 79 | public init(imageName: String = "pencil.and.outline", title: String = "Write a review", appURL: String, addOverlay: Bool = true) { 80 | self.title = title 81 | self.imageName = imageName 82 | self.appURL = appURL 83 | self.addOverlay = addOverlay 84 | } 85 | 86 | public var body: some View { 87 | SettingsActionRow(imageName: imageName, title: title, addOverlay: addOverlay, action: { 88 | writeReview(appURL: appURL) 89 | }) 90 | } 91 | 92 | private func writeReview(appURL: String) { 93 | guard let url = URL(string: appURL) else { return } 94 | var components = URLComponents(url: url, resolvingAgainstBaseURL: false) 95 | components?.queryItems = [URLQueryItem(name: "action", value: "write-review")] 96 | guard let writeReviewURL = components?.url else { return } 97 | UIApplication.shared.open(writeReviewURL) 98 | } 99 | } 100 | 101 | public struct AppVersionRow: View { 102 | var imageName: String = "info.circle" 103 | var title: String = "App version" 104 | var version: String 105 | var addOverlay: Bool 106 | 107 | /// The row which tells the user the app version of your application 108 | /// - Parameters: 109 | /// - imageName: The icon for the app version row. The default is `info.circle`. 110 | /// - title: The tile for the app version row. The default is `App version`. 111 | /// - version: The version of your app. 112 | public init(imageName: String = "info.circle", title: String = "App version", version: String, addOverlay: Bool = true) { 113 | self.imageName = imageName 114 | self.title = title 115 | self.version = version 116 | self.addOverlay = addOverlay 117 | } 118 | 119 | public var body: some View { 120 | HStack(spacing: 8) { 121 | Image(systemName: imageName) 122 | .customIconImage() 123 | 124 | Text(title) 125 | .font(type: .poppins, weight: .regular, style: .body) 126 | 127 | Spacer() 128 | 129 | Text(version) 130 | .font(type: .poppins, weight: .bold, style: .body) 131 | } 132 | .accessibilityElement(children: .combine) 133 | .padding(.vertical, 12) 134 | .settingsBackground(addOverlay: addOverlay) 135 | } 136 | } 137 | 138 | public struct SettingsToggleRow: View { 139 | private var imageName: String 140 | private var title: String 141 | private var addOverlay: Bool 142 | @Binding var value: Bool 143 | 144 | /// A generic settings row which can be customised according to your needs. 145 | /// - Parameters: 146 | /// - imageName: The icon for the settings row. 147 | /// - title: The title of the settings row. 148 | public init(imageName: String, title: String, value: Binding, addOverlay: Bool = true) { 149 | self.imageName = imageName 150 | self.title = title 151 | self.addOverlay = addOverlay 152 | self._value = value 153 | } 154 | 155 | public var body: some View { 156 | Toggle(isOn: $value) { 157 | Image(systemName: imageName) 158 | .font(.headline) 159 | .frame(minWidth: 25, alignment: .leading) 160 | .accessibility(hidden: true) 161 | 162 | Text(title) 163 | .font(type: .poppins, weight: .regular, style: .body) 164 | } 165 | .padding(.vertical, 12) 166 | .toggleStyle(SwitchToggleStyle(tint: .accentColor)) 167 | .settingsBackground(addOverlay: addOverlay) 168 | } 169 | } 170 | 171 | extension View { 172 | func customIconImage() -> some View { 173 | self 174 | .font(.headline) 175 | .frame(minWidth: 25, alignment: .leading) 176 | .accessibility(hidden: true) 177 | } 178 | 179 | func settingsBackground(cornerRadius: CGFloat = 16, innerPadding: CGFloat = 8, outerBottomPadding: CGFloat = 6, addOverlay: Bool = true) -> some View { 180 | let gradient = Gradient(colors: [.accentColor, .accentColor.opacity(0.5)]) 181 | 182 | return self 183 | .foregroundColor(.accentColor) 184 | .frame(maxWidth: .infinity, alignment: .center) 185 | .padding(.horizontal) 186 | .padding(.vertical, innerPadding) 187 | .contentShape(Rectangle()) 188 | .overlay(addOverlay ? RoundedRectangle(cornerRadius: cornerRadius) 189 | .stroke(LinearGradient(gradient: gradient, startPoint: .top, endPoint: .bottom), lineWidth: 1) : nil) 190 | .padding(.bottom, outerBottomPadding) 191 | .padding(.horizontal) 192 | } 193 | } 194 | 195 | struct CustomImageModifier: ViewModifier { 196 | public func body(content: Content) -> some View { 197 | content 198 | .font(.headline) 199 | .frame(minWidth: 25, alignment: .leading) 200 | .accessibility(hidden: true) 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /Sources/RRSettingsKit/SettingsRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsRow.swift 3 | // RRSettingsKit 4 | // 5 | // Created by Rudrank Riyam on 29/03/21. 6 | // 7 | 8 | import SwiftUI 9 | import RRComponentsKit 10 | 11 | public struct SettingsNavigationRow: View { 12 | private var imageName: String 13 | private var title: String 14 | private var destination: Destination 15 | private var addOverlay: Bool 16 | 17 | /// A generic settings row which can be customised according to your needs. 18 | /// - Parameters: 19 | /// - imageName: The icon for the settings row. 20 | /// - title: The title of the settings row. 21 | /// - destination: The view to navigate to, after tapping the row. 22 | /// - addOverlay: Add overlay to the border of the row. 23 | public init(imageName: String, title: String, addOverlay: Bool = true, destination: Destination) { 24 | self.imageName = imageName 25 | self.title = title 26 | self.destination = destination 27 | self.addOverlay = addOverlay 28 | } 29 | 30 | public var body: some View { 31 | NavigationLink(destination: destination) { 32 | SettingsRow(imageName: imageName, title: title, addOverlay: addOverlay) 33 | } 34 | .buttonStyle(PlainButtonStyle()) 35 | } 36 | } 37 | 38 | public struct SettingsActionRow: View { 39 | private var imageName: String 40 | private var title: String 41 | private var action: () -> () 42 | private var addOverlay: Bool 43 | 44 | /// A generic settings row which can be customised according to your needs. 45 | /// - Parameters: 46 | /// - imageName: The icon for the settings row. 47 | /// - title: The title of the settings row. 48 | /// - action: The custom action that you want to perform on tapping the row. 49 | /// - addOverlay: Add overlay to the border of the row. 50 | public init(imageName: String, title: String, addOverlay: Bool = true, action: @escaping () -> ()) { 51 | self.imageName = imageName 52 | self.title = title 53 | self.action = action 54 | self.addOverlay = addOverlay 55 | } 56 | 57 | public var body: some View { 58 | Button(action: action) { 59 | SettingsRow(imageName: imageName, title: title, addOverlay: addOverlay) 60 | } 61 | .buttonStyle(PlainButtonStyle()) 62 | } 63 | } 64 | 65 | public struct SettingsRow: View { 66 | private var imageName: String 67 | private var title: String 68 | private var showDisclosure: Bool 69 | private var addOverlay: Bool 70 | 71 | /// A generic settings row which can be customised according to your needs. 72 | /// - Parameters: 73 | /// - imageName: The icon for the settings row. 74 | /// - title: The title of the settings row. 75 | /// - showDisclosure: Show disclosure icon for action or navigation. 76 | public init(imageName: String, title: String, addOverlay: Bool = true, showDisclosure: Bool = true) { 77 | self.imageName = imageName 78 | self.title = title 79 | self.showDisclosure = showDisclosure 80 | self.addOverlay = addOverlay 81 | } 82 | 83 | public var body: some View { 84 | HStack(spacing: 8) { 85 | Image(systemName: imageName) 86 | .customIconImage() 87 | 88 | Text(title) 89 | .font(type: .poppins, weight: .regular, style: .body) 90 | 91 | Spacer() 92 | 93 | if showDisclosure { 94 | Image(systemName: "chevron.right") 95 | } 96 | } 97 | .padding(.vertical, 12) 98 | .settingsBackground(addOverlay: addOverlay) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import RRSettingsKitTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += RRSettingsKitTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Tests/RRSettingsKitTests/RRSettingsKitTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftUI 3 | @testable import RRSettingsKit 4 | 5 | final class RRSettingsKitTests: XCTestCase { 6 | func testExample() { 7 | var body: some View { 8 | ScrollView { 9 | RRSettingsKit.AboutRow(title: "Made with ❤️ by Rudrank Riyam", accessibilityTitle: "Made with love by Rudrank Riyam") 10 | } 11 | } 12 | } 13 | static var allTests = [ 14 | ("testExample", testExample), 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /Tests/RRSettingsKitTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(RRSettingsKitTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /codemagic.yaml: -------------------------------------------------------------------------------- 1 | definitions: 2 | triggering: 3 | push: &events 4 | events: 5 | - push 6 | - pull_request 7 | scripts: 8 | - &buildFramework 9 | name: Build Framework 10 | script: | 11 | xcodebuild clean build \ 12 | -scheme $XCODE_SCHEME \ 13 | -destination "$DESTINATION" \ 14 | -skipPackagePluginValidation 15 | 16 | workflows: 17 | rrsettingskit: 18 | name: RRSettingsKit Workflow 19 | instance_type: mac_mini_m1 20 | environment: 21 | xcode: 14.2 22 | vars: 23 | XCODE_SCHEME: RRSettingsKit 24 | DESTINATION: "platform=iOS Simulator,name=iPhone 14" 25 | triggering: 26 | <<: *events 27 | scripts: 28 | - *buildFramework 29 | --------------------------------------------------------------------------------