TextExpanderを色んなアプリで使いたいので、JAGTextExpanderManagerを作りました。

ぼくは、TextExpanderが好きで結構使っています。
といっても、それほどたくさんのスニペットを登録しているわけではないのですが、なくてはならないアプリです。

そんなTextExpanderですが、Macで出来ていることをiOSで実現するには比較的ややこしい内部処理をしているようで、バージョンアップのSDKの仕様が何回か変更されています。

現在、Version 2.3.1のSDKを利用しているのですが、デリゲートメソッドが結構あったのでBlocksへ置き換えたかったのと URLスキームのコールバックを受け取るためにUIApplicationDelegateへ、コードを書かなければなりませんが大体は定型のコードだったので、他のアプリでも使いやすいようにラッパークラスを作って使っていくつかのアプリに使っていました。

結構、使いやすかったのでコードを整理して公開してみようと思います。

依存関係は、もちろんTextExpanderのframeworkが必要です。


使い方です。

シングルトンクラスですので、sharedManagerでアクセスしてください。

アプリ名とスニペットの更新用とfill-in用のURLスキームはあらかじめ変数として設定しておく必要があります。

URLSchemeを受け取れるように、忘れずにXcodeで予めスニペットの更新用とfill-in用のURLを設定しておきましょう。

Textexpander wrapper 01

sharedManagerWithAppName:getSnippetsScheme:fillCompletionScheme:をUIApplicationDelegateクラスのインスタンスAppDelegateで呼び、インスタンスを保持しておくという例が以下のコードです。

// 変数の設定  
@interface AppDelegate ()

@property (nonatomic) JAGTextExpanderManager *textExpanderManager;

@end

// 初回起動時のタイミングのどこかで、このメソッドを呼ぶ。  
- (void)_initialize{

 _textExpanderManager = [JAGTextExpanderManager sharedManagerWithAppName:@"アプリ名"
                                                   getSnippetsScheme:@"スニペット更新用URLスキーム"
                                                fillCompletionScheme: @"Fill-in用URLスキーム"];

}

上記の設定が終わると、まずTextExpanderからデータを受け取ってSnippetsのデータを最新のものへと更新しなければなりません。

アプリへのTextExpanderのデータの読み込み

よくあるのが、設定画面でスイッチをオンにしてTextExpanderを有効にするという機能です。

Textexpander wrapper 02

これは、以下のようなコードで実現します。

まず、UISwitchのアクションを設定します。

- (void)changeTextExpanderOption:(id)sender {

  UISwitch *swt = sender;

 if (swt.on &&
    JAGTextExpanderManager.isTextExpanderTouchInstalled) {

     [[JAGTextExpanderManager sharedManager] getSnippets];

 } else {

     swt.on = NO;
 }
}

次にAppDelegateでURLを受け取ります。

// Callback受け取り  
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

 if ([[JAGTextExpanderManager sharedManager] handleSchemeURL:url]) {

     return YES;
 }

 return NO;
}

これで、データの読み込みはOKです。

スニペットを展開するための準備

通常であればUITextFieldUITextViewにスニペットを展開するために、UITextViewなどのインスタンス変数delegateSMTEDelegateControllerのインスタンスにする必要があります。
そして、通常通りUIViewControllerでもデリゲートメソッドを受け取りたい場合は、SMTEDelegateControllerのインスタンスのnextDelegateUIViewControllerを設定する必要があります。

これを一発で解決するように、いくつかメソッドを用意しています。

// このメソッドをUIViewControllerのどこかで呼ぶ。(テキスト入力の前には設定しておく。)   
- (void)_setupTextExpander{

 _textExpanderManager = [JAGTextExpanderManager sharedManager];

    BOOL enabledTextExpander = [_textExpanderManager snippetExpanded];
// 有効化確認
    if (enabledTextExpander) {

    // TextExpanderを有効にしたいビューを配列にする。
      NSArray *textObjects = @[_textField,_textView];

    // textObjects全てに、TextExpanderを有効にする。Fill-inは無効。
     [_textExpanderManager enableTextExpanderToTextObjects:textObjects nextDelegate:self];

    // textObjects全てに、Fill-inを有効にする。
     [_textExpanderManager enableFillinsToTextObjects:textObjects];

    }
}

これで、動くようになりました。

あとは、Fill-inの動作は基本的にデリゲートメソッドで受け取るのですがこれをBlocksで設定できるようにしています。

[[JAGTextExpanderManager sharedManager] fillinsAllActionsAtIdentifierForTextArea:^NSString *(id uiTextObject) {

          if ([_textField isEqual:uiTextObject]) {

             return @"_textField";
            }

            if ([_textView isEqual:uiTextObject]) {

               return @"_textView";
           }
          return nil;

    } prepareForFillinSwitch:^BOOL(NSString *textIdentifier) {

         return YES;

    } fillinCompletionHandler:^id(NSString *textIdentifier, BOOL userCanceledFill, NSInteger ioInsertionPointLocation) {

           if ([textIdentifier isEqualToString:@"_textField"]) {

             return _textField;
         }

         if ([textIdentifier isEqualToString:@"_textView"]) {

             return _textView;
         }

         return nil;
     }];

これらは、enableFillinsToTextObjectsなどのメソッドを呼び出していれば先に設定しなくても動くようにしています。

Fill-inの動作を細かく設定したい場合に、お使いください。

他の機能は、ほとんど元々用意されているものをラップしているだけです。

ぜひ使ってみてください。

全てGitHubにあげていますので、自由にお使いください。

GitHub : JAGTextExpanderManager – TextExpander wrapper

CocoaPodsからの利用は、以下の文字列をpodsfileへ書き込んでください。

     pod 'JAGTextExpanderManager'

これからも更新を続けていきますので、Feedlyへの登録をお願いします!

follow us in feedly

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です