您的位置:首页 > 移动开发 > IOS开发

[IOS]App Extension编程指南(iOS8/OS X v10.10):扩展类型--自定义键盘

2015-01-20 17:55 706 查看


 

本节由CocoaChina翻译组成员星夜暮晨博客)翻翻译自苹果官方文档  App
Extension Programming Guide--App Extension Types--Custom Keyboard  一节,敬请勘误。

通过使用第三方输入法替换系统原生输入法,用户可以实现一些特殊的功能。比如一个特别新颖的输入方式,或输入iOS原生输入法并不支持的语言。第三方输入法的基本功能很简单:通过点击、手势,或者其他输入事件,然后通过一个未分类的 NSString对象在当前文本输入对象的插入点插入文字。

卷首语

请先确保您开发的第三方输入法真的要用于整个系统。若您只打算为您的应用程序提供一个完全定制的输入法或者只打算给系统输入法添加新的定制按键,那么iOS SDK为您提供了更好的方法。详情见Text
Programming Guide for iOS中的Custom
Views for Data Input关于自定义输入视图和输入辅助视图的介绍。

当用户选择了某个输入法后,它将对用户打开的所有应用程序开放。因此,开发者创建的输入法至少包含了基本的输入功能,更重要的是,输入法必须允许用户切换到另一个输入法。

了解用户对输入法的期望

为了了解用户对您开发的第三方输入法的期望,请先向系统输入法学习:速度很快、反应灵敏并且能实现用户想要的功能。系统输入法永远不会中断用户的信息和请求。如果您提供需要用户与输入法程序交互的功能,请将这些功能添加到容纳这个输入法扩展的应用程序中。

iOS用户期望的输入法功能

允许用户切换到另一个输入法是iOS用户期望并且是所有第三方输入法必须提供的功能。在系统输入法中,这个功能由一个被称为Global Key的地球按钮提供。iOS8提供专门的API给第三方输入法设置"切换"功能,请参阅:Providing
a Way to Switch to Another Keyboard

系统输入法提供了一个基于现有文本输入对象的UIKeyboardType特性,来对相应的输入法按键集或布局做出改变的方法。比如说在输入电子邮件地址时,系统输入法上的句号键也会有相应的变化:只要长按该键,就能够选择一系列顶级域名后缀。记住用这些特性来设计您的第三方输入法。

使用区分大小写语言的iOS用户同样也期望输入法在一个句子中实现首字母自动大写。

以下是iOS用户期待的功能:

1.基于输入法输入特性的适当功能和布局

2.自动校正和建议

3.自动首字母大写

4.双击空格键自动添加句号

5.支持大写锁定

6.键帽插图

7.对于表意语言实现并行输入(例如中文)

您可以自行决定是否要实现以上的功能,但是需要注意的是,没有专门的API来实现上述的任何一个功能,所以如果您能够实现这些功能对您的输入法来说将是一个竞争优势。

自定义键盘不能实现的功能

您的自定义键盘不能访问在设置中的大部分通用键盘设置(设置->通用->键盘),比如说自动首字母大写和启动大写字母锁定键。同样, 您的第三方输入法也不能访问字典重设功能(设置->通用->还原->还原键盘字典)。为了让用户使用这些功能,请创建一个标准设置选 项,详情请见 Preferences
and Settings Programming Guide中的Implementing
an iOS Settings Bundle。您的第三方输入法设置将会出现在设置选项中的键盘选项区域内,并与您的第三方输入法相关联。

您的第三方输入法没有权限在某些文本输入对象当中输入。首先是所有安全文本输入对象,比如将secureTextEntry属性设为YES的输入框,这种输入框中显示的内容是一个个的点●●●●●●●。

当用户在安全文本输入对象中输入内容,iOS系统将暂时强行调用系统默认输入法,以保证用户的信息安全。当用户在其他非安全文本输入对象中输入时,您的第三方输入法将被重新调用。

