Config
Config is a framework written in Swift that makes it easy for you to use JSON file as a configuration, with JSON keys in dot notation in your application. Also supports SwiftUI!
Table of contents
Requirements
- iOS 15.0
- Xcode 13.1
- Swift 5.5
Integration
Swift Package Manager
- In Xcode, open
File > Add Packages
. - Search https://github.com/mustafakarakus/Config.git
- Config should be listed. Click
Add Package
CocoaPods
You can use CocoaPods to install Config by adding it to your Podfile:
use_frameworks!
target 'MyApp' do
pod 'Config'
end
Usage
Create a desired config file in JSON format in your Xcode project or use a web url that returns a JSON
{
"development": {
"debug": true
},
"application": {
"type":5,
"version":1.2,
"appKey":"ABCD-EFGH-IJKLMNOPR",
"security":{
"OAuth2":{
"credentials":{
"username":"mustafakarakus",
"password":"password"
},
"groups":[1,9,0,5],
"chain":false
},
"domainExceptions":[
"https://www.google.com",
"https://www.twitter.com"
]
}
}
}
You have 3 options to read your JSON values, Choose the best way for you
- Instance
- Property Wrapper
- Pattern Matching
Instance
- Initialize Config with the JSON file that exists in your directories. Or Use a JSON URL while initializing.
Local File
Add my-config.json
file in the desired project directory
let config = Config(with: "my-config")
Remote File
Use a URL for your JSON file that exists on remote.
let config = Config(with: "https://raw.githubusercontent.com/mustafakarakus/Config/master/ConfigExamples/config.json")
- Type your JSON keys with dot notation that described in JSON file. Last thing is call .value() function. value() function is type inferred. That means you need to specify your data type in your variable/constant.
let myIntegerValue:Int = config.myKey.myIntegerValue.value()
if let development:[String:Any] = config.development.value(){
print(development)
}
Examples
import Config
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let config = Config(with: "my-config")
if let development:[String:Any] = config.development.value() {
print(development)
}
if let debug:Bool = config.development.debug.value(){
print(debug)
}
if let application:[String:Any] = config.application.value(){
print(application)
}
if let version:Double = config.application.version.value(){
print(version)
}
if let applicationType:Int = config.application.type.value(){
print(applicationType)
}
if let appKey:String = config.application.appKey.value(){
print(appKey)
}
if let username:String = config.application.security.OAuth2.credentials.username.value(){
print(username)
}
if let groups:[Int] = config.application.security.OAuth2.groups.value(){
print(groups)
}
if let domainExceptions:[String] = config.application.security.domainExceptions.value(){
print(domainExceptions)
}
}
}
JSONValue Property Wrapper
- Mark your variable with Local JSON file name; @JSONValue("my-json-file-name", "JSONKey")
or
- Mark your variable with Remote JSON URL; @JSONValue("http://www.mydomain.com/files/my-config.json", "JSONKey")
In this case 'application.security.OAuth2.groups' data type is an Int array in 'my-config.json' file (read the sample JSON file above)
@JSONValue("my-config", "application.security.OAuth2.groups")
var groups: [Int] = []
@JSONValue(url: "https://raw.githubusercontent.com/mustafakarakus/Config/master/ConfigExamples/config.json", "application.appKey")
var appKey: String = ""
Examples
import Config
class PropertyWrapperViewController: UIViewController {
@JSONValue("my-config", "application.security.OAuth2.groups")
var groups: [Int] = []
@JSONValue("my-config1", "development")
var development: [String:Any] = [:]
@JSONValue("my-config", "development.debug")
var isDebug: Bool = false
@JSONValue("my-config", "application.security.OAuth2.credentials.username")
var username: String = ""
@JSONValue(url: "https://raw.githubusercontent.com/mustafakarakus/Config/master/ConfigExamples/config.json", "application.appKey")
var appKey: String = ""
override func viewDidLoad() {
super.viewDidLoad()
print("groups: \(groups)")
print("development: \(development)")
print("debug mode: \(isDebug)")
print("OAuth2 username: \(username)")
print("App Key: \(appKey)")
}
}
Pattern Matching
- Create an instance of Config then type your JSON keys with dot notation that described in JSON file.
- Use Swift's Pattern matching power with the following cases
.string(val)
.int(val)
.double(val)
.bool(val)
.object(val)
.array(val)
private var config: Config? {
let sampleUrl = "https://raw.githubusercontent.com/mustafakarakus/Config/master/ConfigExamples/config.json"
guard let url = URL(string: sampleUrl) else { return nil }
return Config(with: url)
}
let string = config?.application.appKey
if case let .string(val) = string {
print("app Key \(val)")
}
Examples
import Config
class PatternMatchingViewController: UIViewController {
private var config: Config? {
let sampleUrl = "https://raw.githubusercontent.com/mustafakarakus/Config/master/ConfigExamples/config.json"
guard let url = URL(string: sampleUrl) else { return nil }
return Config(with: url)
}
override func viewDidLoad() {
super.viewDidLoad()
let string = config?.application.appKey
if case let .string(val) = string {
print("app Key \(val)")
}
let double = config?.application.version
if case let .double(val) = double {
print("version: \(val)")
}
let intArray = config?.application.security.OAuth2.groups
if case let .array(val) = intArray {
for item in val {
print("groups: \(String(describing: item.intValue))")
}
}
let dictionary = config?.application
if case let .object(val) = dictionary {
print("application: \(val)")
}
}
}
SwiftUI
Config now supports SwiftUI. Using the JSONValue Property Wrapper in the SwiftUI variable will bind the data from your JSON source, local or remote.
import SwiftUI
import Config
struct ContentViewLocal: View {
@JSONValue("my-config", "application.security.OAuth2.credentials.username")
var name: String = ""
var body: some View {
Text(name)
.padding()
}
}
import SwiftUI
import Config
struct ContentViewRemote: View {
@JSONValue(url: "https://raw.githubusercontent.com/mustafakarakus/Config/master/ConfigExamples/config.json", "application.appKey")
var appKey: String = ""
var body: some View {
Text(appKey)
.padding()
}
}
What is next?
- Carthage
- Swift Package Manager
- Remote JSON
- Swift 5.x
- Property Wrappers
- Use instance instead of Singleton
- SwiftUI
Contribution
Anyone who would like to contribute to the project is more than welcome.
- Fork this repo
- Make your changes
- Submit pull request
License
MIT License
Copyright (c) 2021 mustafakarakus
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.