How parse id with SwiftyJSON swift 4.2 ,why is wrong? - swifty-json

//This JSON {"data":[{"id":288,"eid":16,"admin":true},{"id":289,"eid":16,"admin":false}],"meta":{"count":2}}
Alamofire.request(self.url, headers: header).responseJSON
(completionHandler: { response in
statusCode = (response.response?.statusCode)!
if statusCode != 200{
}else{
switch response.result {
case .success( let responseJSON):
let json = JSON(responseJSON)
print(json)
let data = json["data"]
print(data)
case .failure(_):
print("ERROR")
}
}
})
}
}
}

Related

RXSwift why loading variable return wrong value?

Here is my view model:
let loadMoreTrigger = PublishSubject<Void>()
let refreshTrigger = PublishSubject<Void>()
let loading = BehaviorRelay<Bool>(value: false)
let stories = BehaviorRelay<[Story]>(value: [])
var offset = 0
let error = PublishSubject<String>()
let selectedFeedType: BehaviorRelay<FeedType> = BehaviorRelay(value: .best)
override init() {
super.init()
let refreshRequest = loading.asObservable().sample(refreshTrigger).flatMap { loading -> Observable<[Story]> in
if loading {
return Observable.empty()
} else {
self.offset = 0
return self.fetchStories(type: self.selectedFeedType.value, offset: self.offset)
}
}
let loadMoreRequest = loading.asObservable().sample(loadMoreTrigger).flatMap { loading -> Observable<[Story]> in
if loading {
return Observable.empty()
} else {
self.offset += 10
return self.fetchStories(type: self.selectedFeedType.value, offset: self.offset)
}
}
let request = Observable.merge(refreshRequest, loadMoreRequest).share(replay: 1)
let response = request.flatMap { (stories) -> Observable<[Story]> in
request.do(onError: { error in
self.error.onNext(error.localizedDescription)
}).catchError { (error) -> Observable<[Story]> in
Observable.empty()
}
}.share(replay: 1)
Observable.combineLatest(request, response, stories.asObservable()) { request, response, stories in
return self.offset == 0 ? response : stories + response
}.sample(response).bind(to: stories).disposed(by: disposeBag)
Observable.merge(request.map{_ in true}, response.map{_ in false}, error.map{_ in false}).bind(to: loading).disposed(by: disposeBag)
}
Then when i checking loading observer i have false -> true, instead of true -> false. I just don't understand why it happening.
loading.subscribe {
print($0)
}.disposed(by: disposeBag)
In my viewController i call refreshTrigger on viewWillAppear using rx.sentMessage
Here is getFeed function:
func getFeed(type: FeedType, offset: Int) -> Observable<[Story]> {
return provider.rx.request(.getFeed(type: type, offset: offset)).asObservable().flatMap { (response) -> Observable<[Story]> in
do {
let feedResponse = try self.jsonDecoder.decode(BaseAPIResponse<[Story]>.self, from: response.data)
guard let stories = feedResponse.data else { return .error(APIError.requestFailed)}
return .just(stories)
} catch {
return .error(error)
}
}.catchError { (error) -> Observable<[Story]> in
return .error(error)
}
}
Your request and response observables are emitting values at the exact same time. Which one shows up in your subscribe first is undefined.
Specifically, request doesn't emit a value until after the fetch request completes. Try this instead:
Observable.merge(
loadMoreTrigger.map { true },
refreshTrigger.map { true },
response.map { _ in false },
error.map { _ in false }
)
.bind(to: loading)
.disposed(by: disposeBag)
There are lots of other problems in your code but the above answers this specific question.

Xcode : Alamofire get String response

I am new in IOS development and currently learning networking with Alamofire
i am trying to make a login ...
whenever the credentials are correct the .php file returns a json and i am able to get that json from Alamofire through the following code:
Alamofire.request(loginUrl, method: .post, parameters: parameters).responseJSON { (response:DataResponse<Any>) in
print("String:\(response.result.value)")
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(self.loginUrl)
print(data)
}
case .failure(_):
print(self.loginUrl)
print("failed")
print("Error message:\(response.result.error)")
break
}
}
now...when ever the credentials are wrong, the .php does't give the json..instead it return a string ..for example "wrong_password" or "userLocked" etc etc...
how can i get the String response through Alamofire?
If you want JSON response use .responseJSON , if you want String response use .responseString. If you want both use both. Hope this help.
Alamofire.request(loginUrl, method: .post, parameters: parameters)
.responseJSON { response in
print("JSON:\(response.result.value)")
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(data)
}
case .failure(_):
print("Error message:\(response.result.error)")
break
}
}
.responseString { response in
print("String:\(response.result.value)")
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(data)
}
case .failure(_):
print("Error message:\(response.result.error)")
break
}
}
UPDATED: Swift 5, Alamofire 5
AF.request(urlString, method: .post, parameters: parameters)
.responseJSON { response in
print("response: \(response)")
switch response.result {
case .success(let value):
print("value**: \(value)")
case .failure(let error):
print(error)
}
}
.responseString { response in
print("response: \(response)")
switch response.result {
case .success(let value):
print("value**: \(value)")
case .failure(let error):
print(error)
}
}
I resolve this by:
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
source:
https://github.com/Alamofire/Alamofire/issues/818