您的第三方输入法也没有资格在电话号码对象中输入(就像联系人应用中的号码字段)。这些输入对象是专门为电信运营商所指定的一个小的数字字符集而建立的字符串对象,可以通过其是否具有下面任意一个输入法类型来识别。

1.UIKeyboardTypePhonePad

2.UIKeyboardTypeNamePhonePad

当用户在电话号码对象中输入时,系统将暂时强行用相应的标准系统输入法来替换。而当用户在其他的输入对象中输入并需要一个标准输入法适配其类型特点的时候,您的第三方输入法将会自动恢复。

程序开发者可以选择禁止所有的第三方输入法在他们的应用中运行。比如一个银行应用程序的开发者或者一个必须遵循HIPAA隐私规则的应用程序开发者将可能会这样做。这些应用程序使用定义在UIApplicationDelegate协议中的application:shouldAllowExtensionPointIdentifier:方法(返回值为NO),从而始终使用系统输入法。

由于一个第三方输入法只能在其UIInputViewController对象的主视图内显示,它将不能够选择输入框中的文字。文本选择是在应用程序的控制下,而第三方输入法并没有权限来访问它。同时第三方输入法也不允许移动光标位置。因此这也就意味着在编辑信息的时候无法移动光标,粘贴、复制以及剪切功能将无法使用。

第三方输入法和iOS 8.0的所有应用程序扩展一样,没有权限来访问设备话筒,所以听写输入也是不可能实现的。

最后,第三方输入法不能在顶行之外显示任何内容(就像当在系统输入法的顶行上长按一个键时)。

自定义键盘API快速上手

本节将会对使用API搭建第三方输入法进行一个快速指南。下图显示了一些运行输入法时的重要元素以及其在一个典型开发流程中的位置:



第三方输入法的基本结构

自定义键盘模板(位于iOS"应用程序扩展"目标模板组)包含了UIInputViewController的一个子类,这个子类将作为您输入法的主视图控制器。模板还包含了一个所需要的"切换输入法"的按钮的基础实例代码,其在
类中调用了advanceToNextInputMode方法。依据图1-1的建议向输入页面控制器的主页面(在它的inputView属性中)中添加视图、控制器、手势识别等。和其他的应用程序扩展一样,在目标对象中并没有窗口存在,因此它本身并没有根视图控制器。

模板的Info.plist文件可以配置一个输入法需要的最小值。请查看位于输入法目标Info.plist文件中的NSExtensionAttributes字典值。配置一个输入法的键值将在后文叙述。

默认情况下,第三方输入法并没有网络访问,也不能和容纳它的应用共享文件。如果想实现这些功能,必须在Info.plist文件中将RequestOpenAccess布尔值至YES。做了这个之后,会扩展第三方输入法的沙盒,就像在建立和维护用户信任提到的那样。

输入视图控制器符合不同的随着一个文本输入对象内容相互作用的协议:

1.为了插入或删除响应触摸事件的文本内容,使用UIKeyInput协议中的insertTextdeleteBackward方法。在输入视图控制器中的textDocumentProxy属性中调用这些方法。它代表了当前文本输入对象,并且符合UITextDocumentProxy协议。例如:
[self.textDocumentProxy insertText:@"hello "]; // 在插入点中插入“hello”字符串 [self.textDocumentProxy deleteBackward];       // 在插入点左边删除字符 [self.textDocumentProxy insertText:@"\n"];     // 在插入点中插入一个换行符(文本页面)


2.当您调用deleteBackward方法时,您可以自行决定要删除多少内容。通过使用textDocumentProxy属性中的documentContextBeforeInput您可以获得插入点前面的文字内容。例如:
NSString *precedingContext = self.textDocumentProxy.documentContextBeforeInput;


然后您可以删除您确定的内容,例如一个单独的字符亦或者是多余的空格字符。

3.为了控制插入点的位置,比如支持向前删除,调用
UITextDocumentProxy
协议的adjustTextPositionByCharacterOffset:方法。

4.为了响应可输入文本对象内容的变化,亦或者是响应用户在插入点发起的位置变化,可以执行UITextInputDelegate协议的方法。

