iOS下的自定義鍵盤(譯)

(本文來自《Custom Keyboard》
自定義鍵盤為那些希望體驗(yàn)更新穎的輸入法或者需要用到iOS不支持的語言的用戶抽莱,提供了替代系統(tǒng)鍵盤的備選闪彼。自定義鍵盤的核心功能很簡單:響應(yīng)按鍵酬核、手勢或其它輸入事件庆捺,并提供轉(zhuǎn)換后的文本字串躏敢,并將該字串插入到當(dāng)前的光標(biāo)位置。

開始閱讀前
請先確認(rèn)你需要開發(fā)的的確是系統(tǒng)范圍的自定義鍵盤喉钢。如果只是希望在你的app內(nèi)部提供可自定義的鍵盤姆打,可以到《Custom Views for Data Input 》《Text Programming Guide for iOS》了解自定義輸入視圖輸入輔助視圖的相關(guān)內(nèi)容,iOS SDK為此提供了更好的備選方案肠虽。

當(dāng)用戶選擇了自定義鍵盤幔戏,該鍵盤即成為每個(gè)app的鍵盤。因此税课,你創(chuàng)建的鍵盤必須包含一些基本的功能闲延。其中最重要的是,必須允許用戶切換到其它鍵盤韩玩。

理解用戶對鍵盤的預(yù)期

要理解用戶對于自定義鍵盤的預(yù)期垒玲,可以系統(tǒng)鍵盤為標(biāo)桿——它反應(yīng)靈敏且高效。它不會用垃圾信息或請求打斷用戶輸入找颓。如果你提供了需要用戶交互的功能合愈,應(yīng)該把它們放到鍵盤的app里,而不是鍵盤上击狮。

iOS用戶預(yù)期的鍵盤功能

每個(gè)自定義鍵盤都必須提供的iOS用戶所預(yù)期的鍵盤功能是:切換到其它鍵盤的方法佛析。在系統(tǒng)鍵盤中,有一個(gè)小地球的按鍵用來完成此功能彪蓬。iOS 8也提供了專門的API用于切換到下一個(gè)鍵盤寸莫,可以參見《提供一種切換到其它鍵盤的方法》

系統(tǒng)鍵盤會根據(jù)當(dāng)前文本輸入對象的UIKeyboardType屬性档冬,展現(xiàn)與之匹配的鍵盤布局膘茎。如果當(dāng)前的輸入對象需要輸入郵箱,系統(tǒng)鍵盤的句號建就會變化:長按會冒出一些頂級域名的后綴作為候選酷誓。你在設(shè)計(jì)自己的鍵盤布局時(shí)也應(yīng)當(dāng)考慮到當(dāng)前的輸入對象屬性披坏。

iOS用戶還期望自動大寫:在一個(gè)標(biāo)準(zhǔn)的文本輸入?yún)^(qū)域,對于大小寫敏感的語言來說呛牲,應(yīng)當(dāng)讓句首的字母自動大寫刮萌。

這類功能列出如下:

  • 對輸入對象的屬性考慮適當(dāng)?shù)逆I盤布局
  • 自動糾錯(cuò)和建議
  • 自動大寫
  • 兩個(gè)空格后自動添加句號
  • Caps lock鍵的支持
  • 鍵帽上的美觀
  • 對于象形文字的多層轉(zhuǎn)換

你可以自行決定是否實(shí)現(xiàn)這些功能;系統(tǒng)并沒有為這些功能提供專用的API娘扩,在自己的輸入法中提供這些功能可以讓你的產(chǎn)品更有競爭力着茸。

系統(tǒng)鍵盤中的哪些功能不適用于自定義鍵盤

自定義鍵盤不能訪問在系統(tǒng)設(shè)置中的通用鍵盤設(shè)置數(shù)據(jù)(設(shè)置 > 通用 > 鍵盤),比如自動大寫琐旁、使Caps Lock可用涮阔。自定義鍵盤也不能訪問字典還原信息(設(shè)置 > 通用 > 還原 > 還原鍵盤詞典)。要滿足你用戶的靈活性要求灰殴,你應(yīng)該創(chuàng)建一個(gè)標(biāo)準(zhǔn)的設(shè)置bundle敬特,這個(gè)話題在《偏好和設(shè)置編程指南》《實(shí)現(xiàn)iOS設(shè)置Bundle》中有討論。這樣你的自定義鍵盤的設(shè)置就會出現(xiàn)在系統(tǒng)設(shè)置的鍵盤區(qū)域。

