unable to print json value with alamofire - swift

I am trying to get data with flickr API and I wrote a simple code with Alamofire and swiftyJSON to get this data from flickr but I am able to print the data size but when I try to print the json, my catch block runs. my codes are shown below
func getPhotos(completion: #escaping CompletionHandler) -> Void {
let parameter: [String: Any] = [
"method": PHOTOS_METHOD,
"api_key": FLICKR_API_KEY,
"per_page": PER_PAGE,
"page": PAGE,
"format": FORMAT_TYPE,
"nojsoncallback": JSON_CALLBACK]
Alamofire.request(FLICKR_URL, method: .get, parameters: parameter, encoding: JSONEncoding.default, headers: HEADER).responseString { (response) in
if response.result.error == nil {
guard let data = response.data else {return}
do {
if let json = try JSON(data: data).array {
print(json)
}
completion(true)
} catch {
print("eroorrrre")
completion(false)
}
print("CALL CORRECT")
print(data)
completion(true)
}
else {
completion(false)
debugPrint(response.result.error as Any)
}
}
}
my console log
eroorrrre
CALL CORRECT
128 bytes
I am not sure what I am doing wrong here, any help would be appriciated

Try this
Alamofire.request(FLICKR_URL, method: .get, parameters: parameter, headers: HEADER).responseJSON { response in // call responseJSON instead of responseString
if response.result.isSuccess { // If http request is success
let json: JSON = JSON(response.result.value!) // JSON format from SwiftyJSON (I suppose you are using it)
guard let data = json.array else { // You suppose that json is array of objects
print("Unexpected JSON format")
completion(false)
}
print(data)
completion(true)
} else {
print(response.error)
completion(false)
}
}

Related

How to access response of callback from AWS Lambda function in swift?

I have a simple AWS Lambda function which returns the id of the user when he logins.
if (event.email && password)
{
connection.query("SELECT * FROM doctor_data WHERE doc_email = ?", [event.email], function(error, results, fields)
{
connection.release();
if(results.length > 0)
{
bcrypt.compare(password, results[0].password, function(err, ress)
{
if(!ress)
{
callback (null, "Incorrect Password");
}
else
{
callback (null, results[0].doc_id);
}
});
}
else
{
callback (null, "Incorrect Email");
}
});
}
else
{
callback(null, "Please enter Email and Password!");
}
Now in Android (Java) we used the below mentioned logic for accessing the id. We directly store it in the String variable and it works fine.
#Override
public void onResponse(Call call, Response response) throws IOException {
String responseMsg = response.body().string();
Log.e(TAG, msg: responseMsg+ " responseMsg");
The iOS swift code is mentioned below.
func callingLoginAPI(login: LoginModel,completionHandler: #escaping (Bool, String) -> ()){
let headers: HTTPHeaders = [
.contentType("application/json")
]
AF.request(doctor_login, method: .post, parameters: login, encoder:
JSONParameterEncoder.default, headers: headers).response{
response in debugPrint(response)
switch response.result{
case.success(let data):
let urlString = doctor_login
guard let url = URL(string: urlString) else {return}
URLSession.shared.dataTask(with: url){ (data, response, err) in
guard let data = data else {return}
let dataAsString = String(data: data,encoding: .utf8)
print("this is", dataAsString)
do{
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
print(json)
print("json")
}
catch{
print(error.localizedDescription)
completionHandler(false, "Login not Done")
print("not done")
}
}.resume()
if response.response?.statusCode == 200
{
completionHandler(true, "Login Done")
print("done")
}
else{
completionHandler(false, "Please try again")
print("not done")
}
case.failure(let err):
print("that")
print(err.localizedDescription)
completionHandler(false, "Try Again")
}
}
It's giving me the following response. It's giving me the id of the user which is 2 in this case but I don't know how to get/extract or save it.
Can anyone guide me how to get/extract or save the response of the body which is 2 in this case?
In Android we used the okhttp library for accessing the API whereas in iOS swift we used NSURLConnection library for acccessing the API.

Swift scoping outside of a function

I have a singleton URLSession that is parsing the response data into a dictionary. I want to use a single value from that dictionary in a subsequent piece of code, but cannot figure out how to pass the value out from the scope it's currently in.
Here is the code as it stands now:
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
debugPrint ("error: \(error!)")
return
}
guard let content = data else {
debugPrint("No data")
return
}
guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else {
debugPrint("Not containing JSON")
return
}
if let idToken = json["id_token"] as? String {
let privateToken = idToken;
debugPrint("Gotten json response dictionary is \(idToken)")
}
}
task.resume()
return privateToken
Currently there is an IDE error on return privateToken saying that I am using an unresolved identifier: privateToken.
How can I take the string idToken and return it as a privateToken for use elsewhere?
Could you use a completion handler like:
func getPrivateToken(completion: #escaping(String) -> (), failure: #escaping (Error) -> ()) {
URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
debugPrint ("error: \(error!)")
failure(error)
return
}
guard let content = data else {
debugPrint("No data")
failure(NSError(domain: "Your error message here.", code: 401, userInfo: nil))
return
}
guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else {
debugPrint("Not containing JSON")
failure(NSError(domain: "Your error message here.", code: 401, userInfo: nil))
return
}
if let idToken = json["id_token"] as? String {
completion(idToken)
debugPrint("Gotten json response dictionary is \(idToken)")
}
}.resume()
}
And use it like so:
func exampleFunction() {
self.getPrivateToken(completion: { (token) in
// Do what ever you need with the token here.
print("ID token is: \(token)")
}) { (error) in
// Present error here
}
}