为了展示适合当前文本输入对象的输入法布局,您可以响应对象的UIKeyboardType属性。对您支持的每一个特性,相应地改变您主页面的内容。

想要在您的第三方输入法中支持多种语言,您有如下两种选择:

1.为每一个语言单独创建一个输入法,分别作为不同的目标添加到共同的输入法管理应用程序中。

2.创建一个多语言输入法,用户可以动态地切换到恰当的语言上。想要动态切换语言,使用
UIInputViewController
类的primaryLanguage属性。

根据您想提供的以及用户期望您提供的语言代码,选择最有意义的选项来完成您的输入法。

每个自定义键盘(独立于其
RequestsOpenAccess
键的值)可以通过UILexicon类来访问一个基本自动校正。请充分利用这个类以及您自己精心设计的词典,来向用户键入的内容提供输入建议和自动校正。UILexicon对象包含不同来源的词汇,来源包括:

1.从用户的地址薄数据库中提取的不成对的姓和名

2.在设置->通用->键盘->用户词典中的短语列表

3.一个常用字字典

您能使用自动布局调整第三方输入法主视图的高度。默认情况下,根据屏幕大小和设备方向,第三方输入法的大小和系统输入法相同。第三方输入法的宽度总是由设置为和当前屏幕宽度相等。如果要调整第三方输入法的高度,可以改变其主视图高度约束。

下面的代码将显示如何定义和添加这样的约束:
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];


提示:在iOS 8.0中,当第三方输入法在屏幕上初始化结束后,您可以在任何时候调整其高度。

关于第三方输入法的开发要点

对于每一个第三方输入法,有两个很重要的要点:

1.信任: 您的第三方输入法能够让您访问用户输入的所有内容,因此您和您的用户之间的信任非常重要。

2.A "next keyboard"key:这个按钮能够让用户切换至另一个输入法,它必须成为每个第三方输入法界面的一部分,因此您必须在您的界面中提供这个按钮。

为了用户信任而设计

在开发第三方输入法时,第一个必需考虑的事就是如何建立和维护用户信任。这种信任取决于您对如何来最好保护隐私的理解,并知道如何实现它们。

提示:本节提供的指导将帮助您创建一个盘尊重用户的隐私的第三方输入法,并将会讨论您可以实现的方面以及在本节被描述的责任。为了了解iOS程序的要求,请阅读App Store审核指南、iOS用户界面指南以及iOS开发者程序许可协议,这些全都可以在App审核支持这个页面找到。

对于第三方输入法,以下是对于建立和维护用户信任最重要的三个方面:

1.输入的文本是安全的:用户只希望输入的信息能进入输入框或文档中,而不是被保存或上传。

2.尽可能少并恰当的使用用户数据:如果您记录或请求了其他的用户数据,比如通信录数据和地理位置信息,您就要负担起向用户解释您需要获取这些信息的原因。

3.准确性:上屏内容需要精确反应用户的点击,这点和隐私无关,而是用户能通过使用感受到您产品的精准能力。

为了建立用户信任,首先要考虑的是是否允许网络访问。虽然允许网络访问可以让您的第三方输入法实现许多功能,但与此同时也增加了不少的义务和责任。(见下表) 



如果您建立了一个没有联网权限的输入法,那么系统会确保用户的输入信息不能够给传递给您或者其他地方。如果您的目标是提供一个只具有一般功能的输入 法,请使用无联网权限的输入法。由于其存放在一个保密的沙盒内,无联网权限的输入法将让您在满足苹果公司的数据隐私准则和获得用户信任有一个好的开端。

如果您启用网络访问的话(如Using
the Xcode Custom Keyboard Template描述的那样),您在获得多种功能的同时也将承担更多的责任。

提示:要提交一个具备联网功能的输入法到应用程序商店,您必须坚持在苹果应用程序审查支持页面的所有相关指南。

作为一个开发者,每一个联网的输入法功能将带来不少的责任,如下表所示。一般情况下,开发者要尽最大可能来尊重用户数据以及不使用这些数据来实现某些用户不知道的目的。 