還有一些文本輸入對象伟阔,自定義鍵盤是不能在其上進(jìn)行輸入的辣之。首先就是任何安全相關(guān)的文本輸入對象。這類文本輸入對象設(shè)置了其secureTextEntry屬性為YES皱炉,在其上的輸入內(nèi)容將呈現(xiàn)為圓點(diǎn)怀估。

當(dāng)用戶在密碼框里輸入時(shí),系統(tǒng)會臨時(shí)用系統(tǒng)鍵盤來替代自定義鍵盤合搅。當(dāng)用戶在非密碼框里輸入時(shí)多搀,自定義鍵盤又會恢復(fù)回來。

自定義鍵盤也無權(quán)在撥號輸入的位置出現(xiàn)灾部,例如通訊錄的電話號碼輸入?yún)^(qū)域康铭。對于這類輸入對象,鍵盤是由運(yùn)營商指定的一個(gè)數(shù)字/字母的小集合組成赌髓,并且具備如下屬性:
UIKeyboardTypePhonePad
UIKeyboardTypeNamePhonePad

當(dāng)用戶點(diǎn)擊撥號輸入對象時(shí)从藤,系統(tǒng)將臨時(shí)用系統(tǒng)鍵盤替換掉你的自定義鍵盤。當(dāng)用戶再點(diǎn)擊其它標(biāo)準(zhǔn)輸入對象時(shí)锁蠕,自定義鍵盤又會恢復(fù)回來呛哟。

app的開發(fā)者可以選擇在app內(nèi)部不使用自定義鍵盤。例如銀行類app匿沛,或者必須遵守美國HIPAA隱私規(guī)則的app,可以這么干榛鼎。這類app實(shí)現(xiàn)來自UIApplicationDelegate協(xié)議的application:shouldAllowExtensionPointIdentifier:方法逃呼,并返回NO,以達(dá)到使用系統(tǒng)鍵盤的效果者娱。

由于自定義鍵盤只能繪制其UIInputViewController對象內(nèi)的主視圖抡笼,在它上面不能選擇文字。選擇文字是使用鍵盤的應(yīng)用程序控制的黄鳍。如果app提供了編輯菜單(如剪切推姻、拷貝和粘貼),鍵盤是無權(quán)訪問它的框沟。自定義鍵盤不能提供在光標(biāo)位置的自動inline糾錯(cuò)能力藏古。

在iOS8.0下,如所有擴(kuò)展app一樣忍燥,自定義鍵盤不能訪問麥克風(fēng)拧晕,因此不能實(shí)現(xiàn)語音輸入。

最后梅垄,顯示插圖不能超過鍵盤的主視圖上邊緣厂捞,系統(tǒng)鍵盤可以,但自定義鍵盤不行。如下圖靡馁,可以發(fā)現(xiàn)自定義鍵盤和系統(tǒng)輸入法的差別:
按鍵插圖不能超越上邊緣

自定義鍵盤API

本節(jié)將給出開發(fā)自定義鍵盤的快速入門欲鹏。如下圖,它展示了鍵盤運(yùn)行過程中一些重要的對象臭墨,以及它們在開發(fā)流程中的的位置:


自定義鍵盤的基本結(jié)構(gòu)

自定義鍵盤模板(在iOS“Application Extension”目標(biāo)模板組)包含一個(gè)UIInputViewController的子類赔嚎,它是你開發(fā)的鍵盤的主視圖控制器。該模板包含鍵盤所必需的“下一個(gè)鍵盤”按鈕的實(shí)現(xiàn)裙犹,它調(diào)用了UIInputViewController類的advanceToNextInputMode方法尽狠。如上圖所示,可以在輸入視圖控制器的主視圖(在其inputView屬性)中添加子視圖叶圃、控制器以及手勢識別器等袄膏。對于其它類型的擴(kuò)展應(yīng)用,在目標(biāo)上并不存在窗體掺冠,因此也就沒有根視圖控制器了沉馆。

