8798
1.環境  
XcodeVer:6.2  
Deployment Target:iOS7.1  
Device:iPhone  
開発言語:Objective-C

2.具体的なプログラミングの問題  
顔文字をユーザ辞書に登録できるアプリを作成しています。  
アプリ内から呼び出した「ユーザ辞書」の「よみ」部分を自動で「☻」文字に変更したいと考えています(よみを「☻」で辞書登録した内容は、顔文字一覧に登録されるため便利)。  
現在、アプリ内からユーザ辞書を呼び出す所まではできましたが、「よみ」部分が「☻」文字に変更出来ない状況です。

3.調べた、試してみたことなど  
・ユーザ辞書を呼び出すUITextFieldの非公開メソッド「-
(void)_addShortcut:(id)arg1;」を確認(引数が「よみ」の値？、引数に「☻」を渡したが変化無し)。  
・「class-dump」を使用して「_addShortcut:」内のコードを見ようとしましたが、ヘッダー部分しかダンプ出来ず分かりませんでした。  
・「よみ」に該当するプロパティが無いか調べましたが、それらしいものは見つけられませんでした。

4.本機能を実装しているアプリ  
かわいい顔文字登録：<https://itunes.apple.com/jp/app/kawaii-yan-wen-zi-deng-
lu/id882667868?mt=8>  
かわいい顔文字「かおもじシンプル」…：<https://itunes.apple.com/jp/app/kawaii-yan-wen-zi-
kaomojishinpuru/id788417205?mt=8>

5.コード内容

```

    // FIXME:辞書登録機能の処理
    - (void)runJisyoSignUpTextField:(UITextField*)textField text:(NSString*)text {
        // テキストフィールドに顔文字を代入
        textField.text = text;
        // テキストフィールド内のテキストを全選択
        [textField selectAll:nil];
        // ユーザ辞書呼び出し
        if([textField respondsToSelector:@selector(_addShortcut:)]) {
            [textField performSelector:@selector(_addShortcut:) withObject:nil];
        }
        // テキストフィールドのテキストを空にする
        textField.text = @"";
        // テキストフィールドのキーボードを閉じる
        [textField resignFirstResponder];
    }
    
```

ご存知の方がおられましたら、ご教授頂けないでしょうか。  
よろしくお願い致します。
CC BY-SA 3.0
2015-04-03T17:32:29.223
8734
2015-08-03T07:44:05.343
9118
question
ios
アプリ内から呼んだ「ユーザ辞書」の「よみ」部分を変更する方法
`UITextField`からユーザ辞書登録の「よみ」の部分を変更するようなAPIは用意されていないと思います。

例として挙げられたアプリケーションは、ユーザ辞書のビューが表示されたあとで、ビュー階層を調べて、「よみ」のテキストフィールドに入力されている文字列を書き換えているのではないかと思います。

非公開APIを使う前提のようですので、別の方法としてユーザー辞書登録のビューコントローラを直接利用する方法を下記に示します。

### UIEditUserWordController クラスをロードする

ユーザー辞書登録のビューコントローラは`UIEditUserWordController`のインスタンスです。

`UIEditUserWordController`のクラスは`UITextField`などを使って、ユーザー辞書の画面を呼び出す前はロードされていませんので、まず、このクラスを`dlopen`関数で強制的にロードします。

```

    dlopen("/System/Library/PreferenceBundles/KeyboardSettings.bundle/KeyboardSettings", RTLD_LAZY);
    
```

### UIEditUserWordController クラスをインスタンス化する

`UIEditUserWordController`クラスには下記の２つのカスタムコンストラクタがあります。  
`text`パラメータ辞書に登録される「単語」の  
`andShortcut`パラメータが、「よみ」の値になりますので、このパラメータに「☻」を渡せば望みの動作になります。

```

    - (id)initWithText:(id)arg1;
    - (id)initWithText:(id)arg1 andShortcut:(id)arg2;
    
```

`UIEditUserWordController`は非公開APIですので、利用するには`NSClassFromString`などリフレクションを使用します。

上記にカスタムコンストラクタを呼び出せるようにするために、適当にカテゴリなどを利用して、宣言を書いておきます。

```

    @interface UIViewController (UIEditUserWordController)
    
    - (id)initWithText:(id)arg1;
    - (id)initWithText:(id)arg1 andShortcut:(id)arg2;
    
    @end
    
```

実際にインスタンス化するコードは次のようになります。

```

    Class clazz = NSClassFromString(@"UIEditUserWordController");
    if (clazz) {
        id controller = [[clazz alloc] initWithText:@"(^_^)" andShortcut:@"☻"];
    
```

### UIEditUserWordController を表示する

あとは`UIEditUserWordController`クラスを通常のビューコントローラと同様に利用するだけです。  
標準の挙動と同じようにするには`UINavigationController`でラップして、モーダルビューとして表示します。

```

    Class clazz = NSClassFromString(@"UIEditUserWordController");
    if (clazz) {
        id controller = [[clazz alloc] initWithText:@"(^_^)" andShortcut:@"☻"];
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
        [self presentViewController:navigationController animated:YES completion:nil];
    }
    
```

### 参考

最後に今回試したコードの全体を載せておきます。

```

    #import "ViewController.h"
    #import <dlfcn.h>
    
    @interface UIViewController (UIEditUserWordController)
    
    - (id)initWithText:(id)arg1;
    - (id)initWithText:(id)arg1 andShortcut:(id)arg2;
    
    @end
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
    
        void *handle = dlopen("/System/Library/PreferenceBundles/KeyboardSettings.bundle/KeyboardSettings", RTLD_LAZY);
        if (handle) {
            Class clazz = NSClassFromString(@"UIEditUserWordController");
            if (clazz) {
                id controller = [[clazz alloc] initWithText:@"(^_^)" andShortcut:@"☻"];
                UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
                [self presentViewController:navigationController animated:YES completion:nil];
            }
        }
    }
    
    @end
    
```
CC BY-SA 3.0
2015-04-05T14:39:44.823
8798
2015-04-05T14:39:44.823
5519
8734
answer