Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alamofire 5.2 cannot convert value of type #36

Closed
PatrickB100 opened this issue Dec 29, 2020 · 9 comments
Closed

Alamofire 5.2 cannot convert value of type #36

PatrickB100 opened this issue Dec 29, 2020 · 9 comments
Labels

Comments

@PatrickB100
Copy link

Hi GCharita,

Since alamofire 5.2 i cannot convert DataResponse to expected type (DataResponse<T, AFError>).

Please find attached the used code and a screenshot of the error. Can you help me throught with this issue?

best regards,

Patrick

Alamofire 5.2
XMLMapper 2.0.0
Xcode 12.3

Schermafbeelding 2020-12-29 om 15 59 23

class AllCnannelModel : XMLMappable {
            
            var nodeName: String!
            
            var  id : Int?
            var  name: String?
            var  url : URL?
            var  picture : URL?
            var  category_id: Int?

            required init?(map: XMLMap) {}

            func mapping(map: XMLMap) {
                id<-map["PERSONID"]
                name<-map["NAME"]
                url<-map["url"]
                picture<-map["picture"]
                category_id<-map["category_id"]
            }
        }
        
        let getallpersonsquery = GetAllPersonsQuery()
        getallpersonsquery.nodeName = "query"
        getallpersonsquery.sql = "SELECT personid, name FROM person where personid = 150"
        
        AF.request(RequestUrl, method: .post, parameters: getallpersonsquery.toXML(), encoding: XMLEncoding.default, headers: headers)
            .redirect(using: redirector)
            .responseXMLObject(completionHandler: (DataResponse<[AllCnannelModel], AFError>) -> Void) in
        }

    }
@gcharita
Copy link
Owner

@PatrickB100 since you want to map your response XML to an array directly you need to use the responseXMLArray(queue:keyPath:dataPreprocessor:encoding:emptyResponseCodes:emptyRequestMethods:options:completionHandler:)
function instead of responseXMLObject(queue:keyPath:dataPreprocessor:mapToObject:encoding:emptyResponseCodes:emptyRequestMethods:options:completionHandler:) that you currently using.

With that modification your code will pass compilation:

AF.request(RequestUrl, method: .post, parameters: getallpersonsquery.toXML(), encoding: XMLEncoding.default, headers: headers)
    .redirect(using: redirector)
    .responseXMLArray { (dataResponse: DataResponse<[AllCnannelModel], AFError>) in

    }

@PatrickB100
Copy link
Author

@gcharita thanks! that made me some progress. Now i'm getting the following return: Cannot use optional chaining on non-optional value of type '[CDCatalog]'
and Value of type '[CDCatalog]' has no member 'cds'

find the code below. Do you have any suggestions?

thanks in advance,

Patrick

`class CDCatalog: XMLMappable {
var nodeName: String!

        var cds: [CD]?

        required init?(map: XMLMap) {}

        func mapping(map: XMLMap) {
            cds <- map["ROW"]
        }
    }

    class CD: XMLMappable {
        var nodeName: String!

        var title: String!


        required init?(map: XMLMap) {}

        func mapping(map: XMLMap) {
            title <- map["NAME"]
        }
    }
    
    AF.request(RequestUrl, method: .post, parameters: updateperson.toXML(), encoding: XMLEncoding.default)
        .redirect(using: redirector)
        .responseXMLArray { (response: DataResponse<[CDCatalog], AFError>) in
            
            
            switch response.result {
            
            case .success(let value):
                print("AF-Success")
                
                print(value?.cds?.first.title ?? "nil")
                
                


            case .failure(let error):
                print("AF-Error")
                print(error)

            }
        }`

image

@gcharita
Copy link
Owner

gcharita commented Jan 1, 2021

@PatrickB100 well, the error is obvious. You are trying to access cds property of CDCatalog, but your value is of type [CDCatalog] (array of CDCatalog objects).

It looks like you are trying to run the README example. If that's the case then you were correct before about using responseXMLObject(queue:keyPath:dataPreprocessor:mapToObject:encoding:emptyResponseCodes:emptyRequestMethods:options:completionHandler:) function, but you need to change the type to CDCatalog instead of [CDCatalog]:

AF.request(RequestUrl, method: .post, parameters: updateperson.toXML(), encoding: XMLEncoding.default)
    .redirect(using: redirector)
    .responseXMLObject { (response: DataResponse<CDCatalog, AFError>) in
        switch response.result {
        case .success(let value):
            print("AF-Success")
            print(value.cds?.first?.title ?? "nil")
        case .failure(let error):
            print("AF-Error")
            print(error)
        }
    }

Generally, which of the 2 function you have to choose depends on the XML that your API will respond to you.

@PatrickB100
Copy link
Author

@gcharita thanks for your support! i'm indeed following the readme example.

i'm getting a reponse in the debug area where it states the following:
*Result]: success(testApp.PersonDetailsView.(unknown context at $102f51890).(unknown context at $102f519cc).CDCatalog)

the returned body seems to be correct:

image

can this issue be related to the fact that there is an xml version encoding utf8 header in front of the response?

thanks,

Patrick

image

@gcharita
Copy link
Owner

gcharita commented Jan 1, 2021

@PatrickB100 this response has nothing to do with the README example. You need to create your own model. The one that matches with your response XML.

@gcharita
Copy link
Owner

gcharita commented Jan 1, 2021

@PatrickB100 a possible model that you can use to map your XML is this:

class Result: XMLMappable {
    var nodeName: String!

    var error: String?
    var rowset: Rowset?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        error <- map.attributes["error"]
        rowset <- map["ROWSET"]
    }
}

class Rowset: XMLMappable {
    var nodeName: String!

    var rows: [Row]?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        rows <- map["ROW"]
    }
}

class Row: XMLMappable {
    var nodeName: String!

    var name: String?
    var prefix: String?
    var firstName: String?
    var homeAddress: String?
    var homeZip: String?
    var homeCity: String?

    required init?(map: XMLMap) {}

    func mapping(map: XMLMap) {
        name <- map["NAME"]
        prefix <- map["PREFIX"]
        firstName <- map["FIRSTNAME"]
        homeAddress <- map["HOMEADDRESS"]
        homeZip <- map["HOMEZIP"]
        homeCity <- map["HOMECITY"]
    }
}

Calling your API with Alamofire may look like this:

AF.request(RequestUrl, method: .post, parameters: updateperson.toXML(), encoding: XMLEncoding.default)
    .redirect(using: redirector)
    .responseXMLObject { (response: DataResponse<Result, AFError>) in
        switch response.result {
        case .success(let value):
            print("AF-Success")
            print(value.rowset?.rows?.first?.name ?? "nil")
        case .failure(let error):
            print("AF-Error")
            print(error)
        }
    }

@PatrickB100
Copy link
Author

@gcharita Thank you very much! it's working now. Do you know if there is a README on how to put reponse data from XMLMapper into an UITableView?

Patrick

@gcharita
Copy link
Owner

gcharita commented Jan 3, 2021

@PatrickB100 you need to use rows array to do that and follow Apple's official Filling a Table with Data documentation. You can also find other great posts online that match your particular case.

@gcharita
Copy link
Owner

gcharita commented Jan 9, 2021

Closing this since question have been answered and there is no issue.

@gcharita gcharita closed this as completed Jan 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants