Touchdown 1.2公開!

Touchdown 1.2を公開しました。



ダウンロードはこちらから。

Ver.1.2の変更点は以下の通りです。

新機能

  • macOS High Sierra 10.13以降に対応
  • コマンドキーを押しながら起動することで設定を保存しない機能を追加
    • 一時的な設定変更が可能です


不具合修正

  • テキストフィールドにフォーカスが合った状態で変換すると、設定が適用されないことがあった問題を修正
  • 多数のファイルをDockアイコンへドラッグ&ドロップした時に一部のファイルが変換できない問題を修正

ぜひお試しください。

ファイルをDockアイコンにドラッグすると「検証中」で遅い問題への対処

Touchdown 1.2を実装中に気がついたのですが、macOS 10.3 High Sierraから、ファイルのダブルクリックやDockアイコンへのドラッグ時にファイルの検証が実行されることがあるようです。

通常使用では問題ないのですが、巨大なファイルや大量のファイルをドラッグした時に問題が発生。

アプリアイコンへのファイルドラッグを受け付けるNSApplicationDelegateのfunc application(NSApplication, openFiles: [String])が呼び出されるのが非常に遅くなっています。

しかも、もともとこのopenFilesはファイル数が多いと複数回呼び出される謎仕様なので、Touchdownの「まとめて受け取って一括変換」という仕様と相性が悪く、ver.1.1までは短いタイマーを貼って全ファイルの受け取りを待つという残念な実装になっていました。

High Sierraからはかなり長い間隔をあけてopenFilesが複数回呼び出されるケースがあるため、適当な対応では対処しきれなくなったため、変換前に確認する場合の仕様を変更することにしました。

従来:最後にまとめてドラッグされたファイルを変換

Ver1.2:変換確認中にドラッグされたファイルをキューに追加していって変換

これに伴い変換するファイルの管理もArrayからSetに変更して、重複しないようにしました。

OSがバージョンアップするとやはり色々ありますね。

Touchdown ver.1.2向け追加予定機能

macOS High Sierraがリリースされて1ヶ月ほど経ちましたが、Touchdown も近日中にVer. 1.2へバージョンアップします。

変更予定箇所は以下の通り。
  • macOS High Sierra 10.13以降に対応
  • コマンドキーを押しながら起動すると、設定の変更が保存されないように
  • 設定で数値を変更しても、適用されない事がある不具合を修正

Swift 4に移行したらファイルのドラッグ時にパスが取り出せない?

TouchdownをSwift 4に変換した際に、フレームワーク側の変更に伴うコードの置換が発生していました。

ファイルのドラッグ&ドロップに関する部分ではドラッグ受付登録が、
register(forDraggedTypes: [NSFilenamesPboardType]);
から
registerForDraggedTypes([NSPasteboard.PasteboardType.fileURL]);
になっています。

NSFilenamesPboardTypeの代わりにfileURLを使うようになったようです。

これに合わせてペーストボードから値を取得する部分が
sender.draggingPasteboard().propertyList(forType: NSPasteboard.PasteboardType.fileURL) as? [String]
のようなコードに置換されたのですが、ここでエラーが発生。

sender.draggingPasteboard().typesにfileURLが含まれているにも関わらず、どうも[String]にうまくキャストできていないようです。

色々調べたところ以下のコードがうまく動きました。
sender.draggingPasteboard().propertyList(forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")) as? [String]

フレームワーク側の不具合でしょうか?
ひとまずワークアラウンドとしてこの対応で進めることにします。

Swift 4に変換でNSKeyedUnarchiverがエラー

macOS High SierraになりSwiftも4にバージョンアップ。
TouchdownもSwift 3からSwift 4に移行します。

基本的にはXcodeの移行ツールに従うだけで、途中で聞かれる

  • Minimize Inference
  • Match Swift 3 Behavior

もせっかくなのでSwift 4推奨のMinimize Inferenceを選択しました。

ワーニングやエラーを手動で修正して実行したところ、以下のエラーが発生。

[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (ConvertSetting) for key (NS.objects); the class may be defined in source code or a library that is not linked

Swift 3版でConvertSettingというクラスをarchiveして保存していたのですが、Swift 4版では互換性がなくなり復元できなくなってしまいました。

原因を調べてみたところ、Swift 3では自動で付与されていた@objcが、Swift 4では自動で付与されなくなり、今後は明示的に記述する必要があるようです。

つまり、もともとCocoa BindingのためConvertSettingには暗黙で@objcが付いていたのが、Swift 4以降のタイミングで付与されなくなったと予想。

クラス定義の部分に
@objc(ConvertSetting)
を追記することで解決しました。
Cocoa Bindingのため@objcMembersも記載してあります。

というわけで、Swift 4(macOS High Sierra)版Touchdownは既知の不具合などを修正してからリリース予定です。

TouchdownをHigh Sierraで動作確認

macOS High Sierraがリリースされたため、Touchdown ver.1.1の動作を確認しました。

今のところ大きな不具合はなさそうです。

NSTableViewの行をドラッグ&ドロップ

やり方を理解するのに結構手間取ったのがNSArrayControllerのビューになっているNSTableViewの行をドラッグ&ドロップで入れ替える実装方法。

詳細な説明は省きますが、概念さえわかれば中身は意外とシンプルです。
NSTableViewDataSourceとして以下の3つを実装すればOK。

func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool

ドラッグ&ドロップの実態は、コピー&ペーストに近いものがあります。
ここでやるべきことはNSPastboardにユーザーが移動しようとしている行のIndexSet(複数行ドラッグの可能性があるためIndexSetが渡ってきます)をセットするだけ。
(コピーに相当。)

func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation

.moveを返せばドラッグ可能になります。

func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool

NSPasteboardから取り出した(ペーストに相当)IndexSetと、移動先として渡ってきた行番号を手がかりにNSArrayControllerが管理している配列を並び替えるだけです。

わかってしまえばシンプルで泥臭い実装をするだけですね。

Touchdown 1.2公開!

Touchdown 1.2を公開しました。 ダウンロードは こちら から。 Ver.1.2の変更点は以下の通りです。 新機能 macOS High Sierra 10.13以降に対応 コマンドキーを押しながら起動することで設定を保存しない機能を追加 一...