Search code examples
iosswiftnsarrayplistclcircleregion

How do I use values out of a plist in Swift without them coming up as AnyObject?


I'm trying to get objects out of a plist and use them in Swift to create a CLCircularRegion, but when I try and use those values I see this error

Cannot invoke 'init' with an argument list of type '(center: $T3, radius: @lvalue AnyObject?!, identifier: @lvalue AnyObject?!)'

Here's the method I'm using to pull the data from the plist, which works fine as I can see the content via the println call.

func setupLocations() {
// Region plist
let regionArray = NSArray(contentsOfFile: NSBundle.mainBundle().pathForResource("Landmarks", ofType: "plist")!)

println(regionArray)

for location in regionArray! {
    var longitudeNumber = location["Longitude"]
    var latitudeNumber = location["Latitude"]
    var rangeNumber = location["Range"]
    var regionString = location["Identifier"]

    let newRegion = CLCircularRegion(center: CLLocationCoordinate2DMake(latitudeNumber, longitudeNumber), radius: rangeNumber, identifier: regionString)
    }
}

Within the plist the objects are stored as an array, which contains a dictionary. That dictionary contains three Number values and one String value.


Solution

  • All of the values that you extract from the dictionary are optionals, and of AnyObject type.

    The first thing to do is make an explicit cast to the actual type:

    var longitudeNumber = location["Longitude"] as? Double
    var latitudeNumber = location["Latitude"] as? Double
    var rangeNumber = location["Range"] as? Int
    var regionString = location["Identifier"] as? String
    

    (I inferred types basing on variable names, but of course change to the actual types you expect).

    Next, you should use either optional binding, but that would look ugly because of the 4 nested if, or more simply:

    if longitudeNumber != nil && latitudeNumber != nil && rangeNumber != nil and regionString != nil {
        let newRegion = CLCircularRegion(center: CLLocationCoordinate2DMake(latitudeNumber!, longitudeNumber!), radius: rangeNumber!, identifier: regionString!)
    }
    

    Note the use of forced unwrapping !, which is safe in this case because protected by the outer if statement.