在模板的Info.plist文件中有預(yù)先配置好的鍵盤所需要的最基本的值。參見其中的NSExtensionAttributes字典關(guān)鍵字德崭,配置一個(gè)鍵盤的關(guān)鍵字在《配置自定義鍵盤的Info.plist文件》中有介紹斥黑。

默認(rèn),鍵盤不能訪問網(wǎng)絡(luò)眉厨,不能和它的app共享容器锌奴。如果要具備這種能力,必須要將Info.plist文件中RequestsOpenAccess的值置為YES憾股。這需要擴(kuò)展鍵盤的沙盒鹿蜀,在《設(shè)計(jì)用戶信任》中有介紹相關(guān)內(nèi)容。

一個(gè)輸入視圖控制器遵從各種與文本輸入對象內(nèi)容交互的協(xié)議:

[self.textDocumentProxy insertText:@"hello "]; // Inserts the string "hello " at the insertion point
[self.textDocumentProxy deleteBackward];       // Deletes the character to the left of the insertion point
[self.textDocumentProxy insertText:@"\n"];     // In a text view, inserts a newline character at the insertion point
NSString *precedingContext = self.textDocumentProxy.documentContextBeforeInput;
然后就可以刪除你指定的文字區(qū)域了丈秩,比如單個(gè)字符還是空格后的所有字符。如果要按照語義執(zhí)行刪除淳衙,比如一個(gè)單詞蘑秽、句子饺著、還是一個(gè)段落,可以使用[《 CFStringTokenizer Reference》](https://developer.apple.com/reference/corefoundation/cfstringtokenizer-rf8)中描述的函數(shù)肠牲,注意每個(gè)語種的語義規(guī)則是不同的幼衰。
  • 為了控制光標(biāo)所在位置的操作,比如支持向前刪除文字缀雳,需要調(diào)用UITextDocumentProxy協(xié)議中的adjustTextPositionByCharacterOffset:方法渡嚣。比如向前刪除一個(gè)字符,代碼如下:
- (void) deleteForward {
    [self.textDocumentProxy adjustTextPositionByCharacterOffset: 1];
    [self.textDocumentProxy deleteBackward];
}
  • 通過實(shí)現(xiàn)UITextInputDelegate協(xié)議中的方法肥印,可以響應(yīng)當(dāng)前輸入文本對象的一些變化识椰,比如內(nèi)容變化以及用戶觸發(fā)的光標(biāo)位置的變化。

為了展現(xiàn)與當(dāng)前文本輸入對象適配的鍵盤布局深碱,需要參照該對象的UIKeyboardType屬性腹鹉,根據(jù)每種你的鍵盤所能支持的屬性,變化布局內(nèi)容敷硅。

在自定義鍵盤中功咒,有兩種方式來支持多語言:

  • 為每個(gè)語言創(chuàng)建一個(gè)鍵盤,每個(gè)鍵盤都作為向容器app添加的獨(dú)立的Target
  • 創(chuàng)建一個(gè)多語言鍵盤绞蹦,動態(tài)切換當(dāng)前語言力奋。可以使用UIInputViewController類的primaryLanguage屬性來動態(tài)切換語言幽七。

根據(jù)你要支持的語言數(shù)量以及你想提供的用戶體驗(yàn)景殷,你可以從上面選擇最合適的方案。

每種自定義鍵盤(需要RequestsOpenAccess)都可以通過UILexicon類訪問自動糾錯(cuò)的詞典澡屡。通過使用該類滨彻,并結(jié)合你自己的詞典設(shè)計(jì),可以在用戶輸入過程中為他提供輸入建議和自動糾錯(cuò)挪蹭。UILexicon對象包含來自如下源的單詞:

  • 來自用戶通訊錄的人名和姓
  • 在 設(shè)置 > 通用 > 鍵盤 > 快捷方式(文本替換) 列表
  • 通用詞典

你可以使用自動布局來調(diào)整你的自定義鍵盤主視圖的高度。默認(rèn)情況下休偶,自定義鍵盤會根據(jù)屏幕尺寸以及設(shè)備方向梁厉,和系統(tǒng)鍵盤的尺寸保持一致。自定義鍵盤的寬度通常與屏幕當(dāng)前寬度一致踏兜。修改自定義鍵盤主視圖的高度約束即可修改其高度词顾。

下面的代碼展示如何定義和添加約束:

CGFloat _expandedHeight = 500;
NSLayoutConstraint *_heightConstraint = 
    [NSLayoutConstraint constraintWithItem: self.view 
                                 attribute: NSLayoutAttributeHeight 
                                 relatedBy: NSLayoutRelationEqual 
                                    toItem: nil 
                                 attribute: NSLayoutAttributeNotAnAttribute 
                                multiplier: 0.0 
                                  constant: _expandedHeight];
[self.view addConstraint: _heightConstraint];

注意
在 iOS8.8下,你可以在主視圖畫到屏幕之后的任何時(shí)間里調(diào)整鍵盤高度碱妆。

自定義鍵盤的開發(fā)關(guān)鍵

自定義鍵盤開發(fā)有兩個(gè)關(guān)鍵點(diǎn):

  • 信任肉盹。 自定義鍵盤能訪問用戶輸入的內(nèi)容 ,因此在鍵盤和用戶間建立信任非常關(guān)鍵疹尾。
  • “下一個(gè)鍵盤”鍵上忍。 通過鍵盤界面必須能讓用戶能切換到下一個(gè)鍵盤骤肛。

為用戶信任所做的設(shè)計(jì)

作為自定義鍵盤的開發(fā)者,你首先應(yīng)當(dāng)考慮的是如何建立和維護(hù)用戶信任窍蓝。你要理解隱私策略的最佳實(shí)踐并知道如何實(shí)現(xiàn)它才能很好地踐行腋颠。

注意
本節(jié)為你創(chuàng)建自定義鍵盤提供相關(guān)的開發(fā)手冊,該手冊要求尊重用戶隱私吓笙。了解iOS編程要求淑玫,請閱讀應(yīng)用商店審核手冊iOS人機(jī)交互手冊面睛,iOS開發(fā)許可協(xié)議絮蒿,請參見蘋果的《應(yīng)用審核支持》《支持用戶隱私》叁鉴,《iOS應(yīng)用編程指南》土涝。

對于鍵盤,如下三個(gè)方面對于建立和維護(hù)用戶信任至關(guān)重要:
按鍵數(shù)據(jù)的安全亲茅。 用戶希望他們的敲鍵會落在文檔以及輸入?yún)^(qū)域內(nèi)回铛,而不是上傳到服務(wù)器或者用于其他不明目的。
最小化合理利用其它用戶數(shù)據(jù)克锣。 如果你的鍵盤還需要使用其他用戶數(shù)據(jù)茵肃,例如定位服務(wù)或者通訊錄,你有義務(wù)解釋這給用戶帶來的好處是什么袭祟。
準(zhǔn)確验残。把輸入事件轉(zhuǎn)換成文本要求精準(zhǔn),這本身雖然不是一個(gè)隱私話題巾乳,但他會影響到信任:每次文字轉(zhuǎn)換需要體現(xiàn)出你的代碼的精準(zhǔn)您没。

