How do I get a plist as a Dictionary in Swift?

IosSwift

Ios Problem Overview


I am playing around with Apple's new Swift programming language and have some problems...

Currently I'm trying to read a plist file, in Objective-C I would do the following to get the content as a NSDictionary:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];

How do I get a plist as a Dictionary in Swift?

I assume I can get the path to the plist with:

let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")

When this works (If it's correct?): How do I get the content as a Dictionary?

Also a more general question:

Is it OK to use the default NS* classes? I think so...or am I missing something? As far as I know the default framework NS* classes are still valid and alright to use?

Ios Solutions


Solution 1 - Ios

You can still use NSDictionaries in Swift:

For Swift 4

 var nsDictionary: NSDictionary?
 if let path = Bundle.main.path(forResource: "Config", ofType: "plist") {
    nsDictionary = NSDictionary(contentsOfFile: path)
 }

For Swift 3+

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
   let myDict = NSDictionary(contentsOfFile: path){
    // Use your myDict here
}

And older versions of Swift

var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
    myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
    // Use your dict here
}

The NSClasses are still available and perfectly fine to use in Swift. I think they'll probably want to shift focus to swift soon, but currently the swift APIs don't have all the functionality of the core NSClasses.

Solution 2 - Ios

This is what I do if I want to convert a .plist to a Swift dictionary:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
  if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
    // use swift dictionary as normal
  }
}

Edited for Swift 2.0:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
    // use swift dictionary as normal
}

Edited for Swift 3.0:

if let path = Bundle.main.path(forResource: "Config", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
        // use swift dictionary as normal
}

Solution 3 - Ios

Swift 4.0

You can now use the Decodable protocol to Decode a .plist into a custom struct. I will go over a basic example, for more complicated .plist structures I recommend reading up on Decodable/Encodable (a good resource is here: https://benscheirman.com/2017/06/swift-json/).

First setup your struct into the format of your .plist file. For this example I will consider a .plist with a root level Dictionary and 3 entries: 1 String with key "name", 1 Int with key "age", and 1 Boolean with key "single". Here is the struct:

struct Config: Decodable {
    private enum CodingKeys: String, CodingKey {
        case name, age, single
    }

    let name: String
    let age: Int
    let single: Bool
}

Simple enough. Now the cool part. Using the PropertyListDecoder class we can easily parse the .plist file into an instantiation of this struct:

func parseConfig() -> Config {
    let url = Bundle.main.url(forResource: "Config", withExtension: "plist")!
    let data = try! Data(contentsOf: url)
    let decoder = PropertyListDecoder()
    return try! decoder.decode(Config.self, from: data)
}

Not much more code to worry about, and its all in Swift. Better yet we now have an instantiation of the Config struct that we can easily use:

let config = parseConfig()
print(config.name) 
print(config.age)
print(config.single) 

This Prints the value for the "name", "age", and "single" keys in the .plist.

Solution 4 - Ios

In swift 3.0 Reading from Plist.

func readPropertyList() {
        var propertyListFormat =  PropertyListSerialization.PropertyListFormat.xml //Format of the Property List.
        var plistData: [String: AnyObject] = [:] //Our data
        let plistPath: String? = Bundle.main.path(forResource: "data", ofType: "plist")! //the path of the data
        let plistXML = FileManager.default.contents(atPath: plistPath!)!
        do {//convert the data to a dictionary and handle errors.
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as! [String:AnyObject]
            
        } catch {
            print("Error reading plist: \(error), format: \(propertyListFormat)")
        }
    }

Read More HOW TO USE PROPERTY LISTS (.PLIST) IN SWIFT.

Solution 5 - Ios

This answer uses Swift native objects rather than NSDictionary.

Swift 3.0

//get the path of the plist file
guard let plistPath = Bundle.main.path(forResource: "level1", ofType: "plist") else { return }
//load the plist as data in memory
guard let plistData = FileManager.default.contents(atPath: plistPath) else { return }
//use the format of a property list (xml)
var format = PropertyListSerialization.PropertyListFormat.xml
//convert the plist data to a Swift Dictionary
guard let  plistDict = try! PropertyListSerialization.propertyList(from: plistData, options: .mutableContainersAndLeaves, format: &format) as? [String : AnyObject] else { return }
//access the values in the dictionary 
if let value = plistDict["aKey"] as? String {
  //do something with your value
  print(value)
}
//you can also use the coalesce operator to handle possible nil values
var myValue = plistDict["aKey"] ?? ""

Solution 6 - Ios

I have been working with Swift 3.0 and wanted to contribute an answer for the updated syntax. Additionally, and possibly more importantly, I am using the PropertyListSerialization object to do the heavy lifting, which is a lot more flexible than just using the NSDictionary as it allows for an Array as the root type of the plist.

Below is a screenshot of the plist I am using. It is a little complicated, so as to show the power available, but this will work for any allowable combination of plist types.

[![Sample plist file][1]][1] [1]: http://i.stack.imgur.com/Ydffw.png

As you can see I am using an Array of String:String dictionaries to store a list of website names and their corresponding URL.

I am using the PropertyListSerialization object, as mentioned above, to do the heavy lifting for me. Additionally, Swift 3.0 has become more "Swifty" so all of the object names have lost the "NS" prefix.

let path = Bundle.main().pathForResource("DefaultSiteList", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let data = try! Data(contentsOf: url)
let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)

After the above code runs plist will be of type Array<AnyObject>, but we know what type it really is so we can cast it to the correct type:

let dictArray = plist as! [[String:String]]
// [[String:String]] is equivalent to Array< Dictionary<String, String> >

And now we can access the various properties of our Array of String:String Dictionaries in a natural way. Hopefully to convert them into actual strongly typed structs or classes ;)

