Attaching [UInt8] as data to alamofire - swift

I am trying to uploading some bytes to a server using alamofire, my code is as follows:
let parameters: Parameters = ["data": data]
let headers: HTTPHeaders = ["Content-Type": "application/vnd.awallet-signed-orders-v0"]
Alamofire.request(query, method: .put,
parameters: parameters,
encoding: JSONEncoding.default,
headers: headers).responseJSON { response in
print("Request: \(String(describing: response.request))") // original url request
print("Response: \(String(describing: response.response))") // http url response
print("Result: \(response.result)") // response serialization result
if let json = response.result.value {
let parsedJSON = try! JSON(parseJSON: (json as! String))
callback(parsedJSON["orders"]["accepted"])
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)") // original server data as UTF8 string
}
}
}
The data is a [UInt8] however doing this makes alamofire cast the bytes as a string, if the array is [0,0] it becomes "0,0", this is not what I want as I want it to upload the bytes directly.
Is there a way to do this in alamofire?
Note: I don't want to cast it to a hex string as this is not efficient

Solved, just need to use the upload method and convert bytes to data
var hexMessageData = signedOrders[0].message
let headers: HTTPHeaders = ["Content-Type": "application/vnd.awallet-signed-orders-v0"]
Alamofire.upload(Data(bytes: hexMessageData), to: query, method: .put, headers: headers).response { response in
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)") // original server data as UTF8 string
callback(data.hexEncoded)
}
}

Related

Swift get request returning unauthorised

I'm using a get request to request data from predicthq, for some reason I keep receiving a response of {"error": "unauthorized"} as the JSON response. I've changed the API a few times now with no luck. I have tried it within Postman and the data is getting returned...
This is the python example they provide:
response = requests.get(
url="https://api.predicthq.com/v1/events",
headers={
"Authorization": "Bearer $ACCESS_TOKEN",
"Accept": "application/json"
}
)
This is the request I'm using, the API key is 100% correct as I've used it to make a request on their website:
let url = URL(string: "https://api.predicthq.com/v1/events")
guard let requestUrl = url else { fatalError() }
// Create URL Request
var request = URLRequest(url: requestUrl)
// Headers
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Accept")
// Specify HTTP Method to use
request.httpMethod = "GET"
// Send HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check if Error took place
if let error = error {
print("Error took place \(error)")
return
}
// Read HTTP Response Status code
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
// Convert HTTP Response Data to a simple String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
Edit: I have also tried using AlamoFire with the same result.
let path = "https://api.predicthq.com/v1/events"
let headers: HTTPHeaders = ["Authorization": "Bearer \(token)"]
AF.request(path, method: .get, headers: headers)
.responseJSON { (response) in
if let data = response.data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
Okay, the issue has been identified. "https://api.predicthq.com/v1/events" needs a / at the end and it works fine.

Swift 4 write a post request with Alamofire and Codable

I'm trying to send a post request with a Codable model via Alamofire.
Where do I put in the data that I've encoded? Thanks for your help in advance.
Here is my model that I'm sending
final class Score: Codable {
var id: Int?
var name: String
var level: Int
var userID: Int
init(
id: Int? = nil, name: String, level: Int, userID: Int) {
self.id = id
self.name = name
self.level = level
self.userID = userID
}
convenience init() {
self.init(name: "", level: 0, userID: 0)
}
}
Here is the function to send.
#IBAction func postWithAF(_ sender: Any) {
let anotherScore = Score()
anotherScore.level = 5
anotherScore.name = "Syd Luckenbach"
anotherScore.userID = 3
let jsonData = try encoder.encode(anotherScore)
let headers: HTTPHeaders = [
"Content-Type": "application/json"
]
Alamofire.request("http://192.168.1.5:8080/json/\(anotherScore)/addScore", method: .post, headers: headers, encoding: JSONEncoding.default).responseJSON { response in
print("Request: \(String(describing: response.request))") // original url request
print("Response: \(String(describing: response.response))") // http url response
print("Result: \(response.result)") // response serialization result
if let json = response.result.value {
print("JSON: \(json)") // serialized json response
self.textView.text = "JSON: \(json)"
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)") // original server data as UTF8 string
self.textView.text.append(" Data: \(utf8Text)")
}
}
}
Create URLRequest before sending the request via Alamofire. Try the example code:
var request = URLRequest(url: "http://192.168.1.5:8080/json/\(anotherScore)/addScore")!
request.setValue("application/json", "Content-Type")
request.httpMethod = .post
request.httpBody = jsonData
Alamofire.request(request).responseJSON {
(response) in
print(response)
}
You can achieve this in a single Alamofire line. For your example (with AF 5.x) this would look like
import Alamofire
func sendJSONViaPOSTRequest(data: Score) {
AF.request(
"some URL",
method: .post,
parameters: data,
encoder: JSONParameterEncoder.default,
// (Optionally) any additional headers.
// 'Content-Type: application/json' is applied automatically.
headers: yourHeaders)
// Followed by any downstream processing methods here
}

ios swift 3 Alamfire post request issue

enter image description hereenter image description hereenter image description hereI am using Alamofire. I am stuck in posting the post request.
I have a post body which is -
[
{
"siteName": "lab1",
"locationCode": "111",
"locationName": "test1"
}
]
How should I make the request call? I am doing -
let parameters: Parameters = [
"siteName": "lab",
"locationCode": "1156",
"locationName": "123test"
]
Alamofire.request(URLStr, method: .post, parameters: parameters , encoding: JSONEncoding.default, headers: headers).responseJSON { response in
print("Request: \(String(describing: response.request))") // original url request
print("Response: \(String(describing: response.response))") // http url response
print("Result: \(response.result)") // response serialization result
if let json = response.result.value {
print("JSON: \(json)") // serialized json response
sucessHandler(json)
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)") // original server data as UTF8 string
failureHandler(response.error)
}
}
Thank you so much guys. I found the other way of doing this.
let fileUrl = NSURL(string: URLStr)
var request = URLRequest(url:fileUrl as! URL )
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let values = [parameters]
request.httpBody = try! JSONSerialization.data(withJSONObject: values)
Alamofire.request(request)
.responseJSON { response in
// do whatever you want here
switch response.result {
case .failure(let error):
print(error)
if let data = response.data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
failureHandler(response.error)
}
case .success(let responseObject):
print(responseObject)
do {
let user = try IeroLocationSave(JSONDecoder(response.data ?? "nil..12"))
//print("city is: \(user.address.city)")
sucessHandler(user)
//That's it! The object has all the appropriate properties mapped.
} catch {
print("unable to parse the JSON")
}
}
}
Below code works for me
let parameters: Parameters = ["feedback_name": "SwiftTest","feedback_email":"m#m.com","feedback_description":"Test"]
Alamofire.request("http://212.69.45.77:8082/api/feedbackapp",method: .post,parameters: parameters).responseJSON { response in
print("Request: \(String(describing: response.request))") // original url request
print("Response: \(String(describing: response.response))") // http url response
print("Result: \(response.result)") // response serialization result
if let json = response.result.value {
print("JSON: \(json)") // serialized json response
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)") // original server data as UTF8 string
}
}

Migrating from URLSession to Alamofire 4.3 in Swift 3, Encoding issue

