LoginSignup
0
2

More than 3 years have passed since last update.

データを他のアプリへ送る(Swift5)

Last updated at Posted at 2020-05-16

概要

めちゃくちゃお久しぶりです。書こう書こうと思ってるとすぐ時間が過ぎる・・・

さて、SNSへ投稿したりするあれです。
SNSだけじゃなくて対応したアプリ(自作含め)は表示されますので好きなアプリに送信すれば良いわけです。
今回はサンプル画像をメモに送って確認したいと思います。
IMG_1450.TRIM 2.gif

UIDocumentInteractionControllerを使います。
これを使ったサンプル記事はQiita内外でもあるのでご参照ください。

ところでこれ、ハマりました。
罠がありますがあんまり触れている方が少なかったので記事にしました。
画像(データ)が送れなかったり、コントローラが表示されなかったりしました。

まず、論よりコードです。動くやつ。
storyboardにてボタンの追加とイベント処理を追加してますがそれは省略します。

サンプルコード

ViewController.swift
// 
// Copyright (c) 2020年, hats_yaki. All rights reserved.
//
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    // 追加したコード
    @IBAction func touch(_ sender: Any) {        
        let img = UIImage(named: "cat4")!     // cat4.pngという名前でasset登録済とする
        _ = SendDocumentView(image: img, targetView: self.view)
    }

}
SendDocumentView.swift
//
// Copyright (c) 2020年, hats_yaki. All rights reserved.
//

import UIKit

class SendDocumentView :NSObject {

    var dController :UIDocumentInteractionController!
    var reference :NSObject!

    init(image:UIImage, targetView:UIView) {
        super.init()
        self.reference = self       // 自身への参照

        guard let data = image.pngData() else { return }

        // ファイル一時保存してNSURLを取得
        let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("tmp.png")!
        do{
            try data.write(to: url, options: Data.WritingOptions.atomicWrite)
        }catch{
            print("画像データ保存でエラー")
            return
        }

        dController = UIDocumentInteractionController.init(url: url)
        if !(dController.presentOpenInMenu(from: CGRect(x: 0, y: 0, width: 500, height: 300), in: targetView, animated: true)) {
            print("ファイルに対応するアプリがない")
        }
    }

}

ちょっとだけ解説

データ送信機能はSendDocumentView(Viewじゃないんですが)として独立させました。
これにUIImageと親となるUIViewを渡すと送信画面が表示されます。
疎結合なのでユーティリティのように使えるのではないでしょうか。

dController.presentOpenInMenuのところはもっと汎用的に書いている他の人のコードを参考にしてください。私はまだよくわかっていません。
あとdControllerの消滅とともにリソースが破棄されることを期待していますがそれもちゃんと動くかは要確認です。

ハマったとこ

さて、ハマったとこですがSendDocumentViewのinitの2行目に自身への参照を持たせています。
一見これに意味がなさそうですがこれがないと期待する挙動になりませんでした。
iOS12系のiPhoneではコントローラーは表示されるのですが画像が空になり、iOS13系のiPadだとそもそもコントローラーが表示されなかったりしました。
なんで違いが・・・違いが出る理由がわかりませんが参照関係にある(あるべき)オブジェクトの生存期間の違いによるものだと思われます。詳しい方教えてもらえたら嬉しいです・・・

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2