Sample code for 30+ languages & platforms
Swift Requires Chilkat v11.0.0+

Xero API through an SOCKS Proxy

This example demonstrates connecting through a SOCKS proxy w/ 2-legged OAuth for a Xero private application.

Chilkat Swift Downloads

Swift

func chilkatTest() {
    var success: Bool = false

    //  This sample code would typically be placed in a subroutine or function
    //  where the rest object is passed by reference.
    //  It does the OAuth1 setup and makes the initial connection.
    let rest = CkoRest()!

    //  Connect to the Xero server through an HTTP proxy, and then tell the REST object
    //  to use the socket connection.
    let socket = CkoSocket()!

    //  Set the SOCKS proxy domain or IP address, port, and SOCKS version number (4 or 5)
    socket.socksHostname = "192.168.1.100"
    socket.socksPort = 1080
    socket.socksVersion = 5
    //  Other properties exist for specifying a SOCKS proxy login and password,
    //  but these are not used in this example.

    //  Connect through the SOCKS proxy..
    var bTls: Bool = true
    var port: Int = 443
    var maxWaitMs: Int = 5000
    success = socket.connect(hostname: "api.xero.com", port: port, ssl: bTls, maxWaitMs: maxWaitMs)
    if success != true {
        print("Connect Failure Error Code: \(socket.connectFailReason.intValue)")
        print("\(socket.lastErrorText!)")
        return
    }

    //  Use the SOCKS proxied TLS connection:
    success = rest.useConnection(connection: socket, autoReconnect: true)
    if success == false {
        print("\(rest.lastErrorText!)")
        return
    }

    //  OK, we're connected.  
    //  The UseConnection method has an internal reference to the underlying/internal socket.
    //  The application can does not need to keep its socket object in existence.
    //  -----------------------------------------------------------------
    //  Now setup the OAuth1 authenticator..

    var consumerKey: String? = "XERO_PRIVATE_APP_KEY"
    var consumerSecret: String? = "XERO_PRIVATE_APP_SECRET"

    //  Let's get our private key from our PFX (password protected), or the PEM (unprotected).
    //  You can decide which to use.  Either is OK, although I would recommend keeping your
    //  private keys in a PFX and not in an unprotected PEM.
    let pfx = CkoPfx()!
    success = pfx.loadFile(path: "qa_data/certs/xero_private_app/public_privatekey.pfx", password: "PFX_PASSWORD")
    if success == false {
        print("\(pfx.lastErrorText!)")
        return
    }

    let privKeyFromPfx = CkoPrivateKey()!
    success = pfx.privateKey(at: 0, privKey: privKeyFromPfx)
    if success == false {
        print("\(pfx.lastErrorText!)")
        return
    }

    //  Or we can load from a PEM..
    let privKeyFromPem = CkoPrivateKey()!
    success = privKeyFromPem.loadPemFile(path: "qa_data/certs/xero_private_app/privatekey.pem")
    if success == false {
        print("\(privKeyFromPem.lastErrorText!)")
        return
    }

    //  Note: There are many other means for loading a private key, including
    //  from other formats and directly from memory (i.e. not file-based).

    let oauth1 = CkoOAuth1()!
    oauth1.consumerKey = consumerKey
    oauth1.consumerSecret = consumerSecret
    oauth1.token = consumerKey
    oauth1.tokenSecret = consumerSecret
    oauth1.signatureMethod = "RSA-SHA1"
    oauth1.setRsaKey(privKey: privKeyFromPfx)

    //  Install the OAuth1 authenticator.
    rest.setAuthOAuth1(authProvider: oauth1, useQueryParams: false)

    print("OK, the Xero OAuth1 is initialized and the REST object is ready to make REST API calls..")

    //  -----------------------------------------------------------------
    //  Make a call to verify that OAuth1 through an HTTP proxy works..

    //  Get the full list of contacts.
    let sbXml = CkoStringBuilder()!
    success = rest.fullRequestNoBodySb(httpVerb: "GET", uriPath: "/api.xro/2.0/Contacts", sb: sbXml)
    if success == false {
        print("\(rest.lastErrorText!)")
        return
    }

    //  A 200 response is expected for actual success.
    if rest.responseStatusCode.intValue != 200 {
        print("\(sbXml.getAsString()!)")
        return
    }

    //  Iterate over the contacts..
    var bAutoTrim: Bool = false
    let xml = CkoXml()!
    xml.loadSb(sb: sbXml, autoTrim: bAutoTrim)
    xml.save(path: "qa_cache/xero_contacts.xml")

    //  How many records exist?
    var recordCount: Int = xml.numChildren(at: "Contacts").intValue
    print("numRecords = \(recordCount)")

    var i: Int = 0
    while i < recordCount {
        xml.i = i
        print("ContactID: \(xml.getChildContent(tagPath: "Contacts|Contact[i]|ContactID")!)")
        i = i + 1
    }


}