Создание целевого типа Moya в iOS

Я пытаюсь использовать Moya с RxSwift в своем проекте.

У меня возникла проблема с URL-адресом, содержащим "?"

Этот TargetType я создал

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

enum TMDb {
    case discoverMovieList(page: Int)
    case discoverMovieDetail(moive: Movie)
}

extension TMDb: TargetType {
    var baseURL: URL { return URL(string: BASE_URL)! }

    var path: String {
        switch self {
        case .discoverMovieList(page: let page):
            return "discover/movie?api_key=\(API_KEY)&sort_by=release_date.desc&page=\(page)"
        }
    }
    var method: Moya.Method {
        return .get
    }
    var parameters: [String: Any]? {
        return nil
    }
    var sampleData: Data {
        switch self {
            case .discoverMovieList(page: _):
                return "test".data(using: .utf8)!
            case .discoverMovieDetail(moive: _):
                return "test1".data(using: .utf8)!
        }
    }
    var task: Task {
        return .request
    }
    var parameterEncoding: ParameterEncoding {
        return URLEncoding.default
    }

}

Проблема в том, когда я делаю запрос. Возврат URL-адреса как-то неверен

Это URL, который я получил из консоли

Optional("https://api.themoviedb.org/3/discover/movie%3Fapi_key=58da429caf2e25e8ff9436665e2f0e36&sort_by=release_date.desc&page=1")

Но правильный должен быть

https://api.themoviedb.org/3/discover/movie?api_key=58da429caf2e25e8ff9436665e2f0e36&sort_by=release_date.desc&page=1

Что-то не так при обработке "?" (в URL-адресе он становится символом %3F. Как мы можем заставить его работать нормально?

Обновлять

Так я называю свою Мойю

let provider: RxMoyaProvider<TMDb>
    let persistentContainer: PersistentContainer

    func discoverMoiveList(for page: Int) {
        self.provider.request(TMDb.discoverMovieList(page: 1)) { (result) in
            print(result.value?.request?.url?.absoluteString ?? "no url")

        }
    }
}

person Lê Khánh Vinh    schedule 05.04.2017    source источник
comment
Кто-нибудь использует Moya для создания конечной точки?   -  person Lê Khánh Vinh    schedule 05.04.2017
comment
как мы можем справиться с? персонаж?   -  person Lê Khánh Vinh    schedule 05.04.2017
comment
Ваша проблема в том, что вы не знаете, как напечатать необязательную переменную в консоли без Optional()?   -  person kamil3    schedule 28.04.2017
comment
Привет, так как правильно печатать? правильно ли моя конструкция Moya?   -  person Lê Khánh Vinh    schedule 28.04.2017


Ответы (3)


Здесь у вас есть тема, как получить необязательную переменную без Opt(). Я предпочитаю такой способ, когда вы создаете extension:

extension Optional {
    func asStringOrNilText() -> String {
        switch self {
        case .some(let value):
            return String(describing: value)
        case _:
            return "(nil)"
        }
    }

}

print(result.value?.request?.url?.absoluteString.asStringOrNilText())
person kamil3    schedule 28.04.2017
comment
Привет, я применяю ваше предложение, но result.value?.request?.url?.absoluteString имеет тип String? компилятор жаловаться на строку нет члена asStringOrNilText - person Lê Khánh Vinh; 29.04.2017

Проблема не в "?". Это произошло из-за того, что вы использовали необязательные значения в URL пути. Управляйте BASE_URL и API_KEY, они не должны быть необязательными значениями.

С Мойей проблем нет. Вот результат Moya-Logger для вашего провайдера:

Moya_Logger: [29/04/2017 15:48:22] Request: https://api.themoviedb.org/3/discover/movie%3Fapi_key=58da429caf2e25e8ff9436665e2f0e36&sort_by=release_date.desc&page=1
Moya_Logger: [29/04/2017 15:48:22] Request Headers: [:]
Moya_Logger: [29/04/2017 15:48:22] HTTP Request Method: GET
Moya_Logger: [29/04/2017 15:48:23] Response: <NSHTTPURLResponse: 0x618000220360> { URL: https://api.themoviedb.org/3/discover/movie%3Fapi_key=58da429caf2e25e8ff9436665e2f0e36&sort_by=release_date.desc&page=1 } { status code: 200, headers {
Connection = "keep-alive";
"Content-Length" = 89;
"Content-Type" = "application/octet-stream";
Date = "Sat, 29 Apr 2017 12:48:23 GMT";
Server = openresty;
"X-RateLimit-Limit" = 40;
"X-RateLimit-Remaining" = 39;
"X-RateLimit-Reset" = 1493470113;
} }
person haydark    schedule 27.04.2017
comment
большое спасибо за ответ. но все BASE_URL и API_KEY являются строковыми. как мы можем сделать необязательный URL - person Lê Khánh Vinh; 28.04.2017
comment
Можете поделиться, как вы вызываете запрос вашего провайдера? - person haydark; 28.04.2017
comment
Привет, обновите способ, которым я вызываю запрос провайдера в вопросе. в основном я создаю маршрутизатор, соответствующий TargetType - person Lê Khánh Vinh; 28.04.2017
comment
Я думаю, что нет проблем ни с вашим провайдером, ни с чем-то еще. Вы должны просто принудительно развернуть результат. Взгляните на мою правку. - person haydark; 29.04.2017

Вы должны передать что-нибудь после ? в качестве параметра, таким образом Мойя знает, как правильно построить URL-адрес.

  var path: String {
    switch self {
    case .discoverMovieList(page: let page):
        return "discover/movie"
    }
}
var method: Moya.Method {
    return .get
}
var parameters: [String: Any]? {
     switch self {
     case .discoverMovieList(page: let page):
       return "["api_key":"\(API_KEY)",
                "sort_by":"release_date.desc",
                "page":page]"
}
}
person Matan Guttman    schedule 06.07.2017