具有联网权限的输入法以及包含它的应用程序将可以向服务器发送用户输入的数据,使您能够使用您的计算资源来实现触摸事件处理和输入预测等功能。当您使用这 个功能时,如果接收到的按键操作或者声音数据超出了提供用户信息以及其他您许诺给用户的功能所需的数据,那么请不要储存它们。当您使用输入法的联网功能 时,请参上表来获知您的责任。

提供切换输入法的功能

系统输入法的Global键在用户拥有多个输入法时启动以便让用户自行切换。详见下图



您的第三方输入法必须也要提供切换输入法的功能

提示:要通过应用程序审核,您必须要提供明显的UI来允许您的第三方输入法切换到其他的输入法。

要让系统切换到其他输入法,您可以调用UIInputViewController类中的advanceToNextInputMode方法。系统将会挑选合适的“下一个”输入法;没有API来实现获取启用输入法的列表清单或者自行选择“下一个”切换的输入法。

Xcode 输入法模板包含了advanceToNextInputMode方法来响应其切换输入法的操作。为了最好的用户体验,请将您的切换输入法按钮放置在接近于系统切换输入法按钮的位置上。

开始第三方输入法的开发

在本节您将学习到如何创建一个第三方输入法以及根据您的期望来配置它,并最终能够在iOS模拟器或是一台设备上运行它。您同样也能学到当替换系统输入法时需要牢记的一些UI要素。

使用Xcode自定义键盘模板

创建一个输入法以及其关联应用程序的步骤和创建其他应用程序扩展的步骤稍有不同。本节将带领您获得一个最基本的输入法并运行它。

在containing app中创建第三方输入法

1.在Xcode中,选择File > New > Project,然后在iOS应用程序模板组(iOS Application template group)中选择空程序模板(Empty Application template)

2.单击Next

3.为这个工程命名(比如"中文输入法设置")并单击Next

4.定位到您想要保存该工程的位置,然后单击Create

这时,您拥有了一个空应用程序来为您的工程提供简单的功能,现在将输入法导入进去。

1.选择File > New > Target,并在iOS模板组(iOS template group)中选择第三方输入法模板(Custom Keyboard template)

2.单击Next

3.将目标命名为您想要输入法出现在iOS用户界面上的名称(比如:中文输入法)

4.确保项目和"Embed in Application"(嵌入到应用程序)菜单中显示了关联应用程序的名称(上面设立的“中文输入法设置”),然后单击Finish

接下来您能够设置自定义键盘的名称(显示在设置中的“第三方输入法”列表中),如下所述。

1.在Xcode项目导航中,选择关联应用程序的Info.plist文件(位于应用程序的Supporting Files文件夹中),打开属性列表编辑器,显示该文件的内容。

2.将光标移动到“Bundle Name”列,然后单击出现的“+”按钮。这将创建一个新的空属性列表行,接下来选择它的关键域(Key field)。

3.输入Bundle display name(如果名称自动出现,则按下回车)

4.在该行双击它的值域(Value field)以获得一个光标,然后输入您想显示的输入法名称

5.选择File > Save来保存您对属性列表文件的修改

下表总结了您可以在关联应用程序和输入法的Info.plist文件中配置的UI字符串。 



现在您可以在iOS模拟器或设备上运行基于该模板的输入法了,来探究其状态和功能。

运行第三方输入法并连接到Xcode调试器

1.在您的Xcode视图控制实现中设置一个断点。例如,在viewDidLoad方法中设置一个断点

2.使用Xcode的工具栏来确保有效方案菜单中指定了输入法方案以及一个iOS模拟器(或者连接着的设备)。

3.选择Product > Run,或者单击位于Xcode项目窗体左上角的Play按钮。Xcode将会提示您选择一个主程序,选择一个拥有可用文本段的应用程序,诸如联系人或者Safari.

4.单击Run

Xcode将会运行您指定的主程序,如果这是您第一次部署您的输入法扩展到iOS模拟器或者设备上,跟随以下操作来添加并使用输入法:

