在Swift中进行REST API调用

ccl*_*oyd 82 api rest http ios swift

我正在尝试使用Swift对REST API进行GET调用,并试图遵循大量的教程,但无法弄明白.或者因为我无法弄清楚如何将所有Obj-C翻译成Swift,或者因为这些方法的一半被弃用了.有谁知道如何进行调用,并解析返回的JSON数据?

jau*_*ard 60

你可以这样做:

var url : String = "http://google.com?test=toto&test2=titi"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
    var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
    let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary

    if (jsonResult != nil) {
        // process jsonResult
    } else {
       // couldn't load JSON, look at error
    }


})
Run Code Online (Sandbox Code Playgroud)

编辑:对于人们有这个问题可能你的JSON流是一个数组[]而不是一个对象{}所以你必须改变jsonResult NSArray而不是NSDictionary

  • 实际上,在Swift中使用带闭包的异步方法要好得多,因为语言本身就是为此而设计的. (5认同)
  • 出于某种原因,当我进行api调用时,我收到0x0000000000000000错误.我不知道怎么解决它.谁能指出我正确的方向? (2认同)
  • @TiffanyLowe发现错误!如果其他人需要一个可行的解决方案:如果你的JSON响应以数组的形式出现,那么jsonResult应该被"转换"为NSArray而不是NSDictionary. (2认同)

Har*_*dim 38

斯威夫特4

let params = ["username":"john", "password":"123456"] as Dictionary<String, String>

var request = URLRequest(url: URL(string: "http://localhost:8080/api/1/login")!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")

let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
    print(response!)
    do {
        let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, AnyObject>
        print(json)
    } catch {
        print("error")
    }
})

task.resume()
Run Code Online (Sandbox Code Playgroud)


mus*_*afa 23

我认为NSURLSessionapi在这种情况下更适合.因为如果你编写swift代码,你的项目目标至少是iOS 7,而iOS 7支持NSURLSessionapi.无论如何这里是代码

let url = "YOUR_URL"

NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)) { data, response, error in
    // Handle result
}.resume()
Run Code Online (Sandbox Code Playgroud)


Nar*_*tty 20

以下是在swift中使用NSURLSession的REST API请求的完整代码

For GET Request

 let configuration = NSURLSessionConfiguration .defaultSessionConfiguration()
    let session = NSURLSession(configuration: configuration)


    let urlString = NSString(format: "your URL here")

    print("get wallet balance url string is \(urlString)")
    //let url = NSURL(string: urlString as String)
    let request : NSMutableURLRequest = NSMutableURLRequest()
    request.URL = NSURL(string: NSString(format: "%@", urlString) as String)
    request.HTTPMethod = "GET"
    request.timeoutInterval = 30

    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let dataTask = session.dataTaskWithRequest(request) {
        (let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in

        // 1: Check HTTP Response for successful GET request
        guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
            else {
                print("error: not a valid http response")
                return
        }

        switch (httpResponse.statusCode)
        {
        case 200:

            let response = NSString (data: receivedData, encoding: NSUTF8StringEncoding)
            print("response is \(response)")


            do {
                let getResponse = try NSJSONSerialization.JSONObjectWithData(receivedData, options: .AllowFragments)

                EZLoadingActivity .hide()

               // }
            } catch {
                print("error serializing JSON: \(error)")
            }

            break
        case 400:

            break
        default:
            print("wallet GET request got response \(httpResponse.statusCode)")
        }
    }
    dataTask.resume()
Run Code Online (Sandbox Code Playgroud)

对于POST请求...

let configuration = NSURLSessionConfiguration .defaultSessionConfiguration()
    let session = NSURLSession(configuration: configuration)

    let params = ["username":bindings .objectForKey("username"), "provider":"walkingcoin", "securityQuestion":securityQuestionField.text!, "securityAnswer":securityAnswerField.text!] as Dictionary<String, AnyObject>

    let urlString = NSString(format: “your URL”);
    print("url string is \(urlString)")
    let request : NSMutableURLRequest = NSMutableURLRequest()
    request.URL = NSURL(string: NSString(format: "%@", urlString)as String)
    request.HTTPMethod = "POST"
    request.timeoutInterval = 30
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")      
    request.HTTPBody  = try! NSJSONSerialization.dataWithJSONObject(params, options: [])

    let dataTask = session.dataTaskWithRequest(request)
        {
            (let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in
            // 1: Check HTTP Response for successful GET request
            guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
                else {
                    print("error: not a valid http response")
                    return
            }

            switch (httpResponse.statusCode)
            {
            case 200:

                let response = NSString (data: receivedData, encoding: NSUTF8StringEncoding)


                if response == "SUCCESS"
                {

                }

            default:
                print("save profile POST request got response \(httpResponse.statusCode)")
            }
    }
    dataTask.resume()
Run Code Online (Sandbox Code Playgroud)

我希望它有效.


小智 10

编辑为swift 2

let url = NSURL(string: "http://www.test.com")

    let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
        print(NSString(data: data!, encoding: NSUTF8StringEncoding))
    }

    task.resume()
Run Code Online (Sandbox Code Playgroud)


Jyo*_*sua 8

Swift 4 - GET请求

var request = URLRequest(url: URL(string: "http://example.com/api/v1/example")!)
request.httpMethod = "GET"

URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
    do {
        let jsonDecoder = JSONDecoder()
        let responseModel = try jsonDecoder.decode(CustomDtoClass.self, from: data!)
        print(responseModel)
    } catch {
        print("JSON Serialization error")
    }
}).resume()
Run Code Online (Sandbox Code Playgroud)

