Alamofire: Cannot get response from server - please help.

Created on 19 Sep 2016  路  12Comments  路  Source: Alamofire/Alamofire

Hello everyone,

Code before new update in swift 2.3 and alamo fire 3.0 was as follows:

    var name: String {
        return _name
    }

    var pokedexId: Int {
        return _pokedexId
    }

    init(name: String, pokedexId: Int) {
        self._name = name
        self._pokedexId = pokedexId

        _pokemonUrl = "\(URL_BASE)\(URL_POKEMON)\(self._pokedexId)/"
    }

    func downloadPokemonDetails(completed: DownloadComplete) {

        let url = NSURL(string: _pokemonUrl)!
        Alamofire.request(.GET, url).responseJSON { (request: NSURLRequest?, response: NSHTTPURLResponse?, result: Result<AnyObject>) -> Void in

            if let dict = result.value as? Dictionary<String, AnyObject> {

I've migrated the code to this, according to documentation, but I get nothing back from the server.

    var name: String{
        return _name
    }

    var pokedexId: Int{
        return _pokedexId
    }

    init(name: String, pokedexId: Int){
        self._name = name
        self._pokedexId = pokedexId

        _pokemonUrl = "\(URL_BASE)\(URL_POKEMON)\(self._pokedexId)/"
    }

    func downloadPokemonDetails (completed: @escaping DownloadComplete){

        let pokemonUrl = URL(string: _pokemonUrl)!

        Alamofire.request(pokemonUrl).responseJSON { response in

            print(response)

            if let dict = response.result.value as? Dictionary<String, AnyObject>{

                if let weight = dict["weight"] as? String{
                    self._weight = weight
                }

As you can see previously i declared the URL as NSURL which should be what I need to fix, but how do I do that now?

Thanks :(

Most helpful comment

Thanks a lot!!! It worked :DDD

return _pokedexId! and in the url adding the ! at the end while declaring the var as an optional did the trick :DDD

My pokedex works :D

All 12 comments

@sungkim23 where is URL_BASE, URL_POKEMON defined? Also, you are passing pokemonUrl into your request however _pokemonUrl is what is set in your initializer. I suppose posting the whole class will be more helpful to assist in debugging your problems.

cheers!

The URL's come from my Constants.swift file

import Foundation

let URL_BASE = "http://pokeapi.co"
let URL_POKEMON = "/api/v1/pokemon/"

typealias DownloadComplete = () -> ()

Pokemon.Swift - which I'm having problems with.

//
//  Pokemon.swift
//  Pokedex
//
//  Created by Sung Kim on 8/18/16.
//  Copyright 漏 2016 Sung Min Kim. All rights reserved.
//

import Foundation
import Alamofire

class Pokemon {
    private var _name: String!
    private var _pokedexId: Int!
    private var _description: String!
    private var _type: String!
    private var _defence: String!
    private var _height: String!
    private var _weight: String!
    private var _attack: String!
    private var _nextEvolutionTxt: String!
    private var _nextEvolutionId: String!
    private var _nextEvolutionLvl: String!
    private var _pokemonUrl: String!

    var description: String{
        if _description == nil{
            _nextEvolutionLvl =  ""
        }
        return _description
    }

    var type: String{
        if _type == nil{
            _type = ""
        }
        return _type
    }

    var defence: String{
        if _defence == nil{
            _defence = ""
        }
        return _defence
    }

    var height: String{
        if _height == nil{
            _height = ""
        }
        return _height
    }

    var weight: String{
        if _weight == nil{
            _weight = ""
        }
        return _weight
    }

    var attack: String{
        if _attack == nil{
            _attack = ""
        }
        return _attack
    }

    var nextEvolutionTxt: String{
        if _nextEvolutionTxt == nil{
            _nextEvolutionTxt = ""
        }
        return _nextEvolutionTxt
    }

    var nextEvolutionId: String{
        if _nextEvolutionId == nil{
            _nextEvolutionId = ""
        }
        return _nextEvolutionId
    }

    var nextEvolutionLvl: String{
        if _nextEvolutionLvl == nil{
            _nextEvolutionLvl = ""
        }
        return _nextEvolutionLvl
    }

    var name: String{
        return _name
    }

    var pokedexId: Int{
        return _pokedexId
    }

    init(name: String, pokedexId: Int){
        self._name = name
        self._pokedexId = pokedexId

        _pokemonUrl = "\(URL_BASE)\(URL_POKEMON)\(self._pokedexId)/"
    }

    func downloadPokemonDetails (completed: @escaping DownloadComplete){

        let pokemonUrl = URL(string: _pokemonUrl)!

//        Alamofire.request(pokemonUrl).responseJSON { response in

            print(response)

            if let dict = response.result.value as? Dictionary<String, AnyObject>{

                if let weight = dict["weight"] as? String{
                    self._weight = weight
                }

                if let height = dict["height"] as? String{
                    self._height = height
                }

                if let attack = dict["attack"] as? Int{
                    self._attack = "\(attack)"
                }

                if let defence = dict["defense"] as? Int{
                    self._defence = "\(defence)"
                }

                 print(self._weight)
//                 print(self._height)
//                 print(self._attack)
//                 print(self._defence)
//                
                if let types = dict["types"] as? [Dictionary<String, String>] , types.count > 0 {
                    if let name = types[0]["name"]{
                        self._type = name.capitalized
                    }

                    if types.count > 1  {
                        for x in 1 ..< types.count {
                            if let name = types[x]["name"]{
                                self._type! += "/\(name.capitalized)"
                            }
                        }
                    }
                } else {
                    self._type = ""
                }
                 print (self._type)

                if let descArr = dict ["descriptions"] as? [Dictionary <String, String>], descArr.count > 0{

                    if let url = descArr[0]["resource_uri"]{

                        let descURL = "\(URL_BASE)\(url)"

                        Alamofire.request(descURL).responseJSON { response in

                            if let descDict = response.result.value as? Dictionary<String, AnyObject>{

                                if let description = descDict["description"] as? String {
                                    self._description = description
                                    print (self._description)
                                }
                            }
                            completed()
                        }
                    }

                } else {
                    self._description = ""
                }

                if let evolutions = dict["evolutions"] as? [Dictionary <String, AnyObject>], evolutions.count > 0 {

                    if let to = evolutions[0]["to"] as? String{

                        //Mega is not found
                        if to.range(of: "mega") == nil{

                            if let uri = evolutions[0]["resource_uri"] as? String {
                                let newStr = uri.replacingOccurrences(of: "/api/v1/pokemon/", with: "")

                                let num = newStr.replacingOccurrences(of: "/", with: "")

                                self._nextEvolutionId = num
                                self._nextEvolutionTxt = to

                                if let lvl = evolutions[0]["level"] as? Int{
                                    self._nextEvolutionLvl = "\(lvl)"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

@ryan-luas

error i get in debugger is

SUCCESS: {
    "error_message" = "Sorry, this request could not be processed. Please try again later.";
}
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) 

Doing further investigation it seems my INT for ._pokedexId is being sent as optional(1) because I'm configuring something wrong in the URL parts, where before when I used NSURL I had no issues.

@sungkim23 ok, I see now that you redefined pokemonUrl in your download details method, and your initializer concatenates pokedexId to your routes... the code seems fine; however is there a race condition? What method is calling the Pokemon class and sending the pokedexId ? Also, if this is just a matter of server response, have you tested the API from cURL or postman and are you getting a response?

Ahhhh try making pokedexId public and an optional, then unwrap it as needed.

You can't expect a dynamic integer to be set and forced to unwrap when the object of pokemon gets put into the heap. So instead declare it as optional, then force unwrap it when you are very sure it's set to be passed into downloadPokemonDetails. ? use those! 馃憤

Thanks for the lldb output, that is huge in helping you solve your problem!

cheers!

Thanks a lot!!! It worked :DDD

return _pokedexId! and in the url adding the ! at the end while declaring the var as an optional did the trick :DDD

My pokedex works :D

A W E S O M E !!! Stoked to hear it @sungkim23

@ryan-luas This was my first full project since Swift 3 and the new Xcode, time to keep making and updating my apps :D

Great work! The concepts of optional unwrapping haven't changed since Swift 1.0, however I'm glad to hear you got your swift3 app working! A good habit to get into is to set variables to be optional by default if they are going to be changed by user input or dynamic API data.

Cheers! 馃嵒 @sungkim23

I am having the same problem, can you show your updated code? because I can't seem to fix my issue.

//
//  Pokemon.swift
//  Pokedex
//
//  Created by Sung Kim on 8/18/16.
//  Copyright 漏 2016 Sung Min Kim. All rights reserved.
//

import Foundation
import Alamofire

class Pokemon {
    private var _name: String!
    private var _pokedexId: Int?
    private var _description: String!
    private var _type: String!
    private var _defence: String!
    private var _height: String!
    private var _weight: String!
    private var _attack: String!
    private var _nextEvolutionTxt: String!
    private var _nextEvolutionId: String!
    private var _nextEvolutionLvl: String!
    private var _pokemonUrl: String!

    var description: String{
        if _description == nil{
            _description =  ""
        }
        return _description
    }

    var type: String{
        if _type == nil{
            _type = ""
        }
        return _type
    }

    var defence: String{
        if _defence == nil{
            _defence = ""
        }
        return _defence
    }

    var height: String{
        if _height == nil{
            _height = ""
        }
        return _height
    }

    var weight: String{
        if _weight == nil{
            _weight = ""
        }
        return _weight
    }

    var attack: String{
        if _attack == nil{
            _attack = ""
        }
        return _attack
    }

    var nextEvolutionTxt: String{
        if _nextEvolutionTxt == nil{
            _nextEvolutionTxt = ""
        }
        return _nextEvolutionTxt
    }

    var nextEvolutionId: String{
        if _nextEvolutionId == nil{
            _nextEvolutionId = ""
        }
        return _nextEvolutionId
    }

    var nextEvolutionLvl: String{
        if _nextEvolutionLvl == nil{
            _nextEvolutionLvl = ""
        }
        return _nextEvolutionLvl
    }

    var name: String{
        return _name
    }

    var pokedexId: Int{
        return _pokedexId!
    }

    init(name: String, pokedexId: Int){
        self._name = name
        self._pokedexId = pokedexId

        _pokemonUrl = "\(URL_BASE)\(URL_POKEMON)\(self._pokedexId!)/"
//        print (_pokemonUrl)
    }

    func downloadPokemonDetails (completed: @escaping DownloadComplete){

        let pokemonUrl = URL(string: _pokemonUrl)!

        Alamofire.request(pokemonUrl).responseJSON { response in

            if let dict = response.result.value as? Dictionary<String, AnyObject>{

                print(response)

                if let weight = dict["weight"] as? String{
                    self._weight = weight
                }

                if let height = dict["height"] as? String{
                    self._height = height
                }

                if let attack = dict["attack"] as? Int{
                    self._attack = "\(attack)"
                }

                if let defence = dict["defense"] as? Int{
                    self._defence = "\(defence)"
                }

//                print(self._weight)
//                print(self._height)
//                print(self._attack)
//                print(self._defence)

                if let types = dict["types"] as? [Dictionary<String, String>] , types.count > 0 {
                    if let name = types[0]["name"]{
                        self._type = name.capitalized
                    }

                    if types.count > 1  {
                        for x in 1 ..< types.count {
                            if let name = types[x]["name"]{
                                self._type! += "/\(name.capitalized)"
                            }
                        }
                    }
                } else {
                    self._type = ""
                }
//                print (self._type)

                if let descArr = dict ["descriptions"] as? [Dictionary <String, String>], descArr.count > 0{

                    if let url = descArr[0]["resource_uri"]{

                        let pokemonDescriptionUrl = URL(string: "\(URL_BASE)\(url)")!
                        Alamofire.request(pokemonDescriptionUrl).responseJSON { response in

                            if let descDict = response.result.value as? Dictionary<String, AnyObject>{

                                if let description = descDict["description"] as? String {
                                    self._description = description
//                                    print (self._description)
                                }
                            }
                            completed()
                         }
                    }

                } else {
                    self._description = ""
                }

                if let evolutions = dict["evolutions"] as? [Dictionary <String, AnyObject>], evolutions.count > 0 {

                    if let to = evolutions[0]["to"] as? String{

                        //Mega is not found
                        if to.range(of: "mega") == nil{

                            if let uri = evolutions[0]["resource_uri"] as? String {
                                let newStr = uri.replacingOccurrences(of: "/api/v1/pokemon/", with: "")

                                let num = newStr.replacingOccurrences(of: "/", with: "")

                                self._nextEvolutionId = num
                                self._nextEvolutionTxt = to

                                if let lvl = evolutions[0]["level"] as? Int{
                                    self._nextEvolutionLvl = "\(lvl)"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}



Was this page helpful?
0 / 5 - 0 ratings