はじめに
iosのshare extension機能では、共有時にjavascriptファイルを実行してデフォルトでは取得できない様々な情報を取得し、アプリに保存することができます。
appleの公式ドキュメントにもその方法は書いてあるのですが、objective-Cのコードしか書かれておらず、ネット上にある情報も古いものが多かったので、最新の環境(Swift5・xcode11)で動作するコードをメモしておきます。
※share extensionの基本機能については実装済みと仮定します。
jsファイルをプロジェクトに追加
info.plistの編集
info.plistのNSExtensionActivationRuleと同じ階層にNSExtensionJavaScriptPreprocessingFileと JSファイル名を追加します。
jsファイルの編集
とりあえずページのURLとタイトルを取得してみます。なおfinalizeという関数はなくても動作しました(よくわかりません)。
GetData.js
var MyPreprocessor = function() {};
MyPreprocessor.prototype = {
run: function(arguments) {
arguments.completionFunction({"url": document.URL, "title": document.title});
},
finalize: function(arguments) {
}
};
var ExtensionPreprocessingJS = new MyPreprocessor;
ShareViewController.swiftの編集
ShareViewController.swift
override func isContentValid() -> Bool {
return true
}
override func didSelectPost() {
for item: Any in self.extensionContext!.inputItems {
let inputItem = item as! NSExtensionItem
for itemProvider : NSItemProvider in inputItem.attachments! {
if itemProvider.hasItemConformingToTypeIdentifier("public.data") {
itemProvider.loadItem(forTypeIdentifier: "public.data", options: nil, completionHandler: {
(item, error) in
if let dictionary = item as? NSDictionary {
DispatchQueue.main.async(execute: { () -> Void in
let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as! NSDictionary
print(results["url"])//取得したURL
print(results["title"])//取得したページのタイトル
//このデータをUserDefaultsやCoreDataでアプリと共有する
})
}
})
}
}
}
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
}
override func configurationItems() -> [Any]! {
return []
}
その他いろいろなデータの取得例
GetData.js
var MyPreprocessor = function() {};
MyPreprocessor.prototype = {
run: function(arguments) {
//現在のスクロール位置を取得
var positionTop = String(Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop));
//動画の現時点での再生時間を取得
var htmlVideoPlayer = document.getElementsByTagName('video')[0];
var currentTimeAtThisVideo = String(parseInt(htmlVideoPlayer.currentTime));
arguments.completionFunction({"positionTop": positionTop, "currentTimeAtThisVideo": currentTimeAtThisVideo});
},
finalize: function(arguments) {
}
};
var ExtensionPreprocessingJS = new MyPreprocessor;
おわりに
上記の方法を利用してShiori(webにしおりをはさめるアプリ)というアプリを開発しました。読んでいる最中の記事や、見ている最中の動画をそのままの状態で記録し、いつでも再開できるアプリです。ぜひご利用ください。