不要忘记配置应用程序传输安全设置以将域添加到例外,并在不使用HTTPS的情况下访问端点时允许不安全的http请求.

您可以使用http://www.json4swift.com/等工具从JSON响应中自动生成可编码映射.


Flo*_*s M 5

斯威夫特3.0

let request = NSMutableURLRequest(url: NSURL(string: "http://httpstat.us/200")! as URL)
let session = URLSession.shared
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
      if error != nil {
          print("Error: \(String(describing: error))")
      } else {
          print("Response: \(String(describing: response))")
      }
 })

 task.resume()
Run Code Online (Sandbox Code Playgroud)


Ton*_*zis 5

斯威夫特 4

使用 Alamofire 和 Api Post 方法创建应用程序

使用 Xcode 9 为 Swift 3 安装 pod 文件 -pod 'Alamofire', '~> 4.0'

创建 Webservices.swift 类,导入 Alamofire

设计故事板,登录查看

为 ViewControllerClass 插入以下代码

import UIKit

class ViewController: UIViewController {

    @IBOutlet var usernameTextField: UITextField!

    @IBOutlet var passwordTextField: UITextField!
    var usertypeStr :String = "-----------"
    var loginDictionary : NSDictionary?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func loginButtonClicked(_ sender: Any) {
        WebServices.userLogin(userName: usernameTextField.text!, password: passwordTextField.text!,userType: usertypeStr) {(result, message, status )in
            if status {
                let loginDetails = result as? WebServices
                self.loginDictionary = loginDetails?.loginData
                if self.loginDictionary?["status"] as? String == "error"
                {
                    self.alertMessage(alerttitle: "Login Error", (self.loginDictionary?["message"] as? String)!)
                } else if self.loginDictionary?["status"] as? String == "ok" {
                    self.alertMessage(alerttitle: "", "Success")

                }else {
                    self.alertMessage(alerttitle: "", (self.loginDictionary?["message"] as? String)!)
                }
            } else {
                self.alertMessage(alerttitle: "", "Sorry")
            }
        }
    }

    func alertMessage(alerttitle:String,_ message : String){
        let alertViewController = UIAlertController(title:alerttitle,  message:message, preferredStyle: .alert)
        alertViewController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(alertViewController, animated: true, completion: nil)
    }

}
Run Code Online (Sandbox Code Playgroud)

为 WebserviceClass 插入以下代码

import Foundation
import Alamofire
class WebServices: NSObject {
    enum WebServiceNames: String {
        case baseUrl = "https://---------------"
        case UserLogin = "------------"
    }

    // MARK: - Login Variables
    var loginData : NSDictionary?

    class func userLogin(userName: String,password : String,userType : String, completion : @escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> ()) {
        let url = WebServiceNames.baseUrl.rawValue + WebServiceNames.UserLogin.rawValue
        let params = ["USER": userName,"PASS":password,"API_Key" : userType]
        WebServices.postWebService(urlString: url, params: params as [String : AnyObject]) { (response, message, status) in
            print(response ?? "Error")
            let result = WebServices()
            if let data = response as? NSDictionary {
                print(data)
                result.loginData = data
                completion(result, "Success", true)

            }else {
                completion("" as AnyObject?, "Failed", false)
            }
        }
    }
    //MARK :- Post
    class func postWebService(urlString: String, params: [String : AnyObject], completion : @escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> Void) {
        alamofireFunction(urlString: urlString, method: .post, paramters: params) { (response, message, success) in
            if response != nil {
                completion(response as AnyObject?, "", true)
            }else{
                completion(nil, "", false)
            }
        }
    }

    class func alamofireFunction(urlString : String, method : Alamofire.HTTPMethod, paramters : [String : AnyObject], completion : @escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> Void){

        if method == Alamofire.HTTPMethod.post {
            Alamofire.request(urlString, method: .post, parameters: paramters, encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in

                print(urlString)

                if response.result.isSuccess{
                    completion(response.result.value as AnyObject?, "", true)
                }else{
                    completion(nil, "", false)
                }
            }

        }else {
            Alamofire.request(urlString).responseJSON { (response) in

                if response.result.isSuccess{
                    completion(response.result.value as AnyObject?, "", true)
                }else{
                    completion(nil, "", false)
                }
            }
        }
    }



