Я не очень хорошо знаком с закрытием. Я использую эту функцию для загрузки JSON файла с удаленного сервера
requestJson(){
// Asynchronous Http call to your api url, using NSURLSession:
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://api.site.com/json")!, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
// Access specific key with value of type String
let str = json["key"] as! String
} catch {
// Something went wrong
}
}
}).resume()
}
Возможно ли, чтобы функция requestJson() вернула JSON файл при его загрузке? Или это невозможно, потому что он загружен асинхронно и не может быть готов? Хочу, чтобы я пытался сделать следующее:
requestJson() -> **[String : AnyObject]**{
// Asynchronous Http call to your api url, using NSURLSession:
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://api.site.com/json")!, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
// Access specific key with value of type String
**return json**
} catch {
// Something went wrong
}
}
}).resume()
}
Вы можете дать параметрам функции обратный вызов @escaping, возвращающий массив или все, что вам нужно;
Пример этого для сетевого запроса;
class func getGenres(completionHandler: @escaping (genres: NSArray) -> ()) {
...
let task = session.dataTask(with:url) {
data, response, error in
...
resultsArray = results
completionHandler(genres: resultsArray)
}
...
task.resume()
}
Затем, чтобы назвать это, вы могли бы сделать что-то подобное;
override func viewDidLoad() {
getGenres {
genres in
print("View Controller: \(genres)")
}
}
//MARK: Request method to get json
class func requestJSON(completion: @escaping (returnModel: String?) -> Void) {
//here you write code for calling API
}
//MARK: Calling function to retrieve return string
API.requestJSON(completion: { (string) in
//here you can get your string
})
func httpGet(request: NSURLRequest!, callback: (NSString, NSString?) -> Void)
{
var session = NSURLSession.sharedSession()
var task = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if error != nil {
callback("", error.localizedDescription)
} else {
var result = NSString(data: data, encoding:
NSASCIIStringEncoding)!
callback(result, nil)
}
}
task.resume()
}
func makeRequest(callback: (NSString) ->Void) -> Void {
var request = NSMutableURLRequest(URL: NSURL(string: "http://sample_url")!)
var result:NSString = ""
httpGet(request){
(data, error) -> Void in
if error != nil {
result = error!
} else {
result = data
}
callback(data)
}
}
Использование:-
self.makeRequest(){
(data) -> Void in
println("response data:\(data)")
}
requestJson()
свое собственное замыкание для собственного методаrequestJson()
.