print(dictArray[0]["Name"])

Solution 7 - Ios

Swift 5

If you want to fetch specific value for some key then we can use below extension which uses infoDictionary property on Bundle.

Bundle.main.infoDictionary can be used to get all info.plist values in the form dictionary and so we can directly query using object(forInfoDictionaryKey: key) method on Bundle

extension Bundle {
    static func infoPlistValue(forKey key: String) -> Any? {
        guard let value = Bundle.main.object(forInfoDictionaryKey: key) else {
           return nil
        }
        return value
    }
}

Usage

guard let apiURL = Bundle.infoPlistValue(forKey: "API_URL_KEY") as? String else { return }

Solution 8 - Ios

It is best to use native dictionaries and arrays because they have been optimized for use with swift. That being said you can use NS... classes in swift and I think this situation warrants that. Here is how you would implement it:

var path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")
var dict = NSDictionary(contentsOfFile: path)

So far (in my opinion) this is the easiest and most efficient way to access a plist, but in the future I expect that apple will add more functionality (such as using plist) into native dictionaries.

Solution 9 - Ios

Swift - Read/Write plist and text file....

override func viewDidLoad() {
    super.viewDidLoad()
    
    let fileManager = (NSFileManager .defaultManager())
    let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]
    
    if (directorys != nil){
        let directories:[String] = directorys!;
        let dictionary = directories[0]; //documents directory
        
        
        //  Create and insert the data into the Plist file  ....
        let plistfile = "myPlist.plist"
        var myDictionary: NSMutableDictionary = ["Content": "This is a sample Plist file ........."]
        let plistpath = dictionary.stringByAppendingPathComponent(plistfile);
        
        if !fileManager .fileExistsAtPath(plistpath){//writing Plist file
            myDictionary.writeToFile(plistpath, atomically: false)
        }
        else{            //Reading Plist file
            println("Plist file found")
            
            let resultDictionary = NSMutableDictionary(contentsOfFile: plistpath)
            println(resultDictionary?.description)
        }
        
        
        //  Create and insert the data into the Text file  ....
        let textfile = "myText.txt"
        let sampleText = "This is a sample text file ......... "
        
        let textpath = dictionary.stringByAppendingPathComponent(textfile);
        if !fileManager .fileExistsAtPath(textpath){//writing text file
            sampleText.writeToFile(textpath, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
        } else{
            //Reading text file
            let reulttext  = String(contentsOfFile: textpath, encoding: NSUTF8StringEncoding, error: nil)
            println(reulttext)
        }
    }
    else {
        println("directory is empty")
    }
}

