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?
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.