こんにちは。
前回の記事でOpenCVのAPIを用意したので、それを使った簡単なiOSアプリを作ります。
GCP + Apache + mod-wsgi + Django 独自ドメインで公開
こんにちは。 OpenCVを使ったDjangoAPIを作成して、独自ドメインで公開という事をしたくなりました。思い立ってから1週間、呪われた1週間でした。色々試してようやく...
アプリを作る際に悩むのがネイティブ(Xcode-Swift)かハイブリッド(Phonegap,fultter..)か。。Swiftは触った事がなくて、学習コストが高いので、JavascriptかPythonが使えたらいいのですがPhonegap設定で躓く躓く。。fultterも未経験でSwift同様で学習コストが高いので、もう腹をくくってネイティブ(Xcode-Swift)で行ってみます。フォトライブラリーを起動して写真を選択して、その写真をAPI向けにアップロードして結果を受け取り、処理する。だけのシンプルアプリだから、大丈夫でしょう。
まぁ、世の中そんなに甘くないよね。
mami
Swiftクセが強い(笑)
なので、今回は以下2点に絞ってお話します。
・APIにPOSTして結果をJSONで受取る
・非同期処理のAPIの結果を待って処理する
目次
APIにPOSTして結果をJSONで受取る
API呼び出してJSONで受取るFuncを作ります。
func processAsyncFaceDetect(image: UIImage?){ var face: FaceDect? let url = URL(string: "http://[api url]") let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let boundary = UUID().uuidString var request = URLRequest(url: url!) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") var uploadData = Data() uploadData.append("\r\n--\(boundary)\r\n".data(using: .utf8)!) uploadData.append("Content-Disposition: form-data; name=\"image\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!) uploadData.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!) uploadData.append((uploadimage?.jpegData(compressionQuality: 1.0)!)!) uploadData.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!) session.uploadTask(with: request,from: image) { data, response, error in DispatchQueue.global().async { if(error != nil){ print("\(error!.localizedDescription)") } face = try! JSONDecoder.init().decode(FaceDect.self, from: data!) } }.resume() } struct FaceDect: Decodable { var success: Bool var num_faces: Int? let faces: [[Int]]? }
非同期処理のAPIの結果を待って処理する
APIの結果を使いたいので、結果を待って次の処理をするようにします。
ちなみにこちらのサイトを殆どコピーさせて頂きました。ありがとうございます。
APIの結果が入ったらそれを通知するようにします。以下色付き行(1,29行目)の部分を変更します。
func processAsyncFaceDetect(image: UIImage? ,_ after:@escaping (FaceDect) -> ()){ var face: FaceDect? let url = URL(string: "http://[api url]") let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let boundary = UUID().uuidString var request = URLRequest(url: url!) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") var uploadData = Data() uploadData.append("\r\n--\(boundary)\r\n".data(using: .utf8)!) uploadData.append("Content-Disposition: form-data; name=\"image\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!) uploadData.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!) uploadData.append((uploadimage?.jpegData(compressionQuality: 1.0)!)!) uploadData.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!) session.uploadTask(with: request,from: uploadData) { data, response, error in DispatchQueue.global().async { if(error != nil){ print("\(error!.localizedDescription)") } face = try! JSONDecoder.init().decode(FaceDect.self, from: data!) after(face !) } }.resume() } struct FaceDect: Decodable { var success: Bool var num_faces: Int? let faces: [[Int]]? }
上記の非同期処理Funcを作成したら、それを同期処理にするFuncを作成します。
func processSyncFaceDetect(image: UIImage?) -> FaceDect? { var result: FaceDect? let semaphore = DispatchSemaphore(value: 0) processAsyncFaceDetect(image: image) { (facerect: FaceDect) in result = facerect semaphore.signal() } semaphore.wait() return result }
コメント