a.定位到设置->通用->键盘->键盘

b.单击添加新键盘

c.在第三方输入法组中,选择您新建的输入法名称。模态视图中将出现一个开关来启用您的输入法

d.单击开关来启用您的输入法。这时将会弹出一个警告框。

e.在警告框中,单击添加输入法来完成您的新输入法的启用。最后单击完成。

5.在iOS模拟器或者连接设备中调用您的第三方输入法

要执行此项操作,单击任何可用文本字段的应用程序或者选择Spotlight来显示系统输入法。接下来使用切换输入法键切换到您的输入法上。

现在您可以开始探索您输入法的性能,但是目前调试器还未连接上。从模板建立的输入法只有一个功能:允许您切换到之前使用的输入法。

在继续下一个步骤前,请确保您的第三方输入法正在运行。

6.接触您的输入法(这样在步骤8您能通过再次调用输入法在viewDidLoad中添加断点)

7.在Xcode中选择Debug > Attach to Process > By Process Identifier (PID) or Name

在出现的表中,输入您的输入法扩展的名称(包括空格,且是在创建它时指定的)。默认情况下,这是在项目导航器中的应用扩展组的名称。

8.单击Attach

Xcode将在Debug导航器中指示它正在等待连接

9.在任意一个iOS模拟器或者设备上的应用程序(这取决于您的使用),通过选中文本框来调用输入法

当您的输入法主视图开始载入的时候,Xcode调试器将会附加到您的输入法并且Xcode将会命中断点

配置第三方输入法的Info.plist文件

信息属性列表(Info.plist文件)键是特定于一个第三方输入法最显著的特征,能让您静态地声明您的输入法,包括其主要语言以及是否联网。

为了研究这些键值,打开您已经添加第三方输入法模板的Xcode项目。然后选择在项目导航器中的Info.plist文件(Info.plist文件在输入法目标的Supporting Files文件夹中)

在源文件文本中,第三方输入法的键值定义如下:
NSExtension      NSExtensionAttributes              IsASCIICapable                  PrefersRightToLeft                  PrimaryLanguage         en-US         RequestsOpenAccess                   NSExtensionPointIdentifier     com.apple.keyboard-service     NSExtensionPrincipalClass     KeyboardViewController


这些键值信息在App
Extension Keys中的Information
Property List Key Reference章节中进行了解释。使用在
NSExtensionAttributes
字典中的键值表示第三方输入法的特点和需求,如下所示:

IsASCIICapable--布尔值,默认为NO,表示第三方输入法是否可以向文档中插入ASCII字符串。如果您的第三方输入法专门提供UIKeyboardTypeASCIICapable输入法特性,那么将这个选项设置为YES。

PrefersRightToLeft--布尔值,默认为NO,表示第三方输入法使用的是否是一个从右到左的语言。如果您的输入法主语言是从右到左书写的,那么讲这个选项设置为YES。

PrimaryLanguage--字符串值,默认为en-US(美国英语),用以表示您输入法的主语言,使用模式为<语言>-<地区>。您可以在这个页面找到某一语言和地区所对应的字符串。

RequestsOpenAccess--布尔值,默认为NO,表示第三方输入法是否要扩展到已满足基本输入法需求的沙箱之外。如果开放存取功能,您的输入法将获得如下特性,但每一个都有相应的责任:

1.访问位置服务和地址本数据库,每一个都需在第一次访问时获得授权。

2.可选择与容纳该输入法的应用的共享容器,使得在应用中可以定制词汇表。

3.能够将输入的字符和其他输入事件上传至服务器进行处理。

4.访问iCloud,例如,能够确保输入法的设置以及您的自动修正词汇能够在所有用户设备上同步。

5.通过包含还输入法的应用,能够访问Game Center和应用内购买。

6.能够和受控应用进行协同,如果您使用来设计该输入法以支持移动设备管理(MDM)。

如果您确实要设置RequestsOpenAccess为YES,请确保您已阅读"设计用户信任"这篇文章,它介绍了您的责任以集如何尊重和保护用户的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IOS开发