Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.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

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
在ios中,从不同的视图控制器多次调用同一Web服务(而不是同时调用)_Ios_Swift_Xcode_Rest - Fatal编程技术网

在ios中,从不同的视图控制器多次调用同一Web服务(而不是同时调用)

在ios中,从不同的视图控制器多次调用同一Web服务(而不是同时调用),ios,swift,xcode,rest,Ios,Swift,Xcode,Rest,我只是想知道在不同的时间从不同的视图控制器调用相同的Web服务的最佳方式是什么。我应该遵循什么架构或设计?我不想在每个视图控制器中编写相同的代码 我将编写一个网络管理器类,它将web服务参数(如果有的话)作为参数 这是一个粗略的架构示例 class YourNetworkManager { public func callSpecificWebService(argument : Type?, [optional closure to handle results]) {

我只是想知道在不同的时间从不同的视图控制器调用相同的Web服务的最佳方式是什么。我应该遵循什么架构或设计?我不想在每个视图控制器中编写相同的代码

我将编写一个网络管理器类,它将web服务参数(如果有的话)作为参数

这是一个粗略的架构示例

class YourNetworkManager {



     public func callSpecificWebService(argument : Type?, [optional closure to handle results]) {

          // Generate the actual URL to be called here. Usually by 
          // appending a suffix to some constant base url 

          // The web service call mechanism goes here.
          // This could either use the NSURLSession API 
          // or some third party library such as Alamofire

          // Process the generic response conditions from the web service  
          // here. Pass on the specific parts to the calling method.
       }
    }

正如我提到的,这是一个粗糙的例子。你能制造的东西越模块化,它就会越好

我将编写一个网络管理器类,它将web服务参数(如果有的话)作为参数

这是一个粗略的架构示例

class YourNetworkManager {



     public func callSpecificWebService(argument : Type?, [optional closure to handle results]) {

          // Generate the actual URL to be called here. Usually by 
          // appending a suffix to some constant base url 

          // The web service call mechanism goes here.
          // This could either use the NSURLSession API 
          // or some third party library such as Alamofire

          // Process the generic response conditions from the web service  
          // here. Pass on the specific parts to the calling method.
       }
    }

正如我提到的,这是一个粗糙的例子。你能制造的东西越模块化,它就会越好

您使用Alamofire吗?如果是,那么我有一个很好的方法,用NetworkHelper类编写

import Foundation
import Alamofire

open class NetworkHelper {

class var sharedManager: NetworkHelper {
    struct Static{
        static let instance: NetworkHelper = NetworkHelper()
    }
    return Static.instance
}

func request(_ method: HTTPMethod
    , _ URLString: String
    , parameters: [String : AnyObject]? = [:]
    , headers: [String : String]? = [:]
    , onView: UIView?, vc: UIViewController, completion:@escaping (Any?) -> Void
    , failure: @escaping (Error?) -> Void) {

    let URL = BASE_PATH + URLString
    Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
        .responseJSON { response in

            switch response.result {
            case .success:
                completion(response.result.value!)
            case .failure(let error):
                failure(error)
                guard error.localizedDescription == JSON_COULDNOT_SERIALISED else {
                    return
                }

            }
    }
}
}

您是否使用Alamofire?如果是,那么我有一个很好的方法,用NetworkHelper类编写

import Foundation
import Alamofire

open class NetworkHelper {

class var sharedManager: NetworkHelper {
    struct Static{
        static let instance: NetworkHelper = NetworkHelper()
    }
    return Static.instance
}

func request(_ method: HTTPMethod
    , _ URLString: String
    , parameters: [String : AnyObject]? = [:]
    , headers: [String : String]? = [:]
    , onView: UIView?, vc: UIViewController, completion:@escaping (Any?) -> Void
    , failure: @escaping (Error?) -> Void) {

    let URL = BASE_PATH + URLString
    Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
        .responseJSON { response in

            switch response.result {
            case .success:
                completion(response.result.value!)
            case .failure(let error):
                failure(error)
                guard error.localizedDescription == JSON_COULDNOT_SERIALISED else {
                    return
                }

            }
    }
}
}

如果使用Alamofire库,我可以建议使用

class NetworkManager {
static let shared = NetworkManager()

static let alamofireManager: SessionManager = {
    let sessionConfiguration = URLSessionConfiguration.default
    sessionConfiguration.timeoutIntervalForRequest = TimeInterval(_TIMEOUT)
    sessionConfiguration.timeoutIntervalForResource = TimeInterval(_TIMEOUT)
    return Alamofire.SessionManager(configuration: sessionConfiguration)
}()

func performRequest(url: String,
                    method: HTTPMethod = .get,
                    parameters: [String: Any] = [String: Any](),
                    encoding: ParameterEncoding = URLEncoding.default,
                    contentType: String? = nil,
                    headers: HTTPHeaders = [String: String](),
                    success: @escaping(Data, Int) -> (),
                    failure: @escaping(CustomError) -> ()) {

        debugPrint("NetworkManager is calling endpoint: \(url)")
        NetworkManager.alamofireManager.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).validate().response { response in
            guard let status = response.response?.statusCode, let data = response.data else {
                if let error = response.error {
                    debugPrint("Error when calling endpoint \(url)")
                    failure(.unknownError(message: error.localizedDescription))
                }
                return
            }
            debugPrint("HTTP Status received: \(status)")
            success(data, status)
       }
    } else {
        failure(.noNetworkConnection)
    }
}
请随意修改您的自定义错误或任何您喜欢的失败处理程序。
当然,您需要序列化响应。

如果使用Alamofire库,我建议使用

class NetworkManager {
static let shared = NetworkManager()

static let alamofireManager: SessionManager = {
    let sessionConfiguration = URLSessionConfiguration.default
    sessionConfiguration.timeoutIntervalForRequest = TimeInterval(_TIMEOUT)
    sessionConfiguration.timeoutIntervalForResource = TimeInterval(_TIMEOUT)
    return Alamofire.SessionManager(configuration: sessionConfiguration)
}()

func performRequest(url: String,
                    method: HTTPMethod = .get,
                    parameters: [String: Any] = [String: Any](),
                    encoding: ParameterEncoding = URLEncoding.default,
                    contentType: String? = nil,
                    headers: HTTPHeaders = [String: String](),
                    success: @escaping(Data, Int) -> (),
                    failure: @escaping(CustomError) -> ()) {

        debugPrint("NetworkManager is calling endpoint: \(url)")
        NetworkManager.alamofireManager.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).validate().response { response in
            guard let status = response.response?.statusCode, let data = response.data else {
                if let error = response.error {
                    debugPrint("Error when calling endpoint \(url)")
                    failure(.unknownError(message: error.localizedDescription))
                }
                return
            }
            debugPrint("HTTP Status received: \(status)")
            success(data, status)
       }
    } else {
        failure(.noNetworkConnection)
    }
}
请随意修改您的自定义错误或任何您喜欢的失败处理程序。 当然,您需要序列化响应。

为Alamofire请求创建一个基类,如下所示:

现在,您可以从任何位置调用此配置文件服务的doLogin方法,或者您可以创建更多类似于层的模型类并从模型类调用此服务,或者您可以像这样直接调用:

为Alamofire请求创建一个基类,如下所示:

现在,您可以从任何位置调用此配置文件服务的doLogin方法,或者您可以创建更多类似于层的模型类并从模型类调用此服务,或者您可以像这样直接调用:

切勿将视图和/或视图控制器传递给NetworkManager类。 假设您有这样一个NetworkManager类

open class NetworkHelper {

    class var sharedManager: NetworkHelper {
        struct Static{
            static let instance: NetworkHelper = NetworkHelper()
        }
        return Static.instance
    }

    func request(_ method: HTTPMethod, _ URLString: String, parameters: [String : AnyObject]? = [:], headers: [String : String]? = [:], completion:@escaping (Any?) -> Void, failure: @escaping (Error?) -> Void) {

        let URL = "BASE_PATH" + "URLString"
        Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
            .responseJSON { response in

                switch response.result {
                case .success:
                    completion(response.result.value!)
                case .failure(let error):
                    failure(error)
                    guard error.localizedDescription == JSON_COULDNOT_SERIALISED else {
                        return
                    }

                }
        }
    }
}
现在创建一个从UIViewController继承的BaseViewController,并用必要的参数编写API调用。 例如,在一个API调用中,您只需要userID,因为param其他所有的都是静态的

不,您应该继承那些需要相同API调用且不想再次编写代码的ViewController

class FirstChildViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.makeThisApiCallWithUserID(userId: 123)
    }
}
class SecondChildViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.makeThisApiCallWithUserID(userId: 13)
    }
}
class ThirdChildViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.makeThisApiCallWithUserID(userId: 3)
    }
}
请看,我没有在FirstChildViewController、SecondChildViewController、ThirdChildViewController中编写API代码,但它们仍然可以使用不同的参数进行相同的API调用。

永远不要将视图和/或视图控制器传递给NetworkManager类。 假设您有这样一个NetworkManager类

open class NetworkHelper {

    class var sharedManager: NetworkHelper {
        struct Static{
            static let instance: NetworkHelper = NetworkHelper()
        }
        return Static.instance
    }

    func request(_ method: HTTPMethod, _ URLString: String, parameters: [String : AnyObject]? = [:], headers: [String : String]? = [:], completion:@escaping (Any?) -> Void, failure: @escaping (Error?) -> Void) {

        let URL = "BASE_PATH" + "URLString"
        Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
            .responseJSON { response in

                switch response.result {
                case .success:
                    completion(response.result.value!)
                case .failure(let error):
                    failure(error)
                    guard error.localizedDescription == JSON_COULDNOT_SERIALISED else {
                        return
                    }

                }
        }
    }
}
现在创建一个从UIViewController继承的BaseViewController,并用必要的参数编写API调用。 例如,在一个API调用中,您只需要userID,因为param其他所有的都是静态的

不,您应该继承那些需要相同API调用且不想再次编写代码的ViewController

class FirstChildViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.makeThisApiCallWithUserID(userId: 123)
    }
}
class SecondChildViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.makeThisApiCallWithUserID(userId: 13)
    }
}
class ThirdChildViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.makeThisApiCallWithUserID(userId: 3)
    }
}
请看,我没有在FirstChildViewController、SecondChildViewController、ThirdChildViewController中编写API代码,但它们仍然可以使用不同的参数进行相同的API调用