在信任的開發(fā)設(shè)計(jì)過程中,首先考慮的是是否要獲取open access權(quán)限胆绊。盡管開啟了open access權(quán)限能給自定義鍵盤開發(fā)帶來極大便利氨鹏,但這也增加了你作為開發(fā)者的責(zé)任。下面是標(biāo)準(zhǔn)的open access的能力和隱私考慮:

Open Access 能力和限制 隱私考慮
Off(default) ·鍵盤可以執(zhí)行所有基本鍵盤的職責(zé)

·可以訪問通用詞典以支持自動糾錯(cuò)和輸入建議
·訪問設(shè)置里的快捷短語
·不與containing應(yīng)用共享容器
·不訪問鍵盤容器以外的文件系統(tǒng)
·不訪問鍵盤容器以外的文件系統(tǒng)
·不能直接或間接訪問iCloud或游戲中心或應(yīng)用內(nèi)購買 | 用戶了解按鍵僅僅被發(fā)送到當(dāng)前使用鍵盤的應(yīng)用里 |
| On | ·具備非聯(lián)網(wǎng)自定義鍵盤的所有能力
·在用戶許可情況下可以訪問位置服務(wù)和通訊錄
·鍵盤和containing app可以訪問共享容器
·鍵盤可以為服務(wù)器側(cè)處理過程發(fā)送按鍵或其他輸入事件
·containing app自動糾錯(cuò)字典提供編輯界面
·通過containing app鍵盤可以使用iCloud來保證自動糾錯(cuò)詞典和設(shè)置的更新
·通過containing app压状,鍵盤可以參與到游戲中心和應(yīng)用內(nèi)購買
·如果鍵盤支持移動設(shè)備管理(MDM)仆抵,它可與被管理的應(yīng)用共同工作 | ·用戶了解鍵盤開發(fā)者會利用按鍵數(shù)據(jù)
·你必須遵守有聯(lián)網(wǎng)能力的鍵盤開發(fā)手冊iOS開發(fā)許可協(xié)議,可參見《應(yīng)用審核支持》 |