    //Mark:-Cancel
    class func cancelAllRequests()
    {
        Alamofire.SessionManager.default.session.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in
            dataTasks.forEach { $0.cancel() }
            uploadTasks.forEach { $0.cancel() }
            downloadTasks.forEach { $0.cancel() }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Gur*_*ngh 5

在 swift 3.3 和 4 中。我用两个公共方法创建了 APIManager 类。只需传递必需的参数、api 名称和请求类型。您将获得响应,然后将其传递给闭包。

 import UIKit   

    struct RequestType {
      static let  POST = "POST"
      static let  GET = "GET"
    }

    enum HtttpType: String {
      case POST = "POST"
      case GET  = "GET"
    }

    class APIManager: NSObject {


      static let sharedInstance: APIManager = {

        let instance = APIManager()
        return instance
      }()
     private init() {}
        // First Method

          public func requestApiWithDictParam(dictParam: Dictionary<String,Any>, apiName: String,requestType: String, isAddCookie: Bool, completionHendler:@escaping (_ response:Dictionary<String,AnyObject>?, _ error: NSError?, _ success: Bool)-> Void) {

            var apiUrl = “” // Your api url
            apiUrl =  apiUrl.appendingFormat("%@", apiName)
            let config = URLSessionConfiguration.default
            let session = URLSession(configuration: config)
            let url = URL(string: apiUrl)!
            let HTTPHeaderField_ContentType  = "Content-Type"
            let ContentType_ApplicationJson  = "application/json"
            var request = URLRequest.init(url: url)

            request.timeoutInterval = 60.0
            request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
            request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
            request.httpMethod = requestType

            print(apiUrl)
            print(dictParam)

            let dataTask = session.dataTask(with: request) { (data, response, error) in

              if error != nil   {
                completionHendler(nil, error as NSError?, false)
              } do {
                let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
                print("Request API = ", apiUrl)
                print("API Response = ",resultJson ?? "")
                completionHendler(resultJson, nil, true)

              } catch {
                completionHendler(nil, error as NSError?, false)
              }
            }
            dataTask.resume()
          }

           // Second Method
           public func requestApiWithUrlString(param: String, apiName: String,requestType: String, isAddCookie: Bool, completionHendler:@escaping (_ response:Dictionary<String,AnyObject>?, _ error: NSError?, _ success: Bool)-> Void ) {
                var apiUrl = "" // Your api url
                let config = URLSessionConfiguration.default
                let session = URLSession(configuration: config)            
                var request: URLRequest?

                if requestType == "GET" {

                  apiUrl =  String(format: "%@%@&%@", YourAppBaseUrl,apiName,param)
                  apiUrl = apiUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
                  print("URL=",apiUrl)

                  let url = URL(string: apiUrl)!
                  request = URLRequest.init(url: url)
                  request?.httpMethod = "GET"

                } else {

                  apiUrl =  String(format: "%@%@", YourAppBaseUrl,apiName)
                  apiUrl = apiUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
                  print("URL=",apiUrl)

                  let bodyParameterData = param.data(using: .utf8)
                  let url = URL(string: apiUrl)!

                  request = URLRequest(url: url)
                  request?.httpBody = bodyParameterData
                  request?.httpMethod = "POST"
                }

                request?.timeoutInterval = 60.0
                request?.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
                request?.httpShouldHandleCookies = true

                let dataTask = session.dataTask(with: request!) { (data, response, error) in

                  if error != nil {
                    completionHendler(nil, error as NSError?, false)
                  } do {
                    if data != nil  {
                      let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]

                      print("Request API = ", apiUrl)
                      print("API Response = ",resultJson ?? "")
                      completionHendler(resultJson, nil, true) 
                    } else  {
                      completionHendler(nil, error as NSError?, false)
                    }
                  } catch {
                    completionHendler(nil, error as NSError?, false)
                  }
                }
                dataTask.resume()
              }
    }

    // Here is example of calling Post API from any class

     let bodyParameters = String(format: "appid=%@&appversion=%@","1","1")
            APIManager.sharedInstance.requestApiWithUrlString(param: bodyParameters, apiName: "PASS_API_NAME", requestType: HtttpType.POST.rawValue, isAddCookie: false) { (dictResponse, error, success) in

                if success {
                    if let dictMessage = dictResponse?["message"] as? Dictionary<String, AnyObject> {
                // do you work
                    }

                }  else {
                    print("Something went wrong...")
                }
            }
        }


/// Or just use simple function 

func dataRequest() {
    let urlToRequest = "" // Your API url

    let url = URL(string: urlToRequest)!
    let session4 = URLSession.shared
    let request = NSMutableURLRequest(url: url)
    request.httpMethod = "POST"
    request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
    let paramString = "data=Hello"
    request.httpBody = paramString.data(using: String.Encoding.utf8)
    let task = session4.dataTask(with: request as URLRequest) { (data, response, error) in
      guard let _: Data = data, let _: URLResponse = response, error == nil else {
        print("*****error")
        return
      }
      if let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) {
          print("****Data: \(dataString)") //JSONSerialization
      }
    }
    task.resume()
  }
Run Code Online (Sandbox Code Playgroud)