Search code examples
iosswiftuitableviewalamofireswifty-json

type does not conform to protocol Sequence Type - Swift


From my swift app I'm fetching data from a webservice. Data comes as an array:

{"hashtags": ["first", "second"]}

I want to put every hashtag in a separate row of my UITableView. I have the logic to do that, but first - I'm getting werid error while parsing data.

I wrote a custom function:

class SingleHashtag: NSObject {

    var hashtagText: [String]

    init(hashtagText: [String]) {
        self.hashtagText = hashtagText
        super.init()
    }

    class func fromJSON(json: JSON) -> SingleHashtag? {
        let hashtagText:[String] = json["hashtags"].arrayValue.map { $0.stringValue}
        return SingleHashtag(hashtagText: hashtagText)
    }
}

and then in my main class I have:

Alamofire.request(.GET, "\(serverURL)/hashtags"/*, headers: headers*/)
        .validate()
        .responseJSON { response in
            print(response.description)
            switch response.result {
            case .Success:
                dispatch_async(dispatch_get_main_queue(),{
                    self.items.removeAllObjects()
                    if let jsonData = response.result.value as? [[String: AnyObject]] {
                        for hashtag in jsonData {
                            if let userHashtags = SingleHashtag.fromJSON(JSON(hashtag)){
                                for hash in userHashtags {
                                    self.items.addObject(hash)
                                    self.hashtagTable.reloadData()
                                }
                            }
                        }
                    }
                    self.hashtagTable.reloadData()
                })
            case .Failure(let error):
                print(error)
            }
    }

but this line:

for hash in userHashtags {

throws an error during compilation:

type SingleHashtag does not conform to protocol 'SequenceType'

I tried adding as AnyObject but that didn't help. Can you tell me what might be wrong here?


Solution

  • Based on our conversation in the comments it looks like there are lots of things at play here.

    Defining items as an objective-c object like NSMutableArray is fighting against Swift and robbing it of its typing strength. If items is only ever a list of hashtag strings, then it should be typed as such. Try changing your items declaration to this:

    var items = [String]()
    

    Based on what you've shared, it also doesn't look like a separate class for SingleHashtag is necessary. If it only has one String variable, it would be simpler to just pass the strings into items directly. An example of that is here:

    Alamofire.request(.GET, "\(serverURL)/hashtags"/*, headers: headers*/)
        .validate()
        .responseJSON { response in
            print(response.description)
            switch response.result {
            case .Success:
                dispatch_async(dispatch_get_main_queue(),{
                    self.items.removeAll()
    
                    //cast the jsonData appropriately, then grab the hashtags
                    if let jsonData = response.result.value as? [String: [String]],
                        let hashtags = jsonData["hashtags"] {
    
                        //hashtags is now type [String], so you can loop
                        //through without the error and add the strings to 'items'
                        for hashtagText in hashtags {
                            self.items.append(hashtagText)
                            self.hashtagTable.reloadData
                        }
                    }
                })
            case .Failure(let error):
                print(error)
            }
    }
    

    Note: this is written in Swift 3, so there will be some syntax differences if you are using an older version of Swift.