在swift中将响应作为对象返回
我有一个连接到API以检索数据的函数。API采用两个参数accessCode(由用户在文本框中提供)和UDID(设备的UDID)。我可以从函数内部解析数据,但只能在本地解析。我需要存储返回的值,但不确定如何正确返回。本质上,我需要它以字典的形式返回json对象(我想…),这样就可以在异步任务之外解析它。我已经阅读了swift文档,在那里我找到了如何执行请求,但是我找不到一种方法将返回的值存储在内存中,以便在函数之外进行访问在swift中将响应作为对象返回,swift,asynchronous,Swift,Asynchronous,我有一个连接到API以检索数据的函数。API采用两个参数accessCode(由用户在文本框中提供)和UDID(设备的UDID)。我可以从函数内部解析数据,但只能在本地解析。我需要存储返回的值,但不确定如何正确返回。本质上,我需要它以字典的形式返回json对象(我想…),这样就可以在异步任务之外解析它。我已经阅读了swift文档,在那里我找到了如何执行请求,但是我找不到一种方法将返回的值存储在内存中,以便在函数之外进行访问 func getResponse(accessCode:String,U
func getResponse(accessCode:String,UDID:String,uu完成:@escaping(NSDictionary)->()){
让urlPath=”https://apihosthere.com/api/validate?accessCode=“+accessCode+”&UDID=“+UDID
guard let url=url(字符串:urlPath)else{return}
让task=URLSession.shared.dataTask(带:url){(数据、响应、错误)在
guard let data=data else{return}
做{
如果让jsonResult=try JSONSerialization.jsonObject(with:data,options:JSONSerialization.ReadingOptions.mutableContainers)作为?NSDictionary{
让results=jsonResult作为?NSDictionary
打印(结果)
完成(结果!)
}
}抓住{
//在这里捕获错误。。。
}
}
task.resume()
}
您的完成
结束应该处理获得的数据。您可以这样调用函数:
getResponse(accessCode:“code”,UDID:“UDID”,完成:{结果为
//对字典结果做任何你需要做的事情
}
另外,我建议您使用swift
字典更改NSDictionary
您的完成
闭包应该处理获得的数据。您可以这样调用函数:
getResponse(accessCode:“code”,UDID:“UDID”,完成:{结果为
//对字典结果做任何你需要做的事情
}
另外,我建议您使用swift字典更改NSDictionary
,这是API作为响应返回的结果
{
AccessCode = 00000000;
Client = "0000 - My Company Name";
EmailAddress = "brandon@brandonthomas.me";
FirstName = Brandon;
Found = 1;
LastName = Thomas;
Status = A;
UDIDregistered = 1;
}
这就是调用函数的地方。在文本字段中输入访问码后,单击一个按钮后,我正在调用
@IBAction func StartWizard(_ sender: UIButton) {
//Store entered access code
let accessCode = AccessCodeField.text!
var accessCodeFound: Bool? = nil
//Call API to validate Access Code
getResponse(accessCode:accessCode, UDID:myDeviceUDID) { result in
accessCodeFound = result["Found"] as! Bool
print("Value of Found during function:")
print(accessCodeFound)
//accessCodeFound = true
}
//If access code is valid, go to License view
print("Value of Found after function:")
print(accessCodeFound)
//accessCodeFound = nil ???
//it seems the value is getting reset after the function completes
if accessCodeFound == true{
//Load License View
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let licenseController = storyboard.instantiateViewController(identifier: "LicenseViewPanel")
self.show(licenseController, sender: Any?.self)
}
}
这是API作为响应返回的内容
{
AccessCode = 00000000;
Client = "0000 - My Company Name";
EmailAddress = "brandon@brandonthomas.me";
FirstName = Brandon;
Found = 1;
LastName = Thomas;
Status = A;
UDIDregistered = 1;
}
这就是调用函数的地方。在文本字段中输入访问码后,单击一个按钮后,我正在调用
@IBAction func StartWizard(_ sender: UIButton) {
//Store entered access code
let accessCode = AccessCodeField.text!
var accessCodeFound: Bool? = nil
//Call API to validate Access Code
getResponse(accessCode:accessCode, UDID:myDeviceUDID) { result in
accessCodeFound = result["Found"] as! Bool
print("Value of Found during function:")
print(accessCodeFound)
//accessCodeFound = true
}
//If access code is valid, go to License view
print("Value of Found after function:")
print(accessCodeFound)
//accessCodeFound = nil ???
//it seems the value is getting reset after the function completes
if accessCodeFound == true{
//Load License View
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let licenseController = storyboard.instantiateViewController(identifier: "LicenseViewPanel")
self.show(licenseController, sender: Any?.self)
}
}
首先,不要在Swift中使用NSDictionary
,使用native[String:Any]
并将类型声明为可选,以便在发生错误时返回nil
在Swift中,决不使用.mutableContainers
,该选项无效
func getResponse(accessCode:String, UDID:String, completion: @escaping ([String:Any]?) -> Void)) {
let urlPath = "https://apihosthere.com/api/validate?accessCode=" + accessCode + "&UDID=" + UDID
guard let url = URL(string: urlPath) else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error else {
print(error)
completion(nil)
return
}
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
print(jsonResult)
completion(jsonResult)
} else {
completion(nil)
}
} catch {
print(error)
completion(nil)
}
}
task.resume()
}
您的错误是,您不考虑关闭,必须在完成处理程序
内执行整个代码。
@IBAction func StartWizard(_ sender: UIButton) {
//Store entered access code
let accessCode = AccessCodeField.text!
//Call API to validate Access Code
getResponse(accessCode:accessCode, UDID:myDeviceUDID) { [weak self] result in
if let accessCodeFound = result?["Found"] as? Bool {
print("Value of Found during function:")
//If access code is valid, go to License view
print(accessCodeFound)
if accessCodeFound {
//Load License View
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let licenseController = storyboard.instantiateViewController(identifier: "LicenseViewPanel")
self?.show(licenseController, sender: self)
}
}
}
}
}
首先,不要在Swift中使用NSDictionary
,使用native[String:Any]
并将类型声明为可选,以便在发生错误时返回nil
在Swift中,决不使用.mutableContainers
,该选项无效
func getResponse(accessCode:String, UDID:String, completion: @escaping ([String:Any]?) -> Void)) {
let urlPath = "https://apihosthere.com/api/validate?accessCode=" + accessCode + "&UDID=" + UDID
guard let url = URL(string: urlPath) else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error else {
print(error)
completion(nil)
return
}
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
print(jsonResult)
completion(jsonResult)
} else {
completion(nil)
}
} catch {
print(error)
completion(nil)
}
}
task.resume()
}
您的错误是,您不考虑关闭,必须在完成处理程序
内执行整个代码。
@IBAction func StartWizard(_ sender: UIButton) {
//Store entered access code
let accessCode = AccessCodeField.text!
//Call API to validate Access Code
getResponse(accessCode:accessCode, UDID:myDeviceUDID) { [weak self] result in
if let accessCodeFound = result?["Found"] as? Bool {
print("Value of Found during function:")
//If access code is valid, go to License view
print(accessCodeFound)
if accessCodeFound {
//Load License View
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let licenseController = storyboard.instantiateViewController(identifier: "LicenseViewPanel")
self?.show(licenseController, sender: self)
}
}
}
}
}
什么叫这个?传递的完成
看起来像什么?你的结果
打印正确吗?你只需要在这个if-let函数之外使用结果
中的任何值?或者你无法在结果
中获取任何值?将其转换为JSON并对其进行解析不是更好吗?什么叫它是吗?传递的完成
看起来像什么?你的结果
打印正确吗?你只想在if let函数之外得到结果
中的任何值?或者你无法在结果
中获得任何值?把它转换成JSON然后解析它不是更好吗?好吧,剩下的代码就这样吧必须在完成处理程序内部,这是有意义的。有没有一种方法可以保存值以便在它外部也可以访问?比如,如果我想存储accessCodeFound和我必须创建的其他变量来存储从API调用提取的其余值,那么有没有一种方法可以使它们全局化,以便在下一个视图中可以访问它们控制器?在LicenseViewPanel
controller中创建一个字典并分配(展开)result
在show
行之前添加它。但是强烈建议使用Decodable
解析结构中的JSON。好的,我将研究设置。当前,当我在响应中运行StartWizard函数时,我得到一个错误:-[UIViewController initWithCoder:]必须仅从主线程使用"视图控制器似乎只能在主线程上更改,而不能在异步任务中更改。如何解决这个问题?这是值得的!非常感谢您的帮助。我将设置一个可解码的struc来保存valuesOK,这样其余的代码就必须在完成处理程序中,这是有意义的。有没有办法保存valUE是否也可以在外部访问?例如,如果我想存储accessCodeFound和我必须创建的其他变量来存储从API调用中提取的其余值,是否有办法使它们全局化,以便可以在下一个视图控制器上访问它们?在LicenseViewPanel
控制器中创建一个字典并分配(未包装)结果
在显示
行之前添加到它。但是强烈建议使用可解码
在结构中解析JSON。好的,我将研究设置。当前,当我在您的响应中运行StartWizard函数时,我得到一个错误:-[UIViewController initWithCoder:]必须仅从主线程使用“似乎视图控制器