그냥 제목이 구미가 당겨서 따라해봤다.
이런 Share Extension에 JavaScript code를 주입한 Extension을 만들어 보겠다는 것이다.
Supporting Suggestions in Your App’s Share Extension
-> apple.Article
NS Extension Item 이란?
-> NSExtensionItem - Apple.docs
- NSExtensionItem을 사용
- NSExtensionItem에서 JavaScript Code를 사용할 수 있다.
NSExtensionItem
추가 하는 법File
⌊ New
⌊ Target
생성!
override func viewDidLoad() {
super.viewDidLoad()
if let inputItem = extensionContext?.inputItems.first as? NSExtensionItem {
if let itemProvider = inputItem.attachments?.first {
itemProvider.loadItem(forTypeIdentifier: kUTTypePropertyList as String) { [weak self] (dict, error) in
// do stuff!
}
}
}
}
Info.plist
⌊ NSExtensionAttributes
⌊ Add NSExtensionJavaScriptPreprocessingFile
: “Action
"
⌊ NSExtensionActivationRule
(→ Dictionary)
⌊ Add NSExtensionActivationSupportsWebPageWithMaxCount
: “1
"
var Action = function() {};
Action.prototype = {
run: function(parameters) {
},
finalize: function(parameters) {
}
};
var ExtensionPreprocessingJS = new Action
잘 생성됐는지 확인!
run: function(parameters) {
parameters.completionFunction({"URL": document.URL, "title": document.title });
},
Run! 클릭
Apple site 접속 → 내보내기(?) 버튼 터치
Extension 클릭
Console 창에 URL과 title이 잘 찍힌다.
NavigationViewController 의 Root View Controller 를 ActionViewController로 해주고,
아래와 같이 구성한다.
@IBOutlet weak var script: UITextView!
var pageTitle = ""
var pageURL = ""
override func viewDidLoad() {
super.viewDidLoad()
if let inputItem = extensionContext?.inputItems.first as? NSExtensionItem {
if let itemProvider = inputItem.attachments?.first {
itemProvider.loadItem(forTypeIdentifier: kUTTypePropertyList as String) { [weak self] (dict, error) in
guard let itemDictionary = dict as? NSDictionary else { return }
guard let javaScriptValues = itemDictionary[NSExtensionJavaScriptPreprocessingResultsKey] as? NSDictionary else { return }
self?.pageTitle = javaScriptValues["title"] as? String ?? ""
self?.pageURL = javaScriptValues["URL"] as? String ?? ""
DispatchQueue.main.async {
//page title
self?.title = self?.pageTitle
}
}
}
}
}
self?.title = self?.pageTitle
코드처럼 title 설정이 잘 됐다.
@IBAction func done() {
// Return any edited content to the host app.
// This template doesn't do anything, so we just echo the passed in items.
let item = NSExtensionItem()
let argument: NSDictionary = ["customJavaScript": script.text]
let webDictionary: NSDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: argument]
let customJavaScript = NSItemProvider(item: webDictionary, typeIdentifier: kUTTypePropertyList as String)
item.attachments = [customJavaScript]
extensionContext?.completeRequest(returningItems: [item])
}
finalize: function(parameters) {
var customJavaScript = parameters["customJavaScript"];
eval(customJavaScript);
}
That's all the code required to send data back to Safari, at which point it will appear inside the finalize()
function in Action.js. From there we can do what we like with it, but in this project the JavaScript we need to write is remarkably simple: we pull the "customJavaScript" value out of the parameters
array, then pass it to the JavaScript eval()
function, which executes any code it finds.
Tada👍