HOME > App Extensions #5
前回の記事はTodayを説明していましたが、今回はActionsの実装方法を解説してみます。まずはActionsが どこのことを指すのか?Safariでメール送信時になんかにでてくる下からビョーンの以下の画像の箇所になります。(actionというアプリを追加した状態。アイコン無し)
参考:【iOS8】App Extension の実装方法 その1:ActionAdd Starkoogawasawat
ShareやTodayと同じように、New->TargetからAppExtensionのActionsを選択します。
プロジェクトに[action]フォルダが生成されます
shareフォルダの中には、以下3つのファイルが含まれています
AppExtensionsはShareやTodayと同様追加時にはこの三つのファイルが含まれているようです。この状態ですでにSafariには追加されている状態です。 SafariのURL取得等はShareと同じですので、こちらの記事(AppExtension(share))等を確認してください。
自作していたアプリのアイコンが設置できずにハマったので共有します。
iOS 8 action extension icon is blank on device (works in simulator)
どうやらBuild PhasesのCopy Bundle ResourceにアイコンセットのImages.xcassetsを含めないといけないようでした。
ActionではページのURLは簡単にとれたのですが、タイトルが取るのが面倒くさかったので共有です
タイトルやHTMLソースは少しトリッキーな方法で取得する必要があります。JavascriptをActionプロジェクトに 埋め込む形でタイトル等を取得するなんだか荒技のような変化球が必要です。
jsファイルを作成してプロジェクトに追加、info.plistにファイル名追加、ソースを調整、の3ステップで取得できます。
var MyPreprocessor = function() {};
MyPreprocessor.prototype = {
run: function(arguments) {
arguments.completionFunction({"url": document.URL, "title": document.title});
//arguments.completionFunction({"URL": document.URL, "pageSource": document.documentElement.outerHTML, "title": document.title, "selection": window.getSelection().toString()});
}
};
var ExtensionPreprocessingJS = new MyPreprocessor;
プロジェクトに実装するJavascriptを追加します。上記はDemoPreprocessor.jsです。これは任意の名称でOK。
info.plistのNSExtensionActivationRuleと同じ階層にNSExtensionJavaScriptPreprocessingFileと JSファイル名を追加します。
import UIKit
import MobileCoreServices
class ActionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
for item: AnyObject in self.extensionContext!.inputItems {
let inputItem = item as NSExtensionItem
for provider : AnyObject in inputItem.attachments! {
let itemProvider = provider as NSItemProvider
itemProvider.loadItemForTypeIdentifier(kUTTypePropertyList, options: nil) {
(decoder: NSSecureCoding!, error: NSError!) -> Void in
if let dictionary = decoder as? NSDictionary {
dispatch_async(dispatch_get_main_queue(), {
let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as NSDictionary
println(results["url"]);
println(results["title"]);
})
}
}
}
}
}
override func viewWillAppear(animated: Bool) {
// Get the item[s] we're handling from the extension context.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
JSを埋め込んでいるだけで勝手に実行してNSExtensionJavaScriptPreprocessingResultsKeyに結果を格納してくれています。 ここからURLやTitle、HTMLソース等を取得することが可能です!面倒くさい、、、、(※上記処理はXCode6.3だとエラー。対応は下に記載しています)
上記DemoPreprocessor.jsを改造してサイトのfaviconを取得するサンプルです。
var MyPreprocessor = function() {};
MyPreprocessor.prototype = {
run: function(arguments) {
//favicon検索。vに格納されます
var f=document.evaluate('//link[(@rel=\'icon\') or (@rel=\'shortcut icon\') or (@rel=\'ICON\') or (@rel=\'SHORTCUT ICON\')][1]/@href',document,null,XPathResult.STRING_TYPE,null);
var u=f.stringValue;
var v=(u=='')?'http://'+location.host+'/favicon.ico':(u.substring(0,7)!='http://')?'http://'+location.host+u:u;
arguments.completionFunction({"url": document.URL, "title": document.title, "favicon": v});
}
};
var ExtensionPreprocessingJS = new MyPreprocessor;
WatchKitアプリ作成、4月24日までにどうにかしてと開発している中、XCodeの最新6.3が!勢いあまってアップデートすると大漁のエラー。おーい、、、、時間あんまりないんですけど。。。 しかしSwiftのパフォーマンスも向上しているとのことですのでトライです。一部動作しなくなっていた処理があったのでここで共有しておきます。今までAppEtensionsのitemprovider.loadItemForTypeIdentifierが 動作していましたが関数に変更があり以下に修正しました。
import UIKit
import MobileCoreServices
class ActionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
for item: AnyObject in self.extensionContext!.inputItems {
let inputItem = item as NSExtensionItem
for provider : AnyObject in inputItem.attachments! {
let itemProvider = provider as NSItemProvider
//itemProvider.loadItemForTypeIdentifier(kUTTypePropertyList, options: nil) {
itemProvider.loadItemForTypeIdentifier("public.data", options: nil) {
(decoder: NSSecureCoding!, error: NSError!) -> Void in
if let dictionary = decoder as? NSDictionary {
dispatch_async(dispatch_get_main_queue(), {
let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as NSDictionary
println(results["url"]);
println(results["title"]);
})
}
}
}
}
}
override func viewWillAppear(animated: Bool) {
// Get the item[s] we're handling from the extension context.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
ここを参考にしました
前の記事はこちら:App Extensions #4(Today)。よかったらご確認下さい!
以下でハマったのでメモです。
参考:今更ですが iOS8 で実装された Share Extension を美味しくいただきました
for item: Any in self.extensionContext!.inputItems {
let inputItem = item as! NSExtensionItem
if let attachments = inputItem.attachments as? [NSItemProvider] {
for itemProvider : NSItemProvider in attachments {
if itemProvider.hasItemConformingToTypeIdentifier("public.data") {
itemProvider.loadItem(forTypeIdentifier: "public.data", options: nil, completionHandler: {
(item, error) in
})
}
}
}
2021-05-14 14:21:41 | WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。
AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、
昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は... |
2021-05-06 14:04:37 | LINEのアニメーションスタンプ制作の落とし穴、、、失敗談
ゴールデンウィークにLINEスタンプを作成してみました。
作り切って申請も通したんですが、意図したアニメーションと違う、、、、
LINEクリエーターの画面だと、アニメーションのプレビュー... |
2021-05-01 18:05:35 | 久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。
忘れないようにメモ
エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。
ターゲット→ex... |
Tweet | |||
|