'Catch is unreachable because no calls to throwing functions', but function is throwing errors?

It's likely that I will receive an SSL error -1200 from an Alamofire request, if this occurs, I want to output the error to a text field.
I'm trying to catch the error I'm getting in my console window so that I can output it to the text field, but I'm getting this message from xcode:
'catch' block is unreachable because no errors are thrown in 'do' block
Here is how I'm structuring the do/try/catch with the AF request:
do{
try AF.request(host, method: .post, parameters: parameters, encoding:JSONEncoding.default)
.responseData{ response in
guard let responseData = response.data else { return }
let responseJSON = try? JSON(data:responseData)
if let responseJSONAsString = responseJSON?.rawString(){
self.output(text: responseJSONAsString + "\n\n\n")
}
}
}
catch {
self.textField.stringValue = ("Caught: " + error.localizedDescription)
}
You need
AF.request(host, method: .post, parameters:parameters,encoding:JSONEncoding.default)
.responseData { response in
do {
guard let responseData = response.data else { return }
let responseJSON = try JSON(data:responseData)
if let responseJSONAsString = responseJSON.rawString(){
///
}
}
catch {
print(error)
}
}
Alamofire does not throw errors – that's what the error says – but you should handle the passed error in the closure
AF.request(host, method: .post, parameters: parameters, encoding: .default)
.responseData { response in
switch response.result {
case .success(let data):
do {
let responseJSON = try JSON(data: data)
if let responseJSONAsString = responseJSON?.rawString(){
self.output(text: responseJSONAsString + "\n\n\n")
}
} catch {
self.textField.stringValue = ("Caught:", error.localizedDescription)
}
case .failure(let error):
self.textField.stringValue = ("Network Error:", error.localizedDescription)
}
}

the alamofire isn't doing a proper connection to the api

i am trying to get a response that contain json from openweathermap api,
but from the debugger it seems that when he get to the code block of alamofire its just skips it
here is the block of code that i am using for this task
func printJson(){
Alamofire.request("https://api.openweathermap.org/data/2.5/find?appid=6ad1f143546b8c6d761ecbda6a34a005&q=yavne", method: .get).responseJSON { response in
if response.data != nil {
var json : JSON
do{
json = try JSON(data: response.data!)
print(json)
}catch{}
}
}
}
Use this helper class to make API calls.
class NetworkHandler {
static let shared = NetworkHandler()
func sendRequest(withUrl url:String,andBody body:[String:Any]? = [:],
completionHandler: #escaping ((_ status: Bool,_ response:Any) -> Void)) {
DispatchQueue.global(qos: .userInitiated).async {
Alamofire.request(url, method: .post, parameters: body,encoding: JSONEncoding.default, headers: nil).responseJSON {
response in
guard response.response?.statusCode == 200 else{
completionHandler(false,"Service Temporarily Unavailable.\nPlease check your internet connection or contact your Service provider.")
return
}
switch response.result {
case .success:
completionHandler(true,response.value!)
break
case .failure(let error):
completionHandler(false,error.localizedDescription)
}
}
}
}
}

Alamofire Post Request is not Executed

I'm making a POST Request to my API. All of a sudden the request is being skipped. I have tried to debug into it, but until now without success.
This is my request:
#IBAction func checkLogin(_ sender: Any) {
guard let managedContext = self.managedObjectContext else { return }
let user = NSEntityDescription.insertNewObject(forEntityName: User.identifier, into: managedContext) as! User
let url = ""
let parameters: Parameters =
["username" : usernameTextField.text!, "password" : passwordTextField.text!]
Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default).responseJSON { (responseData) -> Void in
let results = JSON(responseData.result.value!)
print(results)
user.firstName = results["firstname"].string!
let responseString : String = responseData.response?.allHeaderFields["Set-Cookie"] as! String
if let range = responseString.range(of: ";"){
let startIndex = (responseString.range(of: "="))
let cookie = responseString[(startIndex?.upperBound)!...range.lowerBound]
user.setValue(cookie, forKey: "token")
}
} do {
try self.dataController.saveContext()
}catch {
print("Save Error User")
}
I'm Using Alamofire 4.5 with Swift 3.1.
Please use different types of data request handling block and check again.
Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default)
.responseJSON { response in
print("JSON Response")
}
.responseData { response in
print("Data Response")
}
.responseString { response in
print("String Response")
}
.responsePropertyList { response in
print("PropertyList Response")
}