頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


macOSでオブジェクトをクリップボードに入れる

macOSでコピー・ペーストのために文字列とかではなく自作クラスのオブジェクトをクリップボードに入れたい。
文字列のサンプルなら簡単に見つかるのだがオブジェクトはどうするのがベストプラクティスなのか書いてる今もよくわからない。
現時点で動いたコードはおおよそこんな感じ。
@IBAction func copy(_: Any)  {// コピー(⌘+c)でコールされる

let person = Person(withName: name, age: age)//(1)
let data = try! NSKeyedArchiver.archivedData(withRootObject: person,
requiringSecureCoding: true)//(2)

let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setData(data, forType: .string)//(3)
}

@IBAction func paste(_: Any) {// ペースト(⌘+v)でコールされる

let pasteboard = NSPasteboard.general
if let data = pasteboard.data(forType: .string) {//(4)
let classes = [Person.self]
if let person = try! NSKeyedUnarchiver.unarchivedObject(ofClasses: classes,
from: data) as? Person {
print("pasted object, name=\(person.name!), age=\(person.age!)")
}
}
}
まずクリップボードに入れるところ。
(1)入れるのはPersonクラス(よくあるよね)のオブジェクトとする。
(2)このクラスはNSSecureCodingプロトコルに準拠させてる(ここでは詳細略)のでData型に変換できる。
(3)setData(_:forType:)でdataをクリップボードに入れる。ここでのタイプに何を指定すればいいのかわからず、とりあえず.stringとしてる。

次にペーストしてクリップボードの中身を取り出すところ。
(4)NSPasteboardオブジェクトからDataオブジェクトを取り出す。ここでもタイプは.stringとしてる。
後は元のPersonオブジェクトに変換してる。ここでは簡略化のためにtry!としてるけどちゃんとdo/catchしないとカラの時にペーストすると落ちるかもしれない。

一応これで、動いたのだが、、、(3)、(4)で指定するタイプをここでは.stringとしてるが.pngでも動いた。ただしコピー側とペースト側を揃えておけばだが。リファレンスを読んでもわからない、、、
あと、リファレンスには
pasteboard.declareTypes([.string], owner: nil)
↑が必要とあるけどなくても動く、、、



macOS 10.15.6 Catalina
Xcode 11.7
Swift 5.2.4
スポンサーサイト




<< App Clipに対応する  TopPage  NSTableViewであるセルを編集できないようにする >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
https://ringsbell.blog.fc2.com/tb.php/1361-7cba9b48




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.