FinderSync로 Dropbox 모도키 만들기

8624 단어 MacOSXSwift코코아
Yosemite에서는 Dropbox가 Finder와 깊게 연동하여 작동하게 되었습니다. 동기화 상태를 나타내는 ✅ 배지는 전용 위치에서 그려지며 Dropbox 디렉토리에서 항목을 선택한 경우에만 전용 컨텍스트 메뉴도 표시됩니다.



이것은 Yosemite에서 새로 추가된 프레임워크인 FinderSync를 이용하여 실현됩니다. 이 FinderSync를 이용하면 Dropbox처럼 보이는 앱을 만들 수 있습니다.

FinderSync로 할 수 있는 일



FinderSync의 실체는 App Extension입니다. FinderSync를 사용하면 특정 디렉토리에 대해 다음을 수행할 수 있습니다.
  • 디렉토리의 항목에 대한 배지 설정
  • 디렉토리의 항목이 선택되었을 때 컨텍스트 메뉴 추가
  • Finder 도구 모음 항목 추가
  • 사용자가 디렉토리를 열었음을 감지합니다.

    FinderSync는 동기화 기능을 가진 앱을 Finder UI(와 각종 앱의 파일 조작 패널)와 연동시키기 위한 것으로, 단독으로 파일의 동기화 기능을 실현할 수 없습니다. 이것은 컨테이너 앱 측에서 FSEvents등의 API를 이용하는 것으로 실현할 수 있을 것입니다.

    FinderSync 사용법



    Xcode에서 Cocoa 앱 프로젝트를 열고 Finder Sync Extension 타겟을 추가하면 FinderSync의 병아리가 생성됩니다. FinderSync 프레임워크에는 FIFinderSyncFIFinderSyncController 의 2 개의 클래스 밖에 없기 때문에, 쉽게 전체상을 파악할 수 있다고 생각합니다. FIFinderSync의 서브 클래스를 작성해, 그 중에서 FIFinderSyncController의 메소드를 호출하는 형태로 구현합니다.

    다음은 구현 예를 보여줍니다.
    class MyFinderSync: FIFinderSync {
    
        let controller = FIFinderSyncController.defaultController()
    
        override init() {
            super.init()
    
            // 対象のディレクトリを登録する
            controller.directoryURLs = NSSet(object: NSURL(fileURLWithPath: "/Path/To/Mybox")!)
    
            let doneImage: NSImage! = ... // ファイルのステータスに対応するバッジ画像の生成 ✅
            controller.setBadgeImage(doneImage, label: "Done" , forBadgeIdentifier: "Done")
        }
    
        // アイテムが表示されるときに呼び出される
        override func requestBadgeIdentifierForURL(url: NSURL!) {
            let isDone = ... // ファイルの何らかのステータスを取得
            if (isDone) {
                // init内で用意したDoneバッジをアイテムにセットする
                controller.setBadgeIdentifier("Done", forURL: url)
            }
        }
    
        // 各種メニューを返す
        override func menuForMenuKind(menuKind: FIMenuKind) -> NSMenu! {
            var menu: NSMenu!
            switch menuKind {
            case .ContextualMenuForItems:
                menu = ... // ディレクトリ内のアイテムを選択した際のコンテクストメニュー
            case .ContextualMenuForContainer:
                menu = ... // 対象ディレクトリ自体を選択した際のコンテクストメニュー
            case .ContextualMenuForSidebar:
                menu = ... // サイドバーにある対象ディレクトリを選択した際のコンテクストメニュー
            case .ToolbarItemMenu:
                menu = ... // ツールバーボタンをクリックした際に表示されるプルダウンメニュー
            }
            return menu
        }
    
        // ツールバーにボタンを追加する場合には、下記の3メソッドをオーバーライドする
    
        override var toolbarItemName: String! {
            return "Mybox Sync"
        }
    
        override var toolbarItemToolTip: String! {
            return "Mybox Sync"
        }
    
        override var toolbarItemImage: NSImage! {
            let toolbarIcon: NSImage! = NSImage(named: NSImageNameCaution)
            return toolbarIcon
        }
    
        // 下記の2メソッドをオーバーライドすると、ユーザが対象のディレクトリ内に入るとき、出るときに通知される
    
        override func beginObservingDirectoryAtURL(url: NSURL!) {
            ...
        }
    
        override func endObservingDirectoryAtURL(url: NSURL!) {
            ...
        }
    
    }
    

    작성한 FIFinderSync의 서브 클래스를 Info.plist의 NSExtensionPrincipalClass 키의 값으로 설정해, NSExtensionPointIdentifier 키의 값을 com.apple.FinderSync 로 하는 것으로, FinderSync Extension로서 빌드할 수가 있습니다.

    요약



    위에서 설명한 짧은 코드로, 할리보테이지만 Finder에서 Dropbox와 같은 외형과 거동을 실현할 수 있어 개발자는 동기 기능 등의 구현에 주력할 수 있게 됩니다.
  • 좋은 웹페이지 즐겨찾기