Solution 10 - Ios

Swift 2.0 : Accessing Info.Plist

I have a Dictionary named CoachMarksDictionary with a boolean value in Info.Plist . I want to access the bool value and make it true.

let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  if let CoachMarksDict = dict["CoachMarksDictionary"] {
       print("Info.plist : \(CoachMarksDict)")

   var dashC = CoachMarksDict["DashBoardCompleted"] as! Bool
    print("DashBoardCompleted state :\(dashC) ")
  }

Writing To Plist:

From a Custom Plist:- (Make from File-New-File-Resource-PropertyList. Added three strings named : DashBoard_New, DashBoard_Draft, DashBoard_Completed)

func writeToCoachMarksPlist(status:String?,keyName:String?)
 {
  let path1 = NSBundle.mainBundle().pathForResource("CoachMarks", ofType: "plist")
  let coachMarksDICT = NSMutableDictionary(contentsOfFile: path1!)! as NSMutableDictionary
  var coachMarksMine = coachMarksDICT.objectForKey(keyName!)

  coachMarksMine  = status
  coachMarksDICT.setValue(status, forKey: keyName!)
  coachMarksDICT.writeToFile(path1!, atomically: true)
 }

The method can be called as

self.writeToCoachMarksPlist(" true - means user has checked the marks",keyName: "the key in the CoachMarks dictionary").

Solution 11 - Ios

Converted into a convenience extension via Nick's answer:

extension Dictionary {
	static func contentsOf(path: URL) -> Dictionary<String, AnyObject> {
		let data = try! Data(contentsOf: path)
		let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)
		
		return plist as! [String: AnyObject]
	}
}

usage:

let path = Bundle.main.path(forResource: "plistName", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let dict = Dictionary<String, AnyObject>.contentsOf(path: url)

I'd be willing to bet that it would also work to create a similar extension for Arrays

Solution 12 - Ios

Since this answer isn't here yet, just wanted to point out you can also use the infoDictionary property to get the info plist as a dictionary, Bundle.main.infoDictionary.

Although something like Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) may be faster if you're only interested in a specific item in the info plist.

// Swift 4

// Getting info plist as a dictionary
let dictionary = Bundle.main.infoDictionary

// Getting the app display name from the info plist
Bundle.main.infoDictionary?[kCFBundleNameKey as String]

// Getting the app display name from the info plist (another way)
Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String)

Solution 13 - Ios

can actually do it in 1 line

    var dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Config", ofType: "plist"))

Solution 14 - Ios

You can read plist in SWIFT Language in this way:

let path = NSBundle.mainBundle().pathForResource("PriceList", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)

Read Single Dictionary value:

let test: AnyObject = dict.objectForKey("index1")

If you want to get full multi-dimensional dictionary in plist:

let value: AnyObject = dict.objectForKey("index2").objectForKey("date")

Here is the plist:

<plist version="1.0">
<dict>
<key>index2</key>
<dict>
	<key>date</key>
	<string>20140610</string>
	<key>amount</key>
	<string>110</string>
</dict>
<key>index1</key>
<dict>
	<key>amount</key>
	<string>125</string>
	<key>date</key>
	<string>20140212</string>
</dict>
</dict>
</plist>

Solution 15 - Ios

in my case I create a NSDictionary called appSettings and add all needed keys. For this case, the solution is:

if let dict = NSBundle.mainBundle().objectForInfoDictionaryKey("appSettings") {
  if let configAppToken = dict["myKeyInsideAppSettings"] as? String {

  }
}

Solution 16 - Ios

Step 1 : Simple and fastest way to parse plist in swift 3+

extension Bundle {
    
    func parsePlist(ofName name: String) -> [String: AnyObject]? {
        
        // check if plist data available
        guard let plistURL = Bundle.main.url(forResource: name, withExtension: "plist"),
            let data = try? Data(contentsOf: plistURL)
            else {
                return nil
        }
        
        // parse plist into [String: Anyobject]
        guard let plistDictionary = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: AnyObject] else {
            return nil
        }
        
