Search code examples
iosjsonswiftalamofire

How to use Wordpress REST API in iOS app?


I need to use WP REST API in my ios app, for now I'm using Alamofire and SwiftyJSON.

func requestAlamofireToSwiftyJSON(_ url:String, completion: @escaping (JSON?, Bool, Success) -> ()) {

    let manager = Alamofire.SessionManager.default
    manager.session.configuration.timeoutIntervalForRequest = TIMEOUT
    manager.session.configuration.timeoutIntervalForResource = TIMEOUT

    manager.request(url).responseJSON { (response) -> Void in

        switch response.result {

        case .success:

            guard let value = response.result.value else {
                return
            }

            let json = JSON(value)
            DLog(message:json)

            completion(json, true, .loadOK)

        case .failure(let error):

            DLog(message:"failure")
            DLog(message:"\n\nAuth request failed with error:\n \(error)")

            if error._code == NSURLErrorTimedOut {
                //HANDLE TIMEOUT HERE
                completion(nil, false, .timeOut)

            } else {
                completion(nil, false, .loadError)
            }             
        }        
    }     
}

Logs:

{
   "code" : "rest_cannot_access",
   "data" : {
   "status" : 401
    },
 "message" : "Only authenticated users can access the REST API."
}

I need to auhentificate me, according to the WP rest API documentation, but I have no idea how to do this in SWIFT.

EDIT 1

Almost :) Why this code works? JSON is displayed in the console.

    var headers: HTTPHeaders = [
        "Content-Type": "application/json"
    ]

    let user = "userblablabla"
    let password = "pwdblablabla"

    if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
        headers[authorizationHeader.key] = authorizationHeader.value
    }

    Alamofire.request(url, headers:headers).responseJSON{ response in

        DLog(message:url)

        switch response.result {

        case .success:

            guard let value = response.result.value else {
                return
            }

            let json = JSON(value)
            DLog(message:json)

            completion(json, true, .loadOK)

        case .failure(let error):

            DLog(message:"failure")
            DLog(message:"\n\nAuth request failed with error:\n \(error)")

            if error._code == NSURLErrorTimedOut {
                //HANDLE TIMEOUT HERE
                completion(nil, false, .timeOut)

            } else {
                completion(nil, false, .loadError)
            }
        }
    }

And why this code doesn't work? Error 401 (see above)

let headers = [ "Content-Type": "application/json","X-Requested-With": "XMLHttpRequest","Cache-Control": "no-cache"]

    let manager = Alamofire.SessionManager.default
    manager.session.configuration.timeoutIntervalForRequest = TIMEOUT
    manager.session.configuration.timeoutIntervalForResource = TIMEOUT

    manager.request(url).authenticate(user: "userblablabla", password: "pwdblablabla").responseJSON { (response) -> Void in

        switch response.result {

        case .success:

            guard let value = response.result.value else {
                return
            }

            let json = JSON(value)
            DLog(message:json)

            completion(json, true, .loadOK)

        case .failure(let error):

            DLog(message:"failure")
            DLog(message:"\n\nAuth request failed with error:\n \(error)")

            if error._code == NSURLErrorTimedOut {
                //HANDLE TIMEOUT HERE
                completion(nil, false, .timeOut)

            } else {
                completion(nil, false, .loadError)
            }
        }
    }

Solution

  • It seems you're missing headers with your username and password to access the data. One more thing that I can mention, is to make sure to make it private. Otherwise other users could access the wordpress calls and maybe edit posts and stuff.

    var headers: HTTPHeaders = [:]
    
    // Pass in the username and the password in the authorizationHeader
    if let authorizationHeader = Request.authorizationHeader(user: YOURUSERNAME, password: YOURPASSWORD) {
        headers[authorizationHeader.key] = authorizationHeader.value
    }
    
    // Request with headers
    Alamofire.request(url, method: .get, headers: headers).responseJSON { (response) in
        switch response.result {
        case .success(let value):
            // Handle success
        case .failure(let error):
            // Handle error
        }
    }