Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在swift中将响应作为对象返回_Swift_Asynchronous - Fatal编程技术网

在swift中将响应作为对象返回

在swift中将响应作为对象返回,swift,asynchronous,Swift,Asynchronous,我有一个连接到API以检索数据的函数。API采用两个参数accessCode(由用户在文本框中提供)和UDID(设备的UDID)。我可以从函数内部解析数据,但只能在本地解析。我需要存储返回的值,但不确定如何正确返回。本质上,我需要它以字典的形式返回json对象(我想…),这样就可以在异步任务之外解析它。我已经阅读了swift文档,在那里我找到了如何执行请求,但是我找不到一种方法将返回的值存储在内存中,以便在函数之外进行访问 func getResponse(accessCode:String,U

我有一个连接到API以检索数据的函数。API采用两个参数accessCode(由用户在文本框中提供)和UDID(设备的UDID)。我可以从函数内部解析数据,但只能在本地解析。我需要存储返回的值,但不确定如何正确返回。本质上,我需要它以字典的形式返回json对象(我想…),这样就可以在异步任务之外解析它。我已经阅读了swift文档,在那里我找到了如何执行请求,但是我找不到一种方法将返回的值存储在内存中,以便在函数之外进行访问

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:]必须仅从主线程使用“似乎视图控制器