Parsing JSON Swift 3 with error Code=3840

I have this error.
Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}
Here is my swift code.
let request = NSMutableURLRequest(url: NSURL(string: "http://example.org/file.php")! as URL)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request as URLRequest) {
old_data, response, error in
//Error Checking
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
//Response string built up
let responseString = NSString(data: old_data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
//Manipulating the JSON data
var names = [String]()
do {
if let new_data = old_data,
let json = try JSONSerialization.jsonObject(with: new_data) as? [String: Any],
let buildings = json["buildings"] as? [[String: Any]] {
for building in buildings {
if let name = building["BuildingName"] as? String {
names.append(name)
}
}
}
} catch {
print(error)
}
print("Names: \(names)")
}
task.resume()
The error is happening in my 'do' statement where 'let buildings = json["buildings"]'
And below is what I get when I print the response string.
responseString = Optional({"buildings":[{"BuildingID":"2","BuildingName":"School of Informatics and Comp","Info":"School of higher learning.","Latitude":"39.172085","Longitude":"-86.522908"}]}Successfully Retrieved. SELECT * FROM Buildings;)
Any questions or advice is appreciated

Using FORM DATA with Alamofire

I am using alamofire for some time now, but I have never used a form data Post. Now I am stuck. I have 2 params (email, password) and don't know how POST them to server. Can anyone give me an example please?
And here is a sample code for Alamofire 4.0 in Swift 3.0
let url = "http://testurl.com"
let parameters = [
"email": "asd#fgh.hjk",
"password": "55555"
]
Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default).responseJSON { response in
switch response.result {
case .success:
if let value = response.result.value {
print(value)
}
case .failure(let error):
print(error)
}
}
So my solution is.... you have to specify the Parameter Encoding in Alamofire. So the code will look like this.
Swift 2.0
func registerNewUserFormData(completionHandler: (Bool, String?) -> ()){
// build parameters
let parameters = ["email": "test#test.cz", "password": "123456"]
// build request
Alamofire.request(.POST, urlDomain + "register", parameters: parameters, encoding: .URL).responseJSON { response in
switch response.result {
case .Success:
print("Validation Successful")
if let JSON = response.result.value {
print(JSON)
}
case .Failure(let error):
print(error)
}
}
}
Swift 5
let url = "http://testurl.com"
let parameters = [
"email": "asd#fgh.hjk",
"password": "55555"
]
AF.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default).responseJSON { response in
switch response.result {
case .success:
if let value = response.result.value {
print(value)
}
case .failure(let error):
print(error)
}
}

How to upload image with parameters using Alamofire in Swift

