如何在Swift中创建Action扩展
来源:互联网 发布:android php服务器 编辑:程序博客网 时间:2024/05/22 00:40
http://www.devtalking.com/articles/how-to-create-action-extension/
见证奇迹的时刻
先通过File > New > Project菜单创建一个新的工程,选择Single View Application:
然后通过File > New > Target菜单给给工程添加一个Target,选择Action Extension:
在创建Action扩展时需要指定一个Aciton类型,Apple提供了两种Action扩展的类型模板。一种是有用户界面的类型,包含一个UIViewController
和一个Storeboard
文件,可以自定义显示界面和行为。另一种是不带用户界面的类型,这种类型只允许我们处理来自Host应用的请求。
现在我们在工程中就可以看到刚才创建的Action扩展NoteAppExtension,它包含两个主要的文件,一个是Action.js
,另一个是ActionRequestHandler.swift
:
我们来看看这两个文件的作用。Action.js
文件用来实现和处理浏览器中请求的逻辑,在本文的例子中,它主要实现用户在浏览器中选中文本并发送到我们的应用中。ActionRequestHandler.swift
用来处理Host应用发送的请求和参数。
在实现逻辑之前我们需要设置一下扩展的属性,打开Info.plist
文件将NSExtensionActivationSupportsWebURLWithMaxCount
属性设置为1,该设置让扩展知道我们需要请求一个URL。
我们Action.js
文件中有如下内容:
var Action = function() {}; Action.prototype = { run: function(arguments) { // 在这个方法里,你可以通过document操作HTML中的元素,或者可以将HTML中的内容传给ActionRequestHandler文件的代码。 // 在本文的例子中,我们不做任何更新,只是将HTML中选中的内容穿给ActionRequestHandler文件的代码。 var selected = "No Text Selected"; if (window.getSelection) { selected = window.getSelection().getRangeAt(0).toString(); } else { selected = document.getSelection().getRangeAt(0).toString(); } arguments.completionFunction({"args" : selected}); }, finalize: function(arguments) { // 当ActionRequestHandler文件中的itemLoadCompletedWithPreprocessingResults方法执行完之后会调用该方法。 // 如果ActionRequestHandler文件向HTML返回了信息,我们可以通过arguments["message"]来查看,并且可以根据该信息操作HTML中的元素。 alert(arguments["message"]) }}; var ExtensionPreprocessingJS = new Action
Safari与Action扩展的交互就是通过Action.js
文件中的run
和finalize
这两个方法实现的。当我们在Safari中使用Action扩展时就会调用run
方法,它能让我们在该方法中操作当前Safari显示页面的DOM元素。当Action扩展处理完逻辑向Safari返回信息时会调用finalize
方法,在我们的例子中,我们通过self.extensionContext!.completeRequestReturningItems(nil, completionHandler: nil)
这段代码向Safari返回信息。该方法的第一个参数就是要返回的信息,它会将信息传给Action.js
文件,然后通过js代码操作HTML。如果第一个参数传入nil
,那就意味着不会调用Action.js
文件中的finalize
方法。run
和finalize
这两个方法的参数arguments
都包含着一些信息,只不过一个是来自与HTML,一个来自ActionRequestHandler
文件。
一定要记住:我们必须要实例化ExtensionPreprocessingJS
这个全局变量,因为它是Safari和Action扩展之间的桥梁。
我们的ActionRequestHandler
文件内容如下:
class ActionRequestHandler: NSObject, NSExtensionRequestHandling { var extensionContext: NSExtensionContext? func beginRequestWithExtensionContext(context: NSExtensionContext!) { self.extensionContext = context let identifierType = NSString(format: kUTTypePropertyList, NSUTF8StringEncoding) for (item: NSExtensionItem) in context.inputItems as [NSExtensionItem] { for (itemProvider: NSItemProvider) in item.attachments as [NSItemProvider] { if itemProvider.hasItemConformingToTypeIdentifier(identifierType) { itemProvider.loadItemForTypeIdentifier(identifierType, options: nil, completionHandler: {(item, error) in let dictionary = item as NSDictionary dispatch_async(dispatch_get_main_queue(), { self.itemLoadCompletedWithPreprocessingResults(dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as NSDictionary) }) }) } } } } func itemLoadCompletedWithPreprocessingResults(javaScriptPreprocessingResults: NSDictionary) { if let text = javaScriptPreprocessingResults["args"] as? String { let userDefaults = NSUserDefaults(suiteName: "group.name") userDefaults.setValue(text, forKey: "note") userDefaults.synchronize() self.doneWithResults(["message": "Successfully added to the note app"]) } } func doneWithResults(resultsForJavaScriptFinalizeArg: NSDictionary?) { if let resultsForJavaScriptFinalize = resultsForJavaScriptFinalizeArg { let identifierType = NSString(format: kUTTypePropertyList, NSUTF8StringEncoding) // 创建合适返回类型的标示符。 // 这里创建的resultsItem将作为Action.js文件中finalize方法的参数。 var resultsDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: resultsForJavaScriptFinalize] var resultsProvider = NSItemProvider(item: resultsDictionary, typeIdentifier: identifierType) var resultsItem = NSExtensionItem() resultsItem.attachments = [resultsProvider] // 这段代码意味着Action扩展已经处理完了逻辑,现在将信息返回给Action.js文件。 self.extensionContext!.completeRequestReturningItems([resultsItem], completionHandler: nil) } else { // 就算我们没有任何要返回的信息,也要执行这段代码,用于告知我们的Action扩展已经完成了逻辑处理。 self.extensionContext!.completeRequestReturningItems(nil, completionHandler: nil) } self.extensionContext = nil }}
现在我们可以运行一下我们的应用,然后打开Safari,在Action选项中开启我们的Action扩展:
然后我们就可以在Action栏中看到我们的扩展了:
我们使用Safari随便打开一个含有文字的页面,选中一段文字,然后打开Action栏,点击NoteApp扩展,此时我们的扩展就会将选中的这段文字发送给我们的应用,形成一条新的重要信息。
以上只是一个简单的Aciton扩展的例子,但我们可以由此延伸出更多有用、有创意的功能,让我们的生活更加美好。
本文例子的代码可以在这里下载:NoteApp
原文地址:Action Extension in Swift
- 如何在Swift中创建Action扩展
- 如何在Swift中创建Action扩展
- 如何在Swift中创建自定义控件
- 如何在Swift中创建和使用Model [ MagicalRecord ]
- 请问如何在扩展 DLL 中创建应用程序框架?如何在DLL中创建窗体(SDI/MDI)?非常急!!!!!!!
- 怎样在swift中创建一个CocoaPods
- 怎样在swift中创建CocoaPods
- 如何在action中访问servlet API
- 如何在 Swift 项目中使用 CocoaPods
- 如何在Swift中使用NSError
- 如何在Swift 中使用AFNetworking
- 如何在Swift中使用SELECTOR
- 如何在Swift中调用C函数
- 如何创建swift工程
- 如何在项目实践中扩展Struts
- 如何在项目实践中扩展Struts
- 在Eclipse中如何提供扩展点
- 如何在EDT中扩展UI控件
- Shiro相关知识点
- Tomcat内存溢出报java.lang.OutOfMemoryError: PermGen space错误的解决方案
- 洛谷 P3406 海底高铁
- Laravel 5 User Model not found
- 二叉树的三种遍历方式
- 如何在Swift中创建Action扩展
- 在活动中使用 Menu
- Rxjava(过滤类)-Skip
- 机器学习-线性回归
- [Web前端技术教学]CSS中可继承的属性以及无继承性的属性
- 搞懂JAVA集合类--HashMap(三)
- 雅虎团队经验:网站页面性能优化的 34条
- NSZone理解
- hdu 1978 How many ways 记忆化搜索