如果你的自定義鍵盤不需要open access權(quán)限种冬,系統(tǒng)確保敲鍵信息不會被發(fā)送給你的鍵盤以及別的地方镣丑。如果只想提供一般的鍵盤功能,請不要給鍵盤配備聯(lián)網(wǎng)能力娱两。由于有沙盒限制莺匠,不聯(lián)網(wǎng)的鍵盤一定是滿足蘋果的數(shù)據(jù)隱私手冊并能獲得用戶信任的。

開啟open access權(quán)限(如上所述十兢,可以在Info.plist文件中配置)趣竣,能給你的開發(fā)帶來更多可能性摇庙,同時(shí)也帶來更多的責(zé)任。

注意
向應(yīng)用商店提交一個(gè)open-access的鍵盤必須遵守蘋果《應(yīng)用審核支持》中的相關(guān)條款期贫。

每一個(gè)與open access相關(guān)的功能都需要你履行相應(yīng)的責(zé)任跟匆,應(yīng)當(dāng)最大限度地尊重用戶數(shù)據(jù),不得用于與用戶輸入無關(guān)的其他任何目的通砍。下表列出了open access帶來的好處以及開發(fā)者需承擔(dān)的責(zé)任:

能力 用戶利益示例 開發(fā)者責(zé)任
與containing app共享容器 為鍵盤的自動糾錯(cuò)詞典管理UI界面 要考慮到自動糾錯(cuò)數(shù)據(jù)屬于用戶隱私玛臂。不要把他發(fā)到你的服務(wù)器,用作與輸入無關(guān)的用途封孙。
把按鍵數(shù)據(jù)發(fā)到你的服務(wù)器 通過開發(fā)者的計(jì)算資源可以提供更好的按鍵處理結(jié)果和輸入預(yù)測 只有為用戶提供更好的輸入體驗(yàn)之用時(shí)迹冤,才能保存按鍵和語音數(shù)據(jù)
基于云的自動糾錯(cuò)詞典 把人名、地名虎忌、熱點(diǎn)新聞加入到自動糾錯(cuò)詞典中 不要把用戶身份與輸入數(shù)據(jù)關(guān)聯(lián)起來泡徙,不得將用戶信息用作與輸入體驗(yàn)無關(guān)的其他目的
通訊錄 把人名、地名膜蠢、電話號碼添加到自動糾錯(cuò)詞典中 不得講通訊錄用作與輸入體驗(yàn)無關(guān)的其他目的
位置服務(wù) 將附近的地名添加到自動糾錯(cuò)詞典中 不要在后臺使用位置服務(wù)堪藐,不得將位置信息發(fā)送到你的服務(wù)器并用于與輸入體驗(yàn)無關(guān)的其他目的