I am developing an iPhone application with swift. and I'am using Alamofire framework for handling http requests. I use Alamofire.request for POST , GET and etc like this:
Alamofire.request(.POST, myURL , parameters: ["a": "1", "b" : "2" ])
.response { (request, response, data, error) in
}
And I use Alamofire.upload to upload image to server this :
Alamofire.upload(.POST, uploadURL , fileURL)
And both works perfectly, but now I want to upload an image and also send some parameters with, and my content type should be multipart/form-data and Alamofire.upload does not accept parameters.
There are two more question on SO about this issue with swift, which first one is not using Alamofire (and really, why not?) and in second one, mattt (Alamofire Developer) cited to use encoding parameters.
I checked his example, but still couldn't figure out how to do that.
Can any one please help me solve this problem?
Thank you! :)
you can use Alamofire 3.0+ below code
func uploadImageAndData(){
//parameters
let gender = "M"
let firstName = "firstName"
let lastName = "lastName"
let dob = "11-Jan-2000"
let aboutme = "aboutme"
let token = "token"
var parameters = [String:AnyObject]()
parameters = ["gender":gender,
"firstName":firstName,
"dob":dob,
"aboutme":about,
"token":token,
"lastName":lastName]
let URL = "http://yourserviceurl/"
let image = UIImage(named: "image.png")
Alamofire.upload(.POST, URL, multipartFormData: {
multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 0.6) {
multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "file.png", mimeType: "image/png")
}
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}, encodingCompletion: {
encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
print("s")
upload.responseJSON {
response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .Failure(let encodingError):
print(encodingError)
}
})
}
SWIFT 2 AlamoFire Simple Image Upload (REST API)
#amit gupta It seems answer contains big overhead. AlamoFire contain load of simplified solution. Alamofire.request method contains several simplified overload which can use to upload in simple manner. By using Alamofire.request( method developer can get rid of encoding overhead.
HTTP Status 415 gives because of not specifying the correct media type.
Please check my solution below.
import UIKit
import Alamofire
class ViewController: UIViewController {
#IBOutlet var imageView: UIImageView!
#IBOutlet var btnUpload: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
func successDataHandler(responseData:String){
print ("IMAGE UPLOAD SUCCESSFUL !!!")
}
func failureDataHandler(errorData:String){
print (" !!! IMAGE UPLOAD FAILURE !!! ")
}
#IBAction func actionUpload(sender: AnyObject) {
let URL = "http://m8coreapibeta.azurewebsites.net/api/cards/SaveImages"
let postDataProlife:[String:AnyObject] = ["CardId":(dataCardDetail?.userId)!,"ImageType":1,"ImageData":imageView.image!]
uplaodImageData(URL, postData: postDataProlife, successHandler: successDataHandler, failureHandler: failureDataHandler)
}
func uplaodImageData(RequestURL: String,postData:[String:AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () {
let headerData:[String : String] = ["Content-Type":"application/json"]
Alamofire.request(.POST,RequestURL, parameters: postData, encoding: .URLEncodedInURL, headers: headerData).responseString{ response in
switch response.result {
case .Success:
print(response.response?.statusCode)
successHandler(response.result.value!)
case .Failure(let error):
failureHandler("\(error)")
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Almaofire with swift 3.0
Alamofire.upload(multipartFormData: { multipartFormData in
var index = 1
for image in imageArray {
let imageData: Data = (UIImageJPEGRepresentation(image, 1.0) as Data?)!
multipartFormData.append(imageData, withName: "home-\(index)", fileName: "home-\(index)", mimeType: "image/jpeg")
index += 1
}
}, with: requestName, encodingCompletion: { result in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
print("Image(s) Uploaded successfully:\(response)")
}
case .failure(let encodingError):
print("encodingError:\(encodingError)")
}
})
Swift 4 with Alamofire 4
let isConnected = connectivity.isConnectedToInternet()
func updateProfile(firstName:String,lastName:String ,imageData:Data?,completion: #escaping (isValidUser)->()) {
if self.isConnected {
var parameters : [String:String] = [:]
parameters["auth_key"] = loginUser?.authKey!
parameters["first_name"] = firstName
parameters["last_name"] = lastName
let url = "\(baseUrl)\(basicAuthenticationUrl.updateProfile)"
print(url)
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
if let data = imageData {
multipartFormData.append(data, withName: "image_url", fileName: "image.png", mimeType: "image/png")
}
}, usingThreshold: UInt64.init(), to: url, method: .post) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
print("Succesfully uploaded = \(response)")
if let err = response.error{
print(err)
return
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
}
}
}
}
Almaofire with swift 2.0 just copy and paste below code.here m asumming JSON response from server
func uploadImageRemote (imageData : NSData?) -> Dictionary <String,AnyObject>{
var imageDictionary = Dictionary<String,AnyObject>()
var tokenHeaders:[String:String]! = ["x-access-token":Constants.kUserDefaults.stringForKey("userToken")!]
Alamofire.upload(
.POST,
"http://52.26.230.146:3300/api/profiles/imageUpload",headers:tokenHeaders,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data: imageData!, name: "upload", fileName: "imageFileName.jpg", mimeType: "image/jpeg")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
print("Uploading Avatar \(totalBytesWritten) / \(totalBytesExpectedToWrite)")
dispatch_async(dispatch_get_main_queue(),{
})
}
upload.responseJSON { response in
guard response.result.error == nil else {
print("error calling GET \(response.result.error!)")
return
}
if let value = response.result.value {
print("Success JSON is:\(value)")
if let result = value as? Dictionary<String, AnyObject> {
imageDictionary["imageUrl"] = result["url"]
}
}
dispatch_async(dispatch_get_main_queue(),{
//Show Alert in UI
print("Avatar uploaded");
})
}
case .Failure(let encodingError):
//Show Alert in UI
print("Avatar not uploaded \(encodingError)");
}
}
);
return imageDictionary
}
To use encoding Parameters, make a ParameterEncoding variable, assign it a encoding type (case of the enum which include .JSON, .URL) and then use the encode function with your NSURLRequest and the parameters. This function returns a tuple of two element, the first being the resulting NSURLRequest and the second being the resulting possible NSError.
Here's how I used it for a custom header I needed in a project
var parameterEncoding:ParameterEncoding!
switch method {
case .POST, .PUT :
parameterEncoding = ParameterEncoding.JSON
default :
parameterEncoding = ParameterEncoding.URL
}
var alamoRequest = Alamofire.Manager.sharedInstance.request(parameterEncoding.encode(mutableURLRequest, parameters: parameters).0)

Resources