4

I try to call to Google Places Api using Moya and have a problem with URL. Maya change characters in my URL. In this case for example before character ? adds %3f and change , for %2C. When I copy and paste this address into my web browser, I receive an error, but when I delete %3f and change and %2C on , I receive a correct answer form API. What should I set in Moya if I don't want to change this characters in my url?

my Moya provider looks like that:

extension GooglePlacesService: TargetType {

var baseURL: URL {
    return URL(string: "https://maps.googleapis.com")!
}

var path: String {
    switch self {
    case .gasStation:
        return "/maps/api/place/nearbysearch/json?"
    }
}

var parameters: [String : Any]? {
    switch self {
    case .gasStation(let lat, let long, let type):
        return ["location": "\(lat),\(long)", "type" : "gas_station", "rankby" : "distance", "keyword" : "\(type)", "key" : GoogleKeys.googlePlacesKey]
    }
}

var parameterEncoding: ParameterEncoding {
    switch self {
    case .gasStation:
        return URLEncoding.queryString
    }
}

var method: Moya.Method {
    switch self {
    case .gasStation:
        return .get
    }
}

var sampleData: Data {
    switch self {
    case .gasStation:
        return "".utf8Encoded
    }
}

var task: Task {
    switch self {
    case .gasStation:
        return .request
    }
  }
}


private extension String {
var urlEscaped: String {
    return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
}

var utf8Encoded: Data {
    return self.data(using: .utf8)!
  }
}

URL which generates Moya looks like that (doesn't work with API):

https://maps.googleapis.com/maps/api/place/nearbysearch/json%3F?key=MYAPIKEY&keyword=XXXXXX&location=51.0910166687869%2C17.0157277622482&rankby=distance&type=gas_station

URL which works with API:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=MYAPIKEY&keyword=XXXXXX&location=51.0910166687869,17.0157277622482&rankby=distance&type=gas_station

PiterPan
  • 1,760
  • 2
  • 22
  • 43
  • Problem solved. In `URL` you have to escaping ` ? ` mark. Correct url which we should use in `Moya` looks like that: `https://maps.googleapis.com/maps/api/place/nearbysearch/json` parameters: `key=MYAPIKEY&keyword=XXXXXX&location=51.0910166687869,17.0157277622482&rankby=distance&type=gas_station` – PiterPan May 30 '17 at 06:26
  • Could you please write the complete solution? I'm new to Moya and also experiencing this error. Thanks. – user-unknown Aug 23 '17 at 11:24

3 Answers3

5

I had the same issue with '?' gets converted to '%3F': enter image description here

The solution is to leave the path without tricky symbols(like "?", ",") and to put them in var Task of Moya setup with URLEncoding.default instead: enter image description here enter image description here

Vitya Shurapov
  • 2,200
  • 2
  • 27
  • 32
0

How to add query parameter to URL in Moya

MOYA Convert or Replace %3f into ? mark

My URL with %3f:-

http://multiseller-dev.azurewebsites.net/api/Support/get-comments/34%3Fpage=1&pageSize=10?page=1&pageSize=10

IN Path

var path: String {
    switch self {
    case .GetComments(let id, let page, let pageSize):
        return "api/Support/get-comments/\(id)"
    }
}

IN TASK

var task: Task {
    switch self {
    case .GetComments(let id,let page,let pageSize):
        let post = ["page" : page,
                    "pageSize" : pageSize
        ] as [String : Any]
        return .requestParameters(parameters: post, encoding: URLEncoding.queryString)
    }
}

OUTPUT URL:-

http://multiseller-dev.azurewebsites.net/api/Support/get-comments/34?page=1&pageSize=10?page=1&pageSize=10
0

You can write custom request mapping like:

final class func removePercentEncodingRequestMapping(for endpoint: Endpoint, closure: RequestResultClosure) {
        do {
            var urlRequest = try endpoint.urlRequest()
            if let url = urlRequest.url,
                let updatedString = url.absoluteString.removingPercentEncoding {
                urlRequest.url = URL(string: updatedString)
            }
            closure(.success(urlRequest))
        } catch MoyaError.requestMapping(let url) {
            closure(.failure(MoyaError.requestMapping(url)))
        } catch MoyaError.parameterEncoding(let error) {
            closure(.failure(MoyaError.parameterEncoding(error)))
        } catch {
            closure(.failure(MoyaError.underlying(error, nil)))
        }
    }

and use it via MoyaProvider initializer:

MoyaProvider<YourProvider>(
    requestClosure: MoyaProvider<YourProvider>.removePercentEncodingRequestMapping
)

The point is update urlRequest.url which is encoded wrong when you using "?", "," or another symbols in path