一個(gè)具有open-access權(quán)限的鍵盤和其containing app能將按鍵數(shù)據(jù)發(fā)送到服務(wù)器端,通過這些數(shù)據(jù)可以為用戶提供更好的輸入體驗(yàn)挑围。如果你使用了這些能力礁竞,當(dāng)不需要這些數(shù)據(jù)的時(shí)候,請及時(shí)在服務(wù)器端刪除杉辙。參見上面的表格來履行你使用open-access權(quán)限中的義務(wù)模捂。

提供切換到其他鍵盤的方法

系統(tǒng)鍵盤的小地球按鍵用于切換到其他鍵盤,如下所示:


系統(tǒng)鍵盤的小地球鍵

你的自定義鍵盤必須提供類似的機(jī)制能切換到其他鍵盤蜘矢。

注意
要通過應(yīng)用審核狂男,必須在你的鍵盤上提供明顯允許用戶切換鍵盤的UI標(biāo)識。

調(diào)用UIInputViewController類的advanceToNextInputMode方法可以切換到其他鍵盤品腹。系統(tǒng)會選擇下一個(gè)鍵盤岖食,沒有能獲得鍵盤列表的API,也沒有切換到指定鍵盤的API舞吭。

Xcode自定義鍵盤模板中就已經(jīng)在下一個(gè)鍵盤按鈕上具備了advanceToNextInputMode的功能县耽。為了提供最好的用戶體驗(yàn),應(yīng)當(dāng)把你的下一個(gè)鍵盤按鍵放在靠近系統(tǒng)鍵盤的小地球鍵的位置镣典。

開始自定義鍵盤的開發(fā)

本節(jié)中你將學(xué)習(xí)到如何創(chuàng)建自定義鍵盤,根據(jù)你的目標(biāo)配置并在iOS模擬器或物理機(jī)上把它運(yùn)行起來唾琼。你還將學(xué)習(xí)到一些替代系統(tǒng)鍵盤應(yīng)謹(jǐn)記的UI要點(diǎn)兄春。

使用Xcode自定義鍵盤模板

創(chuàng)建鍵盤及其containing app與其他擴(kuò)展應(yīng)用略有不同。本節(jié)將帶你領(lǐng)略基本鍵盤的開發(fā)和運(yùn)行锡溯。

在一個(gè)容器app中創(chuàng)建鍵盤赶舆,步驟如下:

  1. 在Xcode中選擇File > New > Project > iOS > Application選擇Single View Application模板哑姚。
  2. 點(diǎn)擊Next
  3. 填寫Project Name(如CKIme)芜茵,點(diǎn)擊Next叙量。
  4. 選擇要保存的位置,點(diǎn)擊Create九串。這樣绞佩,你就有了一個(gè)空app,該app只能完成一個(gè)簡單的操作猪钮,接下來它將承載鍵盤品山。在你提交到應(yīng)用商店之前,你需要完成一些有用的功能烤低。請到應(yīng)用審核支持參考應(yīng)用商店審核指南肘交。
  5. 選擇File > New > Target > iOS > Application Extension選擇Custom Keyboard Extension,點(diǎn)擊Next扑馁。
  6. 填寫Product Name(如CKbd)涯呻,點(diǎn)擊Finish
  7. 確認(rèn)ProjectEmbed in Application中都顯示的是容器app的名字(CKIme)腻要,點(diǎn)擊Finish复罐。如果彈出Activate “CKbd” scheme提示讓激活鍵盤工程,點(diǎn)擊Activate闯第。

接下來你可以根據(jù)需要決定是否要自定義鍵盤的group name市栗,它會出現(xiàn)在設(shè)置中的已購買鍵盤列表中。

自定義鍵盤group name咳短,步驟如下:

  1. 在Xcode工程導(dǎo)航視圖中填帽,選擇容器app的Info.plist文件,
  2. 在右側(cè)plist編輯器中咙好,鼠標(biāo)hover到Bundle name上篡腌,點(diǎn)“+”按鈕創(chuàng)建一行空屬性。
  3. 在Key中填寫Bundle display name勾效,回車
  4. 雙擊該行的Value嘹悼,填寫你要自定義的鍵盤group name。
  5. 選擇File > Save保存設(shè)置层宫。