What is the equivalent code of the following in Alamofire 4.3,Swift 3?
let baseUrl = "https://hiddenWebsite.com/api/index_load"
let url = URL(string: baseUrl)
let authObj = ["owner_id": "361900", "auth_key": "f408634ac1e14c08eebce46c34ab9db2", "device": "2", "version": "2.1.16"]
let infoObj = ["case": "feeds", "feeds_call_type": "init", "feed_type": "", "load_next_from": "1"]
let infoJSONData = try! JSONSerialization.data(withJSONObject: infoObj)
let infoStr = "info" + "=" + String(data: infoJSONData, encoding: String.Encoding.utf8)!
let authJSONData = try! JSONSerialization.data(withJSONObject: authObj)
let authStr = "auth" + "=" + String(data: authJSONData, encoding: String.Encoding.utf8)!
let combinedStr = infoStr + "&" + authStr
let reqdat = combinedStr.data(using: String.Encoding.utf8)
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.httpBody = reqdat
let defaultSession = URLSession.shared
defaultSession.dataTask(
with: request,
completionHandler: { data, response, error in
guard error == nil else {
print("Error while fetching data: \(error)")
return
}
guard let data = data,
let json = try? JSONSerialization.jsonObject(
with: data,
options: JSONSerialization.ReadingOptions.mutableContainers)
else {
print("Nil data received")
return
}
print(json)
}).resume()
I'm currently migrating from Apple's URLSession to Alamofire, but stuck at this point. I think this has something to do with encodingParameter.
This is my failed attempt. I also tried with URLEncoding.httpbody but didn't work.
let baseUrl = "https://hiddenWebsite.com/api/index_load"
let masterParameter = [
"auth": ["owner_id": "361900",
"auth_key": "f408634ac1e14c08eebce46c34ab9db2",
"device": "2",
"version": "2.1.16"],
"info": ["case": "feeds",
"feeds_call_type": "init",
"feed_type": "",
"load_next_from": "1"]
]
Alamofire.request(baseUrl, method: .post, parameters: masterParameter, encoding: JSONEncoding.default).responseJSON { (response) in
print(response)
}
The working postman equivalent of this looks like
Postman Screenshot
The encoding you are using it not valid JSON. Therefore, you cannot use JSON.default as your encoding type because it will encode your masterParameter dictionary as a valid JSON dictionary.
Instead, you either need to build your URLRequest manually as you have done in your first example and use the Alamofire.request(urlRequest) API, or you can create your own ParameterEncoding where you pass your data into it then encode the URLRequest.
Thanks cnoon for answering. The following code solved the issue:
public enum JSONError: Error {
case serializing(String)
case encoding
}
extension String: ParameterEncoding {
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try urlRequest.asURLRequest()
request.httpBody = self.data(using: String.Encoding.utf8)
return request
}
}
let encodedStr = try getEncodedString(parameters: masterParameter)
Alamofire.request(baseUrl, method: .post, parameters: [:], encoding: encodedStr).responseJSON { response in
print(response)
}
where getEncodedString(parameters:) is defined as:
func getEncodedString(parameters: Parameters) throws -> String {
var encodedStr = ""
for (key, value) in parameters {
let jsonData: Data
do {
jsonData = try JSONSerialization.data(withJSONObject: value)
}
catch(let error) {
throw JSONError.serializing(error.localizedDescription)
}
guard let encodedJsonString = String(data: jsonData, encoding: .utf8) else {
throw JSONError.encoding
}
let keyValueStr = key + "=" + encodedJsonString
encodedStr += keyValueStr + "&"
}
if encodedStr.characters.last == "&" {
encodedStr.remove(at: encodedStr.index(before: encodedStr.endIndex))
}
return encodedStr
}

Translating Alamofire call to URLSession

I've got a old codebase that I'm trying to migrate out of. The network calls currently use Alamofire 4.0 and I'm trying to use URLSession instead. I'm having trouble figuring out what's wrong, here's what I've been doing. I start off with the route and params that I want to post:
// route to user creation
let url = ...
let params = ["user": ["first_name": "John", "last_name": "Appleseed", "email": "john#apple.com", "password": "asdfgh"]]
Here's the old and new network calls:
// old network request
Alamofire.request(url, method: .post, parameters: newUser, encoding: JSONEncoding.default).responseJSON { response in
// ...
}
// new code
var request = URLRequest(url: url)
let jsonData = try! JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.httpBody = jsonData
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { return print("error=\(error)") }
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("status code should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
For some reason, I'm getting a status code of 400 in my URLSession attempt. Alamofire works fine.
Any advice appreciated.
The problem is that the request isn't recognized as a JSON call. Write the following assignment after you create your URLRequest:
request.allHTTPHeaderFields = ["Content-Type": "application/json"]