URLSessionUploadTask
新しく作成されたものがすぐにキャンセルされるという奇妙な問題が発生しています。Xcode 8 の現在のベータ版のバグかどうかはわかりません。
投稿しようとしているコードは一度だけ正常に実行されたため、バグである可能性があると思われます。その後、変更は加えられず、単に機能しなくなりました。はい、文字通り一度実行した後、動作を停止しました。最後にエラーを投稿します。
以下にコードを掲載しますが、最初にここでのロジックがどのように機能するかを要約します。
私のテスト、またはユーザー公開 API (Playgrounds またはアプリで直接使用するための IE) は、authorize
メソッドを呼び出します。このauthorize
メソッドはbuildPOSTTask
、有効な URL を構築URLSessionUploadTask
し、メソッドによって使用されるを返しますauthorize
。
そうは言っても、コードは以下のとおりです。
セッション:
internal let urlSession = URLSession(configuration: .default)
アップロード タスクを作成する関数:
internal func buildPOSTTask(onURLSession urlSession: URLSession, appendingPath path: String, withPostParameters postParams: [String : String]?, getParameters getParams: [String : String]?, httpHeaders: [String : String]?, completionHandler completion: URLSessionUploadTaskCompletionHandler) -> URLSessionUploadTask {
let fullURL: URL
if let gets = getParams {
fullURL = buildURL(appendingPath: path, withGetParameters: gets)
} else {
fullURL = URL(string: path, relativeTo: baseURL)!
}
var request = URLRequest(url: fullURL)
request.httpMethod = "POST"
var postParameters: Data? = nil
if let posts = postParams {
do {
postParameters = try JSONSerialization.data(withJSONObject: posts, options: [])
} catch let error as NSError {
fatalError("[\(#function) \(#line)]: Could not build POST task: \(error.localizedDescription)")
}
}
let postTask = urlSession.uploadTask(with: request, from: postParameters, completionHandler: completion)
return postTask
}
上記の関数によって作成されたタスクを使用する認証関数:
public func authorize(withCode code: String?, completion: AccessTokenExchangeCompletionHandler) {
// I have removed a lot of irrelevant code here, such as the dictionary building code, to make this snippet shorter.
let obtainTokenTask = buildPOSTTask(onURLSession: self.urlSession, appendingPath: "auth/access_token", withPostParameters: nil, getParameters: body, httpHeaders: nil) { (data, response, error) in
if let err = error {
completion(error: err)
} else {
print("Response is \(response)")
completion(error: nil)
}
}
obtainTokenTask.resume()
}
テストでこのエラーを見つけました:
let testUser = Anilist(grantType: grant, name: "Test Session")
let exp = expectation(withDescription: "Waiting for authorization")
testUser.authorize(withCode: "a valid code") { (error) in
if let er = error {
XCTFail("Authentication error: \(er.localizedDescription)")
}
exp.fulfill()
}
self.waitForExpectations(withTimeout: 5) { (err) in
if let error = err {
XCTFail(error.localizedDescription)
}
}
次のエラーで常に即座に失敗します。
エラー Domain=NSURLErrorDomain Code=-999 「キャンセルされました」 NSErrorFailingURLStringKey = https://anilist.co/api/auth/access_token?client_secret=削除&grant_type=authorization_code&redirect_uri=genericwebsitethatshouldntexist.bo&client_id=ibanez-hod6w&code=削除}
次の点に注意してください。
- セッションで使用される URL は有効です。
- すべての資格情報が有効です。
- 以前は発生しなかった「キャンセルされた」エラーで即座に失敗します。どこでもタスクをキャンセルしていないため、システムによってキャンセルされています。
- 無期限実行が有効になっているプレイグラウンドでも失敗します。これは私のテストに限定されません。
これが私が試したことのリストです:
- これはバグだと思うので、まずプロジェクトをクリーンアップし、派生データを削除し、すべてのシミュレーターをリセットしようとしました。それらのどれも機能しませんでした。
- Macを再起動するところまで行きました...
- 強力なポインターがないためにアップロード タスクの割り当てが解除され、次に を呼び出しているという小さな疑いの下で、によって作成されたタスクを返すように
cancel
書き直して、テストの変数に割り当てました。タスクはまだキャンセルされていました。authorize
buildPOSTTask
私がまだ試していないこと (ただし、これらに取り組んでいる間、他のアイデアを受け入れます):
- 物理デバイスで実行します。これは iOS 10 プロジェクトであるため、現在 iPad に iOS 10 をダウンロードしています。編集:試してみましたが、これを行うことはできません。
私は何を試してみるべきかについてのアイデアがありません。生成されたログには有用な情報がないようです。
編集:
プロジェクト全体をここに投稿することにしました。とにかく完成したらオープンソースになり、私が取得したAPI認証情報はテストアプリ用です。