SSブログ

続・MKMapSnapshotterでsnapshotが取れなくなる件 [楽しいプログラミング]

実機の方は前記事で一見問題が回避されたようだが、Simulatorの方ではさらに凶悪な事態になっていた。snapshotがブロックに送られないどころか、ブロックそのものが呼び出されないことがあるのである。これは酷い。

正直Simulatorなんかどうでも良いのだが(は?)、「simulatorで起きることは実機でも起きる」とは昔から言い習わされていることだ。(言い習わされてねーよ!)

とりあえずエラーハンドリングできないのが困る。当たり前のことだが、(あっちの)処理が終了しないから成功か失敗かの決着を付けることもできないのである。おまけに「処理中ですよ」的なぐるぐるを回していようものなら(UIActivityIndicatorViewのことです)、宇宙が消滅するまでそいつは回り続けることになる。

なのでタイムアウトで無理やり終わらせることにした。(笑)

class ViewController: UIViewController {

    @IBOutlet weak var mapView: MKMapView!
    @IBAction func snapshot(_ sender: Any) {
        
        let semaphore = DispatchSemaphore(value: 0) // セマフォ〜!

        let options = MKMapSnapshotter.Options()
        options.region = self.mapView.region
        options.size = CGSize(width: 640, height: 480)
        
        let snapshotter = MKMapSnapshotter(options: options)
        snapshotter.start { (snapshot, error) in

            // Snapshot!!!
            guard let snapshot = snapshot
                else {
                    print("snapShotが出ーへん")
                    semaphore.signal()  // 終わりますた
                    return
            }

            // ファイルを書き込む場所
            let documentsPath = NSHomeDirectory() + "/Documents"
            let filename = "snapshot"
            
            var url = URL(fileURLWithPath: documentsPath)
            url.appendPathComponent(filename)
            url.appendPathExtension("png")
            print(url)

            // png dataを書き込む
            let data = snapshot.image.pngData()
            do {try data?.write(to: url)}
            catch {print(error)}
            semaphore.signal()  // 終わりますた
        }

        // 10秒だけ待ってやる(Mainでwaitすると本処理が固まるのでサブスレにする)
        DispatchQueue.global().async { 
            // 誰かがsignalする、または10秒経過するまでここ↓で待つ
            if semaphore.wait(timeout: DispatchTime.now() + 10) == .timedOut { 
          //タイムアウトしたときにここに入る        
                if snapshotter.isLoading {  // 一応キャンセルしておく
                    snapshotter.cancel()
                }
                print("snapShotが出ーへん")
            }
        }
    }
 }

ええんかいな?、、、こんなんで。(上のソースは雑すぎですw)

因みに初動で出力サイズ(options.size = CGSize(...の部分です)を小さめにするとたいていは通るが、画面サイズよりも大きいような出力サイズを設定するとこの現象が出る。そしてこれがまたさらに困ったことに、一度これが出ると何度やっても、出力サイズを小さくしようがどうしようが延々と出続けるのである。
アプリケーションを再起動した程度ではこの現象はなくならない。Simulationを再起動しなければならないのである。
どこかに何かのキャッシュが残っているのであろう。それが何かはわからない。自分のアプリフォルダ内の何だかよくわからないファイルを色々消してみたりしてみたが、事態は改善されない。そもそもDocumentsとTmp以外アプリケーション側で無闇やたらに消して良いものかどうか。

仮に実機でもこの現象が起きた場合、デバイスを再起動していただくのが現状では最適な復旧手段なのだが、それについてどこかに「Appleのヴォケがわけわからん不具合出してくるから一応タイムアウトしておいたが、一度この現象が出ると繰り返し出てくるからデバイス再起動してな」などと書こうものなら速攻で落とされるに違いない。(笑)

さてどうしたものか。。。

もう一つ因みに、この現象は昔は出なかった。画面サイズの4x4倍くらいの出力でも大丈夫だったかと。
いつから出るようになったかはわからないが(ちゃんとテストしないからだ!)、直近で変わったことは、iOSのアップ(12です)と、この処理周りをswiftに書き換えたことぐらいか。(はい?)
今さら「セクシー・ユー」か何かをバックにノリノリでSwiftに書き換えたようなソースをObjective-Cに戻す気力はないので、確認するつもりもない。(無料アプリなので強気です)

コメント(0) 
共通テーマ:blog

危険運転 [くだらないこと]

前にも言ったかもしれないが、例えばベートーベンの「運命」とかで、どアタマの「じゃじゃじゃ」はその前の8分休符を含めて曲であるそうだ。この曲は「じゃじゃじゃ」で始まるのではなく、「 じゃじゃじゃ」で始まるのである。つまり、実際に音がでる半拍前に、この曲の演奏は既に始まっているということである。
そんな極端な例を出さずとも、曲中に休符があったりする場合、よほどの音楽無知ではないかぎりそれを「演奏していない」とは言わない。

話は変わって、車の運転も同様である。信号で停止している際など「僕は車を運転してましぇーん」とは言わない。(何で武田鉄矢口調なんだよ!?)
駐車して車を離れた場合は微妙だが(駐車するという行為自体が運転ですね)、例えば他人にイチャモン付けるためにどう見ても「危険」である高速に車を停車させるような行為を「危険運転ではない」とか言うのであれば、それは明らかに屁理屈以下のどこだかの美しい国の言葉のレトリックというものであろう。昨今ではまったく信用ならない木っ端役人どもの端くれである司法の連中がどういう判断を下すか、不謹慎ながら実に楽しみである。

コメント(0) 
共通テーマ:blog

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。