Kalianey
Kalianey

Reputation: 2798

How to loop through an array of objects in swift

I'm trying to access the url of an object stored in an array, but I'm getting errors no matters what methods I'm using.

let userPhotos = currentUser?.photos

    for var i = 0; i < userPhotos!.count ; ++i {
        let url = userPhotos[i].url
    }

Here I get

Could not find member 'url'

and with a foreach:

for photo in userPhotos {

        Utils.getImageAsync(photo.url , completion: { (img: UIImage?) -> () in

        })
    }

I get:

'[ModelAttachment]?' does not have a member named 'Generator'

My array is var photos: Array<ModelAttachment>? and my ModelAttachment looks like this:

class ModelAttachment :Model {
var id: String?
var url: String?
var thumb: String?
}

Any pointers to what I'm doing wrong would be great :)

Upvotes: 47

Views: 120289

Answers (4)

Eric Aya
Eric Aya

Reputation: 70098

Unwrap and downcast the objects to the right type, safely, with if let, before doing the iteration with a simple for in loop.

if let currentUser = currentUser, 
    let photos = currentUser.photos as? [ModelAttachment] 
{
    for object in photos {
        let url = object.url
    }
}

There's also guard let else instead of if let if you prefer having the result available in scope:

guard let currentUser = currentUser, 
    let photos = currentUser.photos as? [ModelAttachment] else 
{
    // break or return
}
// now 'photos' is available outside the guard
for object in photos {
    let url = object.url
}

Upvotes: 83

Forketyfork
Forketyfork

Reputation: 7810

Your userPhotos array is option-typed, you should retrieve the actual underlying object with ! (if you want an error in case the object isn't there) or ? (if you want to receive nil in url):

let userPhotos = currentUser?.photos

for var i = 0; i < userPhotos!.count ; ++i {
    let url = userPhotos![i].url
}

But to preserve safe nil handling, you better use functional approach, for instance, with map, like this:

let urls = userPhotos?.map{ $0.url }

Upvotes: 6

giorashc
giorashc

Reputation: 13713

The photos property is an optional array and must be unwrapped before accessing its elements (the same as you do to get the count property of the array):

for var i = 0; i < userPhotos!.count ; ++i {
    let url = userPhotos![i].url
}

Upvotes: 0

gskspurs
gskspurs

Reputation: 186

You can try using the simple NSArray in syntax for iterating over the array in swift which makes for shorter code. The following is working for me:

class ModelAttachment {
    var id: String?
    var url: String?
    var thumb: String?
}

var modelAttachementObj = ModelAttachment()
modelAttachementObj.id = "1"
modelAttachementObj.url = "http://www.google.com"
modelAttachementObj.thumb = "thumb"

var imgs: Array<ModelAttachment> = [modelAttachementObj]

for img in imgs  {
    let url = img.url
    NSLog(url!)
}

See docs here

Upvotes: 4

Related Questions