Swift
import Foundation
import CryptoSwift
extension URLSession {
func synchronousDataTask(with request: URLRequest) -> (Data?, URLResponse?, Error?) {
var data: Data?
var response: URLResponse?
var error: Error?
let semaphore = DispatchSemaphore(value: 0)
let dataTask = self.dataTask(with: request) {
data = $0
response = $1
error = $2
semaphore.signal()
}
dataTask.resume()
_ = semaphore.wait(timeout: .distantFuture)
return (data, response, error)
}
}
class RFGAPI {
private enum Constants {
static let apiURL = "https://api.researchforgood.com/API"
static let apid = ""
static let secretHex = ""
}
public func sendTestCommand() {
let command = "{ \"command\" : \"test/copy/1\" , \"data1\" : \"THIS IS A TEST\"}";
if let response = send(command: command) {
print("Received Response: \(response)")
}
}
public func send(command: String) -> String? {
print("Sending command: \(command)")
let time = Int(Date().timeIntervalSince1970)
let packet = "\(time)\(command)"
let key = Array<UInt8>(hex: Constants.secretHex)
let bytesCommand = packet.bytes
do {
let bytes: [UInt8] = try HMAC(key: key, variant: .sha1).authenticate(bytesCommand)
let data = Data(bytes: bytes)
let hashString = data.bytes.toHexString()
let urlString = "\(Constants.apiURL)?apid=\(Constants.apid)&time=\(time)&hash=\(hashString)"
guard let url = URL(string: urlString) else {
print("Error: Cannot generate URL from string. Bailing...")
return nil
}
let urlSession = URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("\(command.count)", forHTTPHeaderField: "Content-Length")
request.httpBody = command.data(using: .utf8)
let (_responseData, _, error) = urlSession.synchronousDataTask(with: request)
if let error = error {
print("Error: \(error)")
return nil
}
guard let responseData = _responseData else {
print("Error: Could not receive data.")
return nil
}
if let responseString = String(data: responseData, encoding: .utf8) {
return responseString
} else {
print("Decoding to string failed.")
return nil
}
} catch {
print("Could not hash: \(error)")
return nil
}
}
}
Download the complete Swift example here.