I built a REST WS using dot net 4.5. When I verified it using the Chrome app Advanced Rest Client I get
request: http://mySite.azurewebsites.net/api/tech
with GET selected
The tool reports a status code of 200 and a JSON response of:
[{"fName":"Fred","lName":"Flintstone"},{"fName":"Barney","lName":"Rubble"}]
Over in XCode, using Swift I try a button that calls hitMyWS():
func hitMyWS(){
var url : String = "http://mySite.azurewebsites.net/api/Tech"
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
println("it worked")
} else {
// couldn't load JSON, look at error
println("kablooey")
}
}) }
In the console I get "kablooey"
This is my first attempt at REST web services and Swift, please advise.
Related
In my AWS project, I created webservices using Lambda and API Gateway.
Those webservices are called by my iOS app, using the Amplify framework.
In my lambda functions:
I return something like the following when there is no error:
return {
statusCode: 200,
body: JSON.stringify({
"example_key_1": "example_value",
"example_key_2": 123456789
})
};
I return something like the following when there is an error:
return {
statusCode: 400,
body: JSON.stringify({
"custom_error_code": 333333
})
};
And from my iOS app, I call my API by doing something like the following:
Amplify.API.post(request: request) { result in
switch result
{
case .success(let data):
print("success: \(data)")
case .failure(let error):
print("error: \(error)"
}
}
Now, here are the infos I need to get from the response of the API:
the status code, when there is an error
the body of the response, whether there is an error or not
In other words, I need to get in my iOS app the whole content of each return of the lambda, when I call the API.
It seems easily doable with the Amplify framework for Javascript, according to this, but I can't find the equivalent for iOS or Android.
How can I achieve that with the Amplify framework?
Thanks.
Amplify Android
val body = JSONObject()
.put("name", "Mow the lawn")
.toString()
.toByteArray()
val request = RestOptions.builder()
.addPath("/todo")
.addBody(body)
.build()
Amplify.API.post(request,
{ response ->
if (!response.code.isSuccessful()) {
Log.w("TAG", "non-200 return code")
} else {
val data = repsonse.data.asString()
Log.i("Demo", "OK! Data = $data")
}
},
{ failure ->
Log.e("Demo", "No response from server", failure)
}
)
Amplify iOS
let request = RESTRequest(path: "/todo", body: "my new Todo".data(using: .utf8))
Amplify.API.post(request: request) { result in
switch result {
case .success(let data):
let str = String(decoding: data, as: UTF8.self)
print("Success \(str)")
case .failure(let apiError):
switch apiError {
case .httpStatusError(_, let response):
println("\(response.statusCode)")
else:
println("No response from server")
}
}
}
I had the same problem as yours when developing integrating API Gateway in iOS project. Actually I raised a PR for that. Take a look.. Unfortunately they closed that PR. But anyway I started using my own fork for my project. It has been live for 2 months. And I haven't faced any issues.
Hope it would help.
From version 1.7 you can use:
if case let .httpStatusError(statusCode, response) = error, let awsResponse = response as? AWSHTTPURLResponse {
if let responseBody = awsResponse.body {
print("Response contains a \(responseBody.count) byte long response body")
}
}
As stated in PR #1076
Please assist in figuring out how do I make REST API GET/POST/DELETE/PUT using swift 3 and in playground.
Examples I got from search don't work as expacted. Also I want to consume Laravel REST API first using GET method.
import Foundation
let headers = ["content-type": "application/json"]
let request = NSMutableURLRequest(url: NSURL(string: "http://localhost:8088/api/person")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
To run asynchronous code in a Playground you have to add these two lines
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
You are mixing up GET and POST semantics.
In a GET request the parameters are included in the URL (http://example.com/api?key1=value1&key2=value2)
In a POST request the parameters are passed in the HTTP body
Note: In Swift 3+ don't use NSURL and NSMutableURLRequest. Use the native API
I am trying to use microsoft face recognition for my app. I have signed up for an account and started to implement into my app but cannot get any response except for 404 resource not found. Any ideas as to where I should start with this one?
import Foundation
import Alamofire
class CognitiveService {
static let instance = CognitiveService()
static let apiKey = API_KEY /// set in constants file
static let apiUrl = FACE_DETECT_URL /// set in constants file
func test() {
var header = [String : String]()
header["Ocp-Apim-Subscription-Key"] = CognitiveService.apiKey
let url = "any web address to image here"
let params:[String: String] = ["url": url]
let request = Alamofire.request(CognitiveService.apiUrl, parameters: params, headers: header)
print("\(request)")
request.responseJSON { (response) in
print(response)
}
}
}
Assuming FACE_DETECT_URL is set correctly, the issue is you're making a HTTP GET request (the default for Alamofire) when you wanted a POST. So you'll want:
let request = Alamofire.request(CognitiveService.apiUrl, method: .post, parameters: params, encoding: JSONEncoding.default, headers: header)
We are desperately trying to set a cookie before doing a POST request with Alamofire in Swift3. We only have found solutions for Swift2. Our current code looks like this
Alamofire.request(url, headers: NetworkUtil.getApiKeyHeader())
.responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
It's quit simple in the end, if you adapt it from Swift 2
if userCookie != nil, let cookieStorage = Alamofire.SessionManager.default.session.configuration.httpCookieStorage {
cookieStorage.setCookies([userCookie!], for: url, mainDocumentURL: nil)
}
I am building mobile applications to go with my django based backend. I make a post request in swift like this:
var request: NSMutableURLRequest = NSMutableURLRequest()
var url = "https://webapp.com/makepost/"
url += NSUserDefaults.standardUserDefaults().stringForKey("userPk")!
url += "/"
var err: NSError?
request.URL = NSURL(string: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(JSONObject, options: NSJSONWritingOptions(rawValue:0))
} catch _ {
print ("error")
}
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) {(response, data, error) -> Void in
var query = String(data: data!, encoding: NSUTF8StringEncoding)
query = query!.stringByReplacingOccurrencesOfString("Optional(", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
query = query!.stringByReplacingOccurrencesOfString(")", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
print(query)
//update ui
}
As soon as I make this post it creates the necessary models in django by reading the jsonObject.
The response doesn't matter and could take long as I'm notifying other users via FCM.
This is what I'm trying to do:
Make a post request.
Ignore the response.
Update the UI immediately after I make the post request.
How should I achieve this?
like so
//set request variable here
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) {(response, data, error) -> Void in
var query = String(data: data!, encoding: NSUTF8StringEncoding)
}
sleep(2)
// wait two seconds for models to create in backend
dispatch_async(dispatch_get_main_queue()) {
self.refresh(self.refreshButton)
//refresh ui here with method that fires another get request
}
}