if else conditions executed at the same time in swift - swift

I'm parsing this json from a REST API with SwiftyJSON:
{
"status": {
"code": 201,
"description": "success"
},
"result": [
{
"id": "5951e8eee0207e049c339691",
......
}
]
}
After sending the request with Alamofire and getting the response is when I run into an issue:
case .success:
if let value = response.result.value {
let json = JSON(value)
print(json)
if json["status"]["code"].intValue == 201 {
self.jsonData = json["result"].arrayValue
self.mytableView.reloadData()
print("realoded tableView")
}else{
HUD.show(.error)
HUD.hide(afterDelay: 0.5)
HUD.flash(.label("message"), delay: 3.0){ _ in
print("fail message")
}
}
}
myTableView reloads the data, and the console shows the print message. However, the HUD is also showing a message, and the console logs the fail message.
P.S. I have also tried to compare as a string with json["result"]["code"].stringValue == "201". This does the same tableview update, but the hud is shown the hud is managed with PKHUD library.

Related

Flickr photo upload does not work with OAtuth1Swift postImage Method

i'm currently facing the Problem that after the OAuth1 process, when i actually want to send the image, flickrapi responds with: No Photo Specified. :
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="fail">
<err code="2" msg="No photo specified" />
</rsp>
I am using the OAtuthSwift Framework for ios on XCode 10, Swift 4 for this task.
oAuthSwift = OAuth1Swift(consumerKey: flickr.apiKey,
consumerSecret: flickr.apiSecret,
requestTokenUrl: "https://www.flickr.com/services/oauth/request_token",
authorizeUrl: "https://www.flickr.com/services/oauth/authorize",
accessTokenUrl: "https://www.flickr.com/services/oauth/access_token")
if oAuthSwift != nil {
oAuthSwift?.authorizeURLHandler = SafariURLHandler(viewController: self, oauthSwift: oAuthSwift!)
guard let rwURL = URL(string: "iflickr://oauth-callback/iflickr") else {
return
}
let handle = oAuthSwift!.authorize( withCallbackURL: rwURL) { [unowned self] result in
switch result {
case .success(let (credential, response, parameters)):
print(credential.oauthToken)
print(credential.oauthTokenSecret)
guard let img = self.image?.jpegData(compressionQuality: 0.0) else {
print ("cant convert image")
return
}
var params = parameters
// Until Here seems everything fine
self.oAuthSwift!.client.postImage(flickr.uploadEndpoint, parameters: params, image: img) { upResult in
switch upResult {
case .failure(let error):
print (error)
case .success(let response):
let respData = response.data
if let string = response.string {
print ("\nRESULT:\n - \(string)\n")
// Here it prints the above described `No Photo Specified`
}
}
}
case .failure(let error):
print(error.localizedDescription)
}
}
}
I also tried to do the Request by myself and just take the values of the Dictionary provided from the OAuth process (parameters), but then it says something like: No Token were provided..
Can someone Help?
Like mentioned from #Clemens Brockschmidt, the image parameter were not correct. OAuthSwift provided standardwise "media" as parameter name, which was not accepted by the flickr upload API.
After recognise this, i changed the parameter name from "media" to "photo".
Code is in
OAuthSwift/Sources/OAuthSwiftClient.swift:multiPartRequest(), line 125
https://github.com/OAuthSwift/OAuthSwift/blob/b8941a23d1584ba17426c312bb957de355341f4a/Sources/OAuthSwiftClient.swift#L125

Alamofire sending a request to an API 'NSInvalidArgumentException'

