编辑:答案在下面的注释中,我必须使用completionHandler才能进行异步调用。非常感谢Gasim的帮助。
在一个名为NetworkManager的类中,它有一个sharedInstance结构,允许我调用其他类中的函数,我声明public var urlArray = []
这是一个空数组,不是任何函数的一部分。
在一个名为fetchLatestPosts
的函数中,我正在解析JSON数据并下载一些像var photoURLArray: NSArray = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray
这样的数组返回的相关URL,然后尝试设置self.urlArray = photoURLArray
因为它允许我在函数之外设置photoURLArray
的值。
问题在于,当我尝试将NetworkManager.sharedInstance.urlArray
的值设置为不同方法中的函数时,结果返回nil。
这是因为在我将photoURLArray
函数中的值设置为fetchLatestPosts
之前,xCode认为我正在使用该值调用变量吗?有没有办法让我设置在函数内调用的数组的值,以便允许我在其他类中访问它的值?
我问这个的原因是因为我不想在我的tableViewCell类中进行JSON解析,因为否则每次出现新单元格时我都会对Instagram API进行大量调用。我已经被困在这个问题上一天左右,如果有人能帮我解决这个问题,我会很感激!
public func fetchLatestPosts(tag: String) {
var userDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var accessTokenQuery: AnyObject? = userDefaults.objectForKey("accessToken")
if (accessTokenQuery == nil)
{
// Logging user in to IG
SimpleAuth.authorize("instagram", completion: { (responseObject: AnyObject!, error: NSError!) -> Void in
var IGDictionary: NSDictionary = responseObject as NSDictionary
let credentials: AnyObject! = IGDictionary["credentials"]
let accessToken: AnyObject! = credentials["token"]
println("Access token: \(accessToken)")
userDefaults.setObject(accessToken, forKey: "accessToken")
userDefaults.synchronize()
})
} else {
println("User is already logged in")
// Load some posts
var session: NSURLSession = NSURLSession.sharedSession()
var accessToken: NSString = userDefaults.objectForKey("accessToken") as NSString
var urlString: NSString = NSString(format: "https://api.instagram.com/v1/tags/\(tag)/media/recent?access_token=%@", accessToken)
// println(urlString)
var url = NSURL(string: urlString)!
var request: NSURLRequest = NSURLRequest(URL: url)
var task: NSURLSessionDownloadTask = session.downloadTaskWithRequest(request, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
// Sorting JSON into dictionary
var data: NSData = NSData(contentsOfURL: location)!
var responseDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as [String: AnyObject]!
// Getting photo URLs
var photos: NSArray = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray
// println("photos: \(photos)")
self.IGDictionary = responseDictionary
self.photoItems = photos
// println("photoItems: \(self.photoItems)")
})
task.resume()
}
}
答案 0 :(得分:0)
这就是我喜欢这样做的方式,因为我希望将请求部分与我真正想要做的事情分开,一旦完成:
public func fetchLatestPosts(tag: String, successHandler: (NSDictionary, NSArray) -> Void) {
var userDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var accessTokenQuery: AnyObject? = userDefaults.objectForKey("accessToken")
if (accessTokenQuery == nil)
// ...
} else {
// ...
var task: NSURLSessionDownloadTask = session.downloadTaskWithRequest(request, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
var data: NSData = NSData(contentsOfURL: location)!
var responseDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as [String: AnyObject]!
var photos: NSArray = responseDictionary.valueForKeyPath("data.images.standard_resolution.url") as NSArray
successHandler(responseDictionary, photos);
})
task.resume()
}
}
和示例用法:
override func viewDidLoad() {
super.viewDidLoad();
self.fetchLatestPosts("SomeTag", successHandler: {
(responseDictionary, photos) in
self.photos = photos;
self.IGDictionary = responseDictionary;
// reload collection view data or do whatever you need
self.collectionView.reloadData();
});
}
另外,我建议您查看SwiftyJSON。你使用它的那一刻就会爱上它。