在 swift 中使用 JSON 响应调用函数时出错
error calling functions in swift with a JSON response
其他人可以帮助我知道在 swift 中调用函数的方式是什么,接收 JSON 收集响应吗?
我在 viewController.swift 中调用 ApiClient().getList() 函数,此函数调用我的 API 并在 apiClient.swift 中收到 JSON 响应,最后我想将此 JSON 响应分配给 viewController.swift.
中的 self.result 变量
我的代码是:
viewController.swift
import UIKit
class ClubsViewController: UIViewController, UITableViewDataSource{
var results: [JSON]? = []
@IBOutlet var tableview:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.loadClubsObjects()
}
func loadClubsObjects(){
self.results = ApiClient().getList() <--- here is the call
self.tableview.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.results?.count ?? 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("clubsObjectCell") as! ClubsTableViewCell
cell.clubsObject = self.results?[indexPath.row]
return cell
}
}
ApiClient.swift
import Foundation
import Alamofire
class ApiClient {
func getList() -> [JSON] {
var URL = NSURL(string: "https://api.com/v1/clubs")
var mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { (request, response, json, error) in
if (json != nil){
var jsonObj = JSON(json!)
if let data = jsonObj["hits"].arrayValue as [JSON]?{
return data
}
}
}
}
而 apiClient.swift 中的错误是
return 数据 -> [JSON] 不可转换为 Void
getList
的定义方式应该是 return [JSON]
对象。但它不能那样做,因为 responseJSON
是一个异步方法(即 responseJSON
的完成闭包直到你从 getList
return 之后很久才被调用)。
您必须使用自己的 completionHandler
模式。例如,getList
不会 return 任何东西, 而是需要一个完成处理程序参数:
func getList(completionHandler: ([JSON]) -> ()) {
let URL = NSURL(string: "https://api.com/v1/clubs")
let mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { response in
if let json = response.result.value {
var jsonObj = JSON(json)
if let hits = jsonObj["hits"].arrayValue as [JSON]? {
completionHandler(hits)
}
}
}
}
你会这样调用它:
let apiClient = ApiClient()
func loadClubsObjects() {
apiClient.getList() { hits in
// use hits here
self.results = hits
self.tableView.reloadData()
}
// but not here
}
请注意,我倾向于不让 API 客户端成为 loadClubsObjects
的局部变量,而是 class 属性,如上所示。随心所欲,但它给我的印象是一个更合乎逻辑的生命周期。
如果您想处理错误,您可以更改完成处理程序闭包,以便 (a) JSON
命中数组是可选的; (b) 添加一个可选的错误对象。然后更改 getList
以传回这些可选值:
func getList(completionHandler: ([JSON]?, NSError?) -> ()) {
let URL = NSURL(string: "https://api.com/v1/clubs")
let mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { response in
if let json = response.result.value {
var jsonObj = JSON(json)
if let hits = jsonObj["hits"].arrayValue as [JSON]? {
completionHandler(hits, nil)
} else {
let jsonError = NSError(domain: "mydomain", code: MyErrorCode.HitsNotFound, userInfo: nil) // create whatever sort of error object you think is appropriate if `hits` was not found
completionHandler(nil, jsonError)
}
} else {
completionHandler(nil, response.result.error)
}
}
}
然后调用的时候可以查看JSON个对象数组是不是nil
,如果是nil
,再看NSError
对象。
其他人可以帮助我知道在 swift 中调用函数的方式是什么,接收 JSON 收集响应吗? 我在 viewController.swift 中调用 ApiClient().getList() 函数,此函数调用我的 API 并在 apiClient.swift 中收到 JSON 响应,最后我想将此 JSON 响应分配给 viewController.swift.
中的 self.result 变量我的代码是:
viewController.swift
import UIKit
class ClubsViewController: UIViewController, UITableViewDataSource{
var results: [JSON]? = []
@IBOutlet var tableview:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.loadClubsObjects()
}
func loadClubsObjects(){
self.results = ApiClient().getList() <--- here is the call
self.tableview.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.results?.count ?? 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("clubsObjectCell") as! ClubsTableViewCell
cell.clubsObject = self.results?[indexPath.row]
return cell
}
}
ApiClient.swift
import Foundation
import Alamofire
class ApiClient {
func getList() -> [JSON] {
var URL = NSURL(string: "https://api.com/v1/clubs")
var mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { (request, response, json, error) in
if (json != nil){
var jsonObj = JSON(json!)
if let data = jsonObj["hits"].arrayValue as [JSON]?{
return data
}
}
}
}
而 apiClient.swift 中的错误是
return 数据 -> [JSON] 不可转换为 Void
getList
的定义方式应该是 return [JSON]
对象。但它不能那样做,因为 responseJSON
是一个异步方法(即 responseJSON
的完成闭包直到你从 getList
return 之后很久才被调用)。
您必须使用自己的 completionHandler
模式。例如,getList
不会 return 任何东西, 而是需要一个完成处理程序参数:
func getList(completionHandler: ([JSON]) -> ()) {
let URL = NSURL(string: "https://api.com/v1/clubs")
let mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { response in
if let json = response.result.value {
var jsonObj = JSON(json)
if let hits = jsonObj["hits"].arrayValue as [JSON]? {
completionHandler(hits)
}
}
}
}
你会这样调用它:
let apiClient = ApiClient()
func loadClubsObjects() {
apiClient.getList() { hits in
// use hits here
self.results = hits
self.tableView.reloadData()
}
// but not here
}
请注意,我倾向于不让 API 客户端成为 loadClubsObjects
的局部变量,而是 class 属性,如上所示。随心所欲,但它给我的印象是一个更合乎逻辑的生命周期。
如果您想处理错误,您可以更改完成处理程序闭包,以便 (a) JSON
命中数组是可选的; (b) 添加一个可选的错误对象。然后更改 getList
以传回这些可选值:
func getList(completionHandler: ([JSON]?, NSError?) -> ()) {
let URL = NSURL(string: "https://api.com/v1/clubs")
let mutableURLRequest = NSMutableURLRequest(URL: URL!)
mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
mutableURLRequest.HTTPMethod = "GET"
mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")
let manager = Alamofire.Manager.sharedInstance
let request = manager.request(mutableURLRequest)
request.responseJSON { response in
if let json = response.result.value {
var jsonObj = JSON(json)
if let hits = jsonObj["hits"].arrayValue as [JSON]? {
completionHandler(hits, nil)
} else {
let jsonError = NSError(domain: "mydomain", code: MyErrorCode.HitsNotFound, userInfo: nil) // create whatever sort of error object you think is appropriate if `hits` was not found
completionHandler(nil, jsonError)
}
} else {
completionHandler(nil, response.result.error)
}
}
}
然后调用的时候可以查看JSON个对象数组是不是nil
,如果是nil
,再看NSError
对象。