        return plistDictionary
    }
}

Step 2: How to use:

Bundle().parsePlist(ofName: "Your-Plist-Name")

Solution 17 - Ios

You can use that, I create a simple extension for Dictionary in github https://github.com/DaRkD0G/LoadExtension

extension Dictionary {
    /**
        Load a Plist file from the app bundle into a new dictionary
    
        :param: File name
        :return: Dictionary<String, AnyObject>?
    */
    static func loadPlistFromProject(filename: String) -> Dictionary<String, AnyObject>? {

        if let path = NSBundle.mainBundle().pathForResource("GameParam", ofType: "plist") {
            return NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject>
        }
        println("Could not find file: \(filename)")
        return nil
    }
}

And you can use that for load

/**
  Example function for load Files Plist

  :param: Name File Plist
*/
func loadPlist(filename: String) -> ExampleClass? {
    if let dictionary = Dictionary<String, AnyObject>.loadPlistFromProject(filename) {
        let stringValue = (dictionary["name"] as NSString)
        let intergerValue = (dictionary["score"] as NSString).integerValue
        let doubleValue = (dictionary["transition"] as NSString).doubleValue

        return ExampleClass(stringValue: stringValue, intergerValue: intergerValue, doubleValue: doubleValue)
    }
    return nil
}

Solution 18 - Ios

Here is a bit shorter version, based on @connor 's answer

guard let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
    let myDict = NSDictionary(contentsOfFile: path) else {
    return nil
}
    
let value = dict.value(forKey: "CLIENT_ID") as! String?

Solution 19 - Ios

Swift 3.0

if let path = Bundle.main.path(forResource: "config", ofType: "plist") {
    let dict = NSDictionary(contentsOfFile: path)
                
    // use dictionary
}

The easiest way to do this in my opinion.

Solution 20 - Ios

I've created a simple Dictionary initializer that replaces NSDictionary(contentsOfFile: path). Just remove the NS.

extension Dictionary where Key == String, Value == Any {
    
    public init?(contentsOfFile path: String) {
        let url = URL(fileURLWithPath: path)
        
        self.init(contentsOfURL: url)
    }
    
    public init?(contentsOfURL url: URL) {
        guard let data = try? Data(contentsOf: url),
            let dictionary = (try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any]) ?? nil
            else { return nil }
        
        self = dictionary
    }
    
}

You can use it like so:

let filePath = Bundle.main.path(forResource: "Preferences", ofType: "plist")!
let preferences = Dictionary(contentsOfFile: filePath)!
UserDefaults.standard.register(defaults: preferences)

Solution 21 - Ios

Swift 4.0 iOS 11.2.6 list parsed and code to parse it, based on https://stackoverflow.com/users/3647770/ashok-r answer above.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
  <dict>
	<key>identity</key>
	<string>blah-1</string>
	<key>major</key>
	<string>1</string>
	<key>minor</key>
	<string>1</string>
	<key>uuid</key>
	<string>f45321</string>
	<key>web</key>
	<string>http://web</string>
</dict>
<dict>
	<key>identity</key>
	<string></string>
	<key>major</key>
	<string></string>
	<key>minor</key>
	<string></string>
	<key>uuid</key>
	<string></string>
	<key>web</key>
	<string></string>
  </dict>
</array>
</plist>

do {
   let plistXML = try Data(contentsOf: url)
    var plistData: [[String: AnyObject]] = [[:]]
    var propertyListFormat =  PropertyListSerialization.PropertyListFormat.xml
        do {
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as! [[String:AnyObject]]
        
        } catch {
            print("Error reading plist: \(error), format: \(propertyListFormat)")
        }
    } catch {
        print("error no upload")
    }

Solution 22 - Ios

Here's the solution I found:

let levelBlocks = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("LevelBlocks", ofType: "plist"))
let test: AnyObject = levelBlocks.objectForKey("Level1")
println(test) // Prints the value of test

I set the type of test to AnyObject to silence a warning about an unexpected inference that could occur.

