扩展
iOS
应用
305
分享扩展
share extension
与动作扩展十分相似,让你的应用接收内容,然后分享。
Twitter
Facebook
Pinterest
应用都提供了分享扩展。
链接分享扩展
shared links extension
让应用把链接放到
Safari
“共享的链接”
区域。例如,
Twitter
应用提供了这样的扩展,你关注的人发布的包含链接的推文都
会出现在
Safari
中。
前面说过,本章将构建两个扩展:
一个
Spotlight
索引扩展,让
iOS
定期运行,更新
Spotlight
搜索系统。
一个“今天”扩展,让应用在通知中心里显示一个小组件
widget
),当用户从屏
幕顶部向下轻扫时显示。
为这个
iOS
应用添加
Apple Watch
支持时,还会添加一个应用扩展。
13.1
使用
Spotlight
索引扩展搜索
Spotlight
(见图
13-1
)是
iOS
内置的搜索系统。在主屏幕向下轻扫就会进入
Spotlight
在那里可以搜索设备和
Web
中的内容。
如果想让你应用的内容出现在
Spotlight
中,需要把内容添加到可搜索的索引中。可搜索
的索引是搜索数据库,用于定位设备中的一切;索引中没有的内容,不会出现在搜索结
果中。
12
章,我们使用
NSUserActivity
把文档标记为可搜索的。但是有个局限:只有打
开过文档,才能搜索。如果用户在其他设备中修改了文档的内容,搜索索引不会更新,
除非再次打开文档。
为了解决这个问题,我们将添加一个
Spotlight
索引扩展。系统会定期唤醒这个扩展,更
新可搜索的索引。具体更新什么,完全取决于你的应用这里,我们将扫描整个文档集合。
306
13
13-1
iOS 中的 Spotlight 中搜索
下面为这个项目添加扩展:
1.
打开“
File
”菜单,选择“
New
”→“
Target
”。
2.
选择“
iOS
”→“
Application Extension
”→“
Spotlight Index Extension
”(见图
13-
2
)。
扩展
iOS
应用
307
13-2
添加
Spotlight Index Extension
目标
之所以添加一个新目标,是因为严格来说扩展是完全独立的程序。也就是说,扩展
独立于容器应用,单独编译和链接。
3.
把这个新目标命名为
Notes-SpotlightIndexer
击“
Finish
后,
Xcode
会弹出一个窗口,问你是否想激活新创建的方案。创建
Spotlight
扩展时,
Xcode
会创建一个新方案,以便编译扩展。
4.
单击“
Activate
”,进入这个新方案。
现在,我们要赋予这个扩展访问
iCloud
容器的权限,因为若想访问用户的文档,就要访
问存放它们的容器。
1.
打开这个目标的属性,打开“
Capabilities
”标签页。
2.
启用
iCloud
,等到旋转图标消失。
3.
启用
iCloud Documents
308
13
4.
选择
Mac
应用和
iOS
应用使用的那个
iCloud
容器,确保没有选中其他容器。为此,
要把“
Use defaultcontainer
”改为“
Specify custom container
”。
现在,这个扩展有权限访问
iCloud
容器了。
接下来,我们要让
Notes-SpotlightIndexer
目标能访问定义重要文件名称的那个枚举。
1.
打开
DocumentCommon.swift
文件,然后选择“
View
”→“
Utilities
”→“
Show File
Inspector
”菜单,打开“
File Inspector
”。
2.
确保勾选了“
Notes-SpotlightIndexer
”旁边的复选框(见图
13-3
)。
13-3
DocumentCommon.swift 文件添加到 Notes-SpotlightIndexer 目标中
你看到的项目目标列表的顺序可能与图中稍有不同。没关系,只要把文件添加到正
确的目标中即可。
接下来,实现这个
Spotlight
索引扩展。
1.
打开
I
ndexRequestHandler.swift
,这个文件在添加目标时创建,
Xcode
在里面生成了
一些模板代码。文件中定义了
IndexRequestHandler
类,用于实现这个索引扩展的
核心功能。
扩展
iOS
应用
309
2.
在文件顶部添加下面这行代码:
import UIKit
IndexRequestHandler
中有两个主要方法:
searchableIndex(_,reindexAllSearchableItemsWithAcknowledgementHandler:)
searchableIndex(_,reindexSearchableItemsWithIdentifiers:,
acknowledgementHandler:)
第一个方法的作用是让索引更新程序知道,它应该重新扫描整个数据集合,然后将
其添加到
Spotlight
中。第二个方法的作用是让更新程序知道,它应该重新扫描特定
的文件。
为了实现这个扩展的功能,首先要获取这个应用知道的所有文档。为此,我们将实
现一个计算属性,查找本地的
Documents
文件夹和
iCloud
容器中的所有文档。
3.
把下述计算属性添加到
IndexRequestHandler
类中:
var availableFiles : [NSURL] {
let fileManager = NSFileManager.defaultManager()
var allFiles : [NSURL] = []
//
获取所有本地文件
if let localDocumentsFolder
= fileManager.URLsForDirectory(.DocumentDirectory,
inDomains: .UserDomainMask).first {
do {
let localFiles = try fileManager
.contentsOfDirectoryAtPath(localDocumentsFolder.path!)
.map({
localDocumentsFolder.URLByAppendingPathComponent($0,
isDirectory: false)
})
allFiles.appendContentsOf(localFiles)
} catch {
NSLog("Failed to get list of local files!")
}
}
//
获取
iCloud
中的文档
if let documentsFolder = fileManager
.URLForUbiquityContainerIdentifier(nil)?
.URLByAppendingPathComponent("Documents", isDirectory: true) {
do {

Get Swift学习手册 now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.