【问题标题】:How to get JSON response data from shared class to ViewController?如何从共享类获取 JSON 响应数据到 ViewController?
【发布时间】:2019-01-31 12:43:02
【问题描述】:

我没有使用 Alamofire,所以我想在 SharedClass 中使用 JSON 发布方法,并且我想将我的 api 名称和所有参数发送到该函数。最后我想得到回复。我试过了,但它不起作用。如果不正确,请纠正我,或者如果有其他可用的选项,请建议我。

我在 SharedClass 中的代码

func postRequestFunction(apiName:String , parameters:String ) -> [String:Any] {

    var localURL =  "hostname/public/index.php/v/***?"

        localURL = localURL.replacingOccurrences(of: "***", with: apiName)

        var request = URLRequest(url: URL(string: localURL)!)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        print("shared URL : \(request)")
        request.httpBody = parameters.data(using: .utf8)

    var returnRes:[String:Any] = [:]
        let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error
            print(error!)
            //                print("error=\(String(describing: error))")
                            print("localizedDescription : \(String(describing: error?.localizedDescription))")
            return
            }

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(String(describing: response))")
            }

            do {
                returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
                print(returnRes)

            } catch let error as NSError {
                print(error)
            }
        }

        task.resume()

    return returnRes
}

在我的视图控制器类中,我的代码是。这里我调用函数

func getProjectDetails() {
    let response = SharedClass.sharedInstance.postRequestFunction(apiName: "API Name", parameters: parameters)
    print(response)
    let res = response["Response"] as! [String:Any]
    let status = res["status"] as! String

    if status == "SUCCESS" {
        //I will handle response here
    } else {
        let message = res["message"] as! String
        //Call alert function
        SharedClass.sharedInstance.alert(view: self, title: "", message: message)
    }
}

【问题讨论】:

    标签: ios json swift singleton http-post


    【解决方案1】:

    这是我的解决方案:

    class APIManager {
    
        private init () {}
    
        static let shared = APIManager()
    
        func postRequestFunction(apiName: String , parameters: String, onCompletion: @escaping (_ success: Bool, _ error: Error?, _ result: [String: Any]?)->()) {
    
            var localURL =  "hostname/public/index.php/v/***?"
    
            localURL = localURL.replacingOccurrences(of: "***", with: apiName)
    
            var request = URLRequest(url: URL(string: localURL)!)
            request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
            request.httpMethod = "POST"
            print("shared URL : \(request)")
            request.httpBody = parameters.data(using: .utf8)
    
            var returnRes:[String:Any] = [:]
            let task = URLSession.shared.dataTask(with: request) { data, response, error in
    
                if let error = error {
                    onCompletion(false, error, nil)
                } else {
                    guard let data = data else {
                        onCompletion(false, error, nil)
                        return
                    }
    
                    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 200 {
                        do {
                            returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
                            onCompletion(true, nil, returnRes)
    
                        } catch let error as NSError {
                            onCompletion(false, error, nil)
                        }
                    } else {
                        onCompletion(false, error, nil)
                    }
                }
            }
            task.resume()
        }
    }
    
    func getProjectDetails() {
    
        /* Notes:
    
         ** onCompletion Block Parameters:
    
         success - This indicates whether the API called successfully or not.
         error - This indicates errors from either API calling failed, JSON parsing, or httpStatus is not 200.
         result - This indicates the JSON parsed result.
    
         ** APIManager:
    
         I have renamed your SharedClass to APIManager for better readibility.
    
         ** sharedInstance:
    
         I have renamed sharedInstance to shared for better readibility.
    
        */
    
        APIManager.shared.postRequestFunction(apiName: "API Name", parameters: "parameters") { (success, error, result) in
            if success {
                if let res = result?["Response"] as? [String: Any] {
                    if let status = res["status"] as? String {
                        if status == "SUCCESS" {
                            //You can handle response here.
                        } else {
                            let message = res["message"] as! String
                            //Call alert function.
                        }
                    }
                }
            } else {
                print(error?.localizedDescription)
            }
        }
    }
    

    【讨论】:

    • 亲爱的 Hemang,是否可以从同一个类中访问多个 API。像这样 例如:stackoverflow.com/questions/28634995/…
    • 嗨,很高兴你喜欢这个答案,我相信,这是可能的,但你指出的问题是,它使用了第三方库 PromiseKit。不使用你也可以做到,但是你需要为它编写大量代码。也许,NSOperationManager 和使用GCD 调用?
    • 我有一些关于 NSOperationManager 的基本知识,你能把那个代码发给我吗?是否可以发送
    • 你的博客不错,几分钟前我就看到了...很棒的工作 Hemang
    • 谢谢你,但现在我的博客不活跃了。 :( 我会尝试添加更多内容。关于您的查询,我无法向您发送该代码,因为正如我所说,您需要编写这么多代码,所以我目前无能为力。会我宁愿建议您使用PromiseKit 探索它,也许对您来说会更容易?
    【解决方案2】:

    你忘记了 Service 的异步范式,你可以在 Closure 中返回你的 API 响应,如下所示

    func postRequestFunction(apiName:String , parameters:String, returnRes: @escaping ([String: Any]) -> () ) {
    
        var localURL =  "hostname/public/index.php/v/***?"
    
        localURL = localURL.replacingOccurrences(of: "***", with: apiName)
    
        var request = URLRequest(url: URL(string: localURL)!)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        print("shared URL : \(request)")
        request.httpBody = parameters.data(using: .utf8)
    
        let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else {
            // check for fundamental networking error
            return
            }
    
            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(String(describing: response))")
            }
    
            do {
                if let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any] {
                    returnRes(response)
                }
            } catch let error as NSError {
                print(error)
            }
        }
    
        task.resume()
    }
    

    并像下面这样使用

    postRequestFunction(apiName: "yourUrl", parameters: "Param") { (response) in
    
        print(response)
    
    }
    

    【讨论】:

    • 我这样调用 SharedClass.sharedInstance.postRequestFunction(apiName: "apiname", parameters: parameters) { (response) in print(response) ,, 响应进入共享类,但不是返回任何东西
    • print(response) 它没有打印任何东西,我正在从共享类中的服务器获取数据。获取数据后如何从共享类获得对我的自定义类的响应。请帮帮我...
    • 没什么,在 SharedClass 响应打印成功,但该响应没有进入我的班级
    • NSNotificationCenter 是否可以将响应发送回 ViewController
    • 如果可能与代表或通知中心请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多