Also, it has to be done in a class method.

To access and save a specific value of a known type:

let value = levelBlocks.objectForKey("Level1").objectForKey("amount") as Int
println(toString(value)) // Converts value to String and prints it

Solution 23 - Ios

I use swift dictionaries but convert them to and from NSDictionaries in my file manager class like so:

    func writePlist(fileName:String, myDict:Dictionary<String, AnyObject>){
        let docsDir:String = dirPaths[0] as String
        let docPath = docsDir + "/" + fileName
        let thisDict = myDict as NSDictionary
        if(thisDict.writeToFile(docPath, atomically: true)){
            NSLog("success")
        } else {
            NSLog("failure")
        }
        
    }
    func getPlist(fileName:String)->Dictionary<String, AnyObject>{
        let docsDir:String = dirPaths[0] as String
        let docPath = docsDir + "/" + fileName
        let thisDict = NSDictionary(contentsOfFile: docPath)
        return thisDict! as! Dictionary<String, AnyObject>
    }

This seems the least troubling way to read and write but let's the rest of my code stay as swift as possible.

Solution 24 - Ios

Plist is a simple Swift enum I made for working with property lists.

// load an applications info.plist data

let info = Plist(NSBundle.mainBundle().infoDictionary)
let identifier = info["CFBundleIndentifier"].string!

More examples:

import Plist

// initialize using an NSDictionary
// and retrieve keyed values

let info = Plist(dict)
let name = info["name"].string ?? ""
let age = info["age"].int ?? 0


// initialize using an NSArray
// and retrieve indexed values

let info = Plist(array)
let itemAtIndex0 = info[0].value


// utility initiaizer to load a plist file at specified path
let info = Plist(path: "path_to_plist_file")

// we support index chaining - you can get to a dictionary from an array via
// a dictionary and so on
// don't worry, the following will not fail with errors in case
// the index path is invalid
if let complicatedAccessOfSomeStringValueOfInterest = info["dictKey"][10]["anotherKey"].string {
  // do something
}
else {
  // data cannot be indexed
}

// you can also re-use parts of a plist data structure

let info = Plist(...)
let firstSection = info["Sections"][0]["SectionData"]
let sectionKey = firstSection["key"].string!
let sectionSecret = firstSection["secret"].int!

Plist.swift

Plist itself is quite simple, here's its listing in case you to refer directly.

//
//  Plist.swift
//


import Foundation


public enum Plist {
    
    case dictionary(NSDictionary)
    case Array(NSArray)
    case Value(Any)
    case none
    
    public init(_ dict: NSDictionary) {
        self = .dictionary(dict)
    }
    
    public init(_ array: NSArray) {
        self = .Array(array)
    }
    
    public init(_ value: Any?) {
        self = Plist.wrap(value)
    }
    
}


// MARK:- initialize from a path

extension Plist {
    
    public init(path: String) {
        if let dict = NSDictionary(contentsOfFile: path) {
            self = .dictionary(dict)
        }
        else if let array = NSArray(contentsOfFile: path) {
            self = .Array(array)
        }
        else {
            self = .none
        }
    }
    
}


// MARK:- private helpers

extension Plist {
    
    /// wraps a given object to a Plist
    fileprivate static func wrap(_ object: Any?) -> Plist {
        
        if let dict = object as? NSDictionary {
            return .dictionary(dict)
        }
        if let array = object as? NSArray {
            return .Array(array)
        }
        if let value = object {
            return .Value(value)
        }
        return .none
    }
    
    /// tries to cast to an optional T
    fileprivate func cast<T>() -> T? {
        switch self {
        case let .Value(value):
            return value as? T
        default:
            return nil
        }
    }
}

// MARK:- subscripting

extension Plist {
    
    /// index a dictionary
    public subscript(key: String) -> Plist {
        switch self {
            
        case let .dictionary(dict):
            let v = dict.object(forKey: key)
            return Plist.wrap(v)
            
        default:
            return .none
        }
    }
    
    /// index an array
    public subscript(index: Int) -> Plist {
        switch self {
        case let .Array(array):
            if index >= 0 && index < array.count {
                return Plist.wrap(array[index])
            }
            return .none
            
        default:
            return .none
        }
    }
    
}


// MARK:- Value extraction

extension Plist {
    
    public var string: String?       { return cast() }
    public var int: Int?             { return cast() }
    public var double: Double?       { return cast() }
    public var float: Float?         { return cast() }
    public var date: Date?         { return cast() }
    public var data: Data?         { return cast() }
    public var number: NSNumber?     { return cast() }
    public var bool: Bool?           { return cast() }
    
    
    // unwraps and returns the underlying value
    public var value: Any? {
        switch self {
        case let .Value(value):
            return value
        case let .dictionary(dict):
            return dict
        case let .Array(array):
            return array
        case .none:
            return nil
        }
    }
    
    // returns the underlying array
    public var array: NSArray? {
        switch self {
        case let .Array(array):
            return array
        default:
            return nil
        }
    }
    
    // returns the underlying dictionary
    public var dict: NSDictionary? {
        switch self {
        case let .dictionary(dict):
            return dict
        default:
            return nil
        }
    }
    
}


// MARK:- CustomStringConvertible

extension Plist : CustomStringConvertible {
    public var description:String {
        switch self {
        case let .Array(array): return "(array \(array))"
        case let .dictionary(dict): return "(dict \(dict))"
        case let .Value(value): return "(value \(value))"
        case .none: return "(none)"
        }
    }
}

Solution 25 - Ios

Swift 3.0

if you want to read a "2-dimensional Array" from .plist, you can try it like this:

if let path = Bundle.main.path(forResource: "Info", ofType: "plist") {
    if let dimension1 = NSDictionary(contentsOfFile: path) {
        if let dimension2 = dimension1["key"] as? [String] {
            destination_array = dimension2
        }
    }
}

Solution 26 - Ios

If you have Info.plist, then use

Bundle.main.infoDictionary

Solution 27 - Ios

Simple struct to access plist file (Swift 2.0)

struct Configuration {      
  static let path = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")!
  static let dict = NSDictionary(contentsOfFile: path) as! [String: AnyObject]

  static let someValue = dict["someKey"] as! String
}

Usage:

print("someValue = \(Configuration.someValue)")

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSebastianView Question on Stackoverflow
Solution 1 - IosConnorView Answer on Stackoverflow
Solution 2 - IospheedstaView Answer on Stackoverflow
Solution 3 - IosekreloffView Answer on Stackoverflow
Solution 4 - IosAshok RView Answer on Stackoverflow
Solution 5 - IosTommie C.View Answer on Stackoverflow
Solution 6 - IosNickView Answer on Stackoverflow
Solution 7 - IosSuhit PatilView Answer on Stackoverflow
Solution 8 - Ios67cherriesView Answer on Stackoverflow
Solution 9 - IosNithin SathyanView Answer on Stackoverflow
Solution 10 - IosAlvin GeorgeView Answer on Stackoverflow
Solution 11 - IosmredigView Answer on Stackoverflow
Solution 12 - IosScott MarchantView Answer on Stackoverflow
Solution 13 - IosKennyVBView Answer on Stackoverflow
Solution 14 - IosimtiView Answer on Stackoverflow
Solution 15 - Iosjose920405View Answer on Stackoverflow
Solution 16 - IosBhuvan BhattView Answer on Stackoverflow
Solution 17 - IosYannStephView Answer on Stackoverflow
Solution 18 - IosBence PattogatoView Answer on Stackoverflow
Solution 19 - IosquemefulView Answer on Stackoverflow
Solution 20 - IosJordan HView Answer on Stackoverflow
Solution 21 - Iosuser3069232View Answer on Stackoverflow
Solution 22 - IosTheAppleManView Answer on Stackoverflow
Solution 23 - Iose.w. parrisView Answer on Stackoverflow
Solution 24 - IosBenziView Answer on Stackoverflow
Solution 25 - IosSanduView Answer on Stackoverflow
Solution 26 - Iosmacio.JunView Answer on Stackoverflow
Solution 27 - Iosn0_quarterView Answer on Stackoverflow