下表匯總了在容器app和鍵盤app的Info.plist文件中你可以配置的UI字符串:

iOSUI字符串 Info.plist關(guān)鍵字
· 在系統(tǒng)設(shè)置的已購鍵盤列表中的鍵盤group name 在容器app的Info.plist文件中的Bundle display name
· 系統(tǒng)設(shè)置中的鍵盤名稱
· 鍵盤換列表中的鍵盤名稱 在鍵盤app的Info.plist文件中的Bundle display name

現(xiàn)在你可以在iOS模擬器或真機(jī)上運(yùn)行該鍵盤杨伙,看看它目前都具備什么行為和能力吧。

運(yùn)行自定義鍵盤并將Xcode調(diào)試器attach到它上面

  1. 在Xcode萌腿,你的view controller實(shí)現(xiàn)中設(shè)置一個(gè)斷點(diǎn)(比如可以斷在viewDidLoad上)限匣。
  2. 在Xcode工具欄確保當(dāng)前活動的項(xiàng)目為鍵盤項(xiàng)目,并對應(yīng)iOS模擬器或設(shè)備毁菱。
  3. 選擇菜單Project > Run米死,或點(diǎn)擊Build and then run the current scheme按鈕(即播放按鈕)锌历。Xcode會提示選擇host app。選擇一個(gè)帶有輸入框的峦筒,比如通訊錄或Safari究西。
  4. 點(diǎn)擊Run
    Xcode將運(yùn)行起你指定的host app物喷。如果這是你第一次使用鍵盤擴(kuò)展應(yīng)用辞州,需要現(xiàn)在設(shè)置中添加并啟用鍵盤:
    1. Settings > General > Keyboard > Keyboards
    2. 點(diǎn)擊Add New Keyboard...
    3. OTHER IPHONE KEYBOARDS中點(diǎn)擊你剛剛創(chuàng)建的鍵盤
  5. 在iOS模擬器或真機(jī)上浆洗,調(diào)出你的自定義鍵盤。
    點(diǎn)擊任意可輸入?yún)^(qū)域,將顯示出系統(tǒng)鍵盤碗降。按住小地球桩警,選擇你的自定義鍵盤屏箍。
    此時(shí)你將看到自定義鍵盤萝风,但是調(diào)試器尚未attach上來。一個(gè)從模板構(gòu)建而來的極簡鍵盤僅有一個(gè)Next Keyboard按鈕材蹬,點(diǎn)擊后切換回前一個(gè)鍵盤实幕。
  6. 取消你的鍵盤(以便在第8步中你可以再次調(diào)出鍵盤以命中viewDidLoad斷點(diǎn))
  7. 在Xcode中,選擇Debug > Attach to Process > By Process Identifier(PID) or Name
    在彈出對話框中堤器,輸入你的鍵盤擴(kuò)展應(yīng)用的名字(包含空格).默認(rèn)就是該擴(kuò)展應(yīng)用在工程導(dǎo)航窗口里的group name昆庇。
  8. 點(diǎn)擊Attach
    Xcode將顯示出等待attach的調(diào)試器闸溃。
  9. 在任意能輸入文字的app中調(diào)出鍵盤整吆。
    當(dāng)你的鍵盤主視圖開始加載時(shí),Xcode調(diào)試器將attache到你的鍵盤辉川,并命中斷點(diǎn)表蝙。

為自定義鍵盤配置Info.plist文件

自定義鍵盤的Info.plist文件允許靜態(tài)定義鍵盤的現(xiàn)式特征,包括主要語言乓旗,以及是否需要open access權(quán)限府蛇。

打開Xcode并切換到自定義鍵盤的target。在工程導(dǎo)航欄選擇Info.plist文件屿愚,按文本格式呈現(xiàn)如下:

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>IsASCIICapable</key>
        <false/>
        <key>PrefersRightToLeft</key>
        <false/>
        <key>PrimaryLanguage</key>
        <string>en-US</string>
        <key>RequestsOpenAccess</key>
        <false/>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.keyboard-service</string>
    <key>NSExtensionPrincipalClass</key>
    <string>KeyboardViewController</string>