i am using this code to send an image and text to an api:
func uploadImageAndData(_ url:String,parameters1:Parameters,headers1:HTTPHeaders,images:[UIImage]){
Alamofire.upload(multipartFormData: { multipartFormData in
// import image to request
var i=0
for imageData in images {
// multipartFormData.append(self.resizeImage(image: uploadedProfileImage, targetSize: CGSize(width: 200, height: 200)
multipartFormData.append(imageData.pngData()!, withName: "profilePic", fileName: "profileimage"+".jpeg", mimeType: "image/jpeg")
i += 1
}
for (key, value) in parameters1 {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
} ,to: url,method:.post,
headers:[:],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
print("showuing upload progress")
print("Upload Progress: \(Progress.fractionCompleted)")
//SwiftSpinner.show(progress: Progress.fractionCompleted*100, title: "تحميل")
})
upload.responseJSON { response in
print(response.response?.statusCode as Any)
if let data = response.result.value, let utf8Text = String(data: data as! Data, encoding: .utf8) {
print("New Func Data: \(utf8Text)")
}
switch response.response?.statusCode {
case 201 :
print("Success")
break
case 413 :
print("Post too large")
break
case 200 :
print("200")
break
case 400 :
print("400")
break
case 401 :
print("401")
break
case 302 :
print("302")
break
case 500 :
print("500")
break
default: break
}
}
return
case .failure(let encodingError): break
}
})
}
and i got these datas :
let address: Parameters = [
"location" : addressField.text!,
"locationLat" :pickedLocationLat,
"locationLong" :pickedLocationLong
]
let body: Parameters = [
"name": "Sample Name",
"email": "test#test.com",
"password": "test123",
"address": address
]
and i am accessing the function using this code
var head = [String:Any]()
head["Accept"]="application/json"
uploadImageAndData(BASE_URL", parameters1: body, headers1: head as! HTTPHeaders, images: [uploadedProfileImage])
this code is throwing an error like
Terminating app due to uncaught exception 'NSInvalidArgumentException'
reason: '-[_TtGCs26_SwiftDeferredNSDictionarySSP__$ dataUsingEncoding:]: unrecognized selector sent to instance 0x6000015bed00'
terminating with uncaught exception of type NSException
i dont know what is causing this problem the api requires a json body with a content-type of application/json
i tired removing all the content of the body parameter except for the name to try and send only the name and when i do that the image uploads successfully but it still gives me this error,so please help me figure out this problem.
You need to make values a string not double
let address: Parameters = [
"location" : addressField.text!,
"locationLat" :"\(pickedLocationLat)",
"locationLong" :"\(pickedLocationLong)"
]

Alamofire not getting full response

I'm trying to fetch data from a GET request using Alamofire in Swift. There's an issue where it's not getting the full response from the request. The response is an array with nested arrays some String and some [String:Any]. I've none of the [String:Any] gets pulled in using Alamofire and think this is a serious bug. Postman shows the nested array values but not Alamofire.
The request
Alamofire.request(request.getFullUrl(param: paramsForUrl), method: request.getMethodType(), parameters: data, encoding: request.getEncoding(), headers: headers).validate(statusCode: 200..<500).responseJSON { response in }
What a typical response should look like
{
"uuid": "787FDS8-FS7FS7DG9-FSD789FCS98",
"name": "Show time",
"views_count": 0,
"comments_count": 0,
...
"events": [
{
"uuid": "f69a358e-9a1e-427c-a158-95dfc8c54ed7",
"name": "Test",
...
},
{
"uuid": "8993b639-f6c9-4d20-b8a9-c43c73a9828b",
"name": "Test 2",
...
},
...
]
"times: [
{
"name: "test time 1",
"clock: "Face"
},
{
"name": "test time 2",
"clock: "Back"
}
]
}
What's missing
Anything inside nested arrays: events, times. If I have a simple array of String then Alamofire gets these. It doesn't show anything nested and this is with both printing response.result.value and JSON decoding the response and accessing events directly. It doesn't see events or times.
Thanks for your help.
May be your JSON is not valid. To check that try changing responseJSON to responseString and see if it prints all the data e.g.
Alamofire.request(url ,method: .get ,parameters: data).validate().responseString{ response in
switch response.result{
case .success:
let s = response.result.value ?? "nil"
print("API Response: \(s)")
case .failure:
debugPrint(response)
}
}
If the above is printing all the data from your server than you need to fix the service
Delete .validate(statusCode: 200..<500) and try again.
Alamofire.request(url ,method: .get ,parameters: parameter).responseJSON{ response in
switch response.result{
case .success:
let value = response.result.value ?? "nil"
print("API Response: \(value)")
case .failure:
print("error")
}
}

Swift catching error

Why is
if error = response.result.error else {
print (error)
}
Not allowed and throws an error within the function below? I would have expected it should go through well.
Alamofire.request(Router.RegisterUser(parameters))
.validate()
.responseJSON(completionHandler: { (response) -> Void in
if let receivedData = response.result.value {
let json = JSON(receivedData)
// Check for error in JSON
if let message = json["error"]["message"].string {
let error = Error.errorWithCode(.DataSerializationFailed, failureReason: message)
print(error)
return
}
completionHandler(.Success(true), response: JSON(receivedData))
}
if error = response.result.error else {
print (error)
}
})
I use the validate function to avoid successful responses to the completionhandler, when indeed an error code is returned by the server. The problem now is, that the only error I can currently receive is the one, thrown by validate(). But I use error handling in my API as well and will return a suitable error message to the user.
Error Domain=com.alamofire.error Code=-6003 "Response status code was
unacceptable: 400" UserInfo={NSLocalizedFailureReason=Response status
code was unacceptable: 400}
How can I achieve this now? As by using validate, the response will never get processed as far as I understand?
Alamofire.request(Router.RegisterUser(parameters))
.validate()
.responseJSON(completionHandler: { (response) -> Void in
switch(response.result) {
case .Success(let response):
print(response)
case .Failure(let error):
print("FAILURE: \(error)")
}
})
}
There seems to be 2 issues in your code:
You are missing a let or guard to check if there is an error.
print(error) should be inside if as you are checking error is not nil and trying to print error in else which will be nil.

Getting JSON array with Alamofire + SwiftyJSON

I'm really new to Swift, sorry if this is a dumb question... there seem to be many questions about this but none of them use the latest version of Alamofire
Alamofire.request(.GET, url)
.responseJSON { response in
let json = JSON(response.data!)
debugPrint(json)
self.delegate?.didReceiveAPIResults(json)
}
And the delegate's didReceiveAPIResults method
func didReceiveAPIResults(results: JSON) {
dispatch_async(dispatch_get_main_queue(), {
self.tableData = results["items"].arrayObject!
self.appsTableView!.reloadData()
})
}
Here's the JSON response:
{
"items": [
{
"id": 1,
"name": "Sample 1"
},
{
"id": 2,
"name": "Sample 2"
}
]
}
I expect the debugPrint to print something similar to that JSON, but instead it just prints unknown
If I debugPrint response.data by itself, it appears to be encoded...
Optional(<7b226461 7461223a 5b7b2269 64223a36 2c226e61 6d6522......
Then my results["items"].arrayObject! line has this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Rather than grabbing response.data, I'd suggest grabbing response.result.value. When you do responseJSON, Alamofire does the JSON parsing for you, and you should feel free to just grab this parsed object.
Alamofire.request(.GET, url)
.responseJSON { response in
if let value = response.result.value {
let json = JSON(value)
self.delegate?.didReceiveAPIResults(json)
}
}