</dict>

每個(gè)關(guān)鍵字在App Extension Keys中都有解釋汇跨。可以使用字典NSExtensionAttributes中的關(guān)鍵字來描述你的自定義鍵盤的特征和需求妆距,如下:

IsASCIICapable - 默認(rèn)為NO的布爾值穷遂。用戶鍵盤是否可以向文檔中插入ASCII字串。如果要為UIKeyboardTypeASCIICapable屬性的輸入對象展現(xiàn)單獨(dú)類型的鍵盤娱据,需要將該值置為YES蚪黑。

PrefersRightToLeft - 默認(rèn)為NO的布爾值。是否為從右到左的語種設(shè)計(jì)的的自定義鍵盤。

PrimaryLanguage - 默認(rèn)為en-US的字串祠锣。以<語種>-<區(qū)域>的形式描述鍵盤的主語言⊙拾玻可以到http://www.opensource.apple.com/source/CF/CF-476.14/CFLocaleIdentifier.c找到對應(yīng)的語種和區(qū)域伴网。

RequestsOpenAccess - 默認(rèn)為NO的布爾值。是否需要比基礎(chǔ)鍵盤更大的沙盒范圍妆棒。把該值置為YES將需要完全訪問權(quán)限澡腾,你的鍵盤將獲得如下能力,每個(gè)能力都伴隨有相應(yīng)的權(quán)限:

  • 訪問定位服務(wù)糕珊,通訊錄數(shù)據(jù)庫动分,相機(jī),每個(gè)都需要用戶允許
  • 與鍵盤的容器app共享容器數(shù)據(jù)红选,以便完成比如在容器app中管理用戶詞庫的界面的功能
  • 通過網(wǎng)絡(luò)發(fā)送按鍵澜公、輸入事件之類的數(shù)據(jù)供云端處理
  • 使用UIPasteboard
  • 播放音頻,包括使用playInputClick方法播放按鍵音
  • 訪問iCloud喇肋,可以用來根據(jù)用戶身份同步比如鍵盤設(shè)置坟乾、自定義自動糾錯(cuò)詞典
  • 通過容器app訪問游戲中心和應(yīng)用內(nèi)購買
  • 如果你的鍵盤支持移動設(shè)備管理(MDM),可以與被管理的app無縫合作

當(dāng)考慮是否將這些關(guān)鍵字設(shè)置為YES之前蝶防,一定要先閱讀《用戶信任設(shè)計(jì)》甚侣,這里描述了如何尊重和保護(hù)用戶數(shù)據(jù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末间学,一起剝皮案震驚了整個(gè)濱河市殷费,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌低葫,老刑警劉巖详羡,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異氮采,居然都是意外死亡殷绍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門鹊漠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來主到,“玉大人,你說我怎么就攤上這事躯概〉窃浚” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵娶靡,是天一觀的道長牧牢。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么塔鳍? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任伯铣,我火速辦了婚禮,結(jié)果婚禮上轮纫,老公的妹妹穿的比我還像新娘腔寡。我一直安慰自己,他們只是感情好掌唾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布放前。 她就那樣靜靜地躺著,像睡著了一般糯彬。 火紅的嫁衣襯著肌膚如雪凭语。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天撩扒,我揣著相機(jī)與錄音似扔,去河邊找鬼。 笑死却舀,一個(gè)胖子當(dāng)著我的面吹牛虫几,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挽拔,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼辆脸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了螃诅?” 一聲冷哼從身側(cè)響起啡氢,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎术裸,沒想到半個(gè)月后倘是,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袭艺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年搀崭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猾编。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘤睹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出答倡,到底是詐尸還是另有隱情轰传,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布瘪撇,位于F島的核電站获茬,受9級特大地震影響港庄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恕曲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一鹏氧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧佩谣,春花似錦度帮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞳秽。三九已至瓣履,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間练俐,已是汗流浹背袖迎。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腺晾,地道東北人燕锥。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像悯蝉,于是被迫代替她去往敵國和親归形。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353