iOS AppExtension : How can I Combine NSExtensionActivationRule and NSPredicate
What I ended up doing is 1) allowing TRUEPREDICATE temporarily, and using some logic like this`
NSExtensionItem *item = extensionContext.inputItems.firstObject;
if ( item )
{
NSItemProvider *itemProvider = item.attachments.firstObject;
if ( itemProvider )
{
NSArray *registeredTypeIdentifiers = itemProvider.registeredTypeIdentifiers;
NSLog( @"registeredTypeIdentifiers: %@", registeredTypeIdentifiers );
}
}`
This will give you all the types of the document you want to share (example: "public.url"). Because of the multiple types, my predicate became a little complex:
SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
(
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.png"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg-2000"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.tiff"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.compuserve.gif"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.bmp"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.word.doc"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "org.openxmlformats.wordprocessingml.document"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.comma-separated-values-text"
)
AND
(
NOT ( ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.photoshop-image" )
)
).@count == $extensionItem.attachments.@count
).@count == 1
This basically looks for any file type for image (other than adobe psd), pdf, txt, csv or doc/docx.
It also only allows 1 document to be shared at a time.
It looks like kUTTypeImage includes PSD - hence my blocking of that format ( "com.adobe.photoshop-image" ).
NSExtensionActivationRule for iOS app extension that can share everything
Try this post iOS AppExtension : How can I Combine NSExtensionActivationRule and NSPredicate
Combining Subquery with keys to a UTI NSExtensionActivationRule:
- NSExtensionActivationSupportsFileWithMaxCount to "public.file-url"
- NSExtensionActivationSupportsMovieWithMaxCount to "public.movie"
- NSExtensionActivationSupportsText to "public.text"
- NSExtensionActivationSupportsWebURLWithMaxCount to "public.url"
How do I set NSExtensionActivationRule predicates?
This is how it should look like and works fine for me, just try:
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
(
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.png"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg-2000"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.compuserve.gif"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.bmp"
)
).@count == 1
).@count == 1
</string>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.ui-services</string>
</dict>
How to have a share extension to show up for multiple photos
NSExtensionActivationRule as dictionary works fine.
The issues was not plist itself but xcode.
Somehow the change from 1 to 256 was not picked up.
This is not an ios issue. This seems to be an xcode[8.2.1]
dependencies issue.
IOS Share extension: how to read from notes posts
At least in iOS 9, the correct code is
<dict>
<key>NSExtensionActivationSupportsText</key>
<true/>
</dict>
For reference, this is typically what it would like for text share extension support:
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationUsesStrictMatching</key>
<integer>2</integer>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationDictionaryVersion</key>
<integer>2</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
</dict>
</dict>
Action Extension activation rule predicate doesn't hide the action when multiple of the same type is selected
From debugging the code, it seems like it is a single extension item with a bunch of attachments. So to support only a single attachment you would to do the following:
Replace $extensionItem.attachments.@count with 1.
This should hide your extension if you are selecting more than 1 GIF file.
Share attachment from Mail App with Share extension in iOS
So finally I found an answer on my question! Just in case if somebody will meet the same problem..
First of all I have to use PREDICATE statement (Subquery) in Info.plist instead of key NSExtensionActivationSupportsAttachmentsWithMaxCount. Like:
<key>NSExtensionActivationRule</key>
<string>SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
(
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.png"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.jpeg-2000"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.tiff"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.compuserve.gif"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.bmp"
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.microsoft.word.doc"
)
).@count == 1 // Important! to activate extension only on 1 chosen image
).@count == 1
</string>
Second: Properly get all attachments using necessary TypeIdentifier (UTI):
if let content = extensionContext!.inputItems.first as? NSExtensionItem {
if let contents = content.attachments as? [NSItemProvider] {
for attachment in contents{
attachment.loadItemForTypeIdentifier("public.item", options: nil) { data, error in
let url = data as! NSURL
let fileExtension = url.pathExtension as String!
let fileName = self.generateImageName() as String
if let fileData = NSData(contentsOfURL: url) {
self.uploadFile("\(fileName).\(fileExtension)", data: fileData)
}
}
}
}
}
"public.item" - is universal UTI to support all kind of file extensions listed in your NSExtensionActivationRule string.
You can get necessary UTI on https://developer.apple.com
Good Luck with developing of action extensions! Any questions are welcome!
Sharing Extension in IOS8 beta
Below is how you can get the url. Notice the type identifier is kUTTypeURL and the block argument is NSURL. Also, the plist needs to be correct like mine also. The documentation was lacking and got help from number4 on the Apple dev forums. (you'll need to be registered and logged in to see it).
Code:
NSExtensionItem *item = self.extensionContext.inputItems.firstObject;
NSItemProvider *itemProvider = item.attachments.firstObject;
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeURL]) {
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeURL options:nil completionHandler:^(NSURL *url, NSError *error) {
self.urlString = url.absoluteString;
}];
}
Info.plist
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionPointName</key>
<string>com.apple.share-services</string>
<key>NSExtensionPointVersion</key>
<string>1.0</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
</dict>
Related Topics
Cannot Invoke 'Indexof' with an Argument List of Type '(Checklistitem)'
Offline Crash Reporting in Crashlytics
How to Hide a Bar Button Item for Certain Users
iOS 13 Set Uisearchtextfield Placeholder Color
Get the Expiration Date of a Provisioning Profile at Run-Time
Build Information in iOS Application (Date/Time App Was Built)
Does Swift Not Work with Function Pointers
Get Created Date and Last Login Date from Firuser with Firebase 3
How to Remove Black Edge on Uiimageview with Rounded Corners and a Border Width
What Is Difference Between Self.Timer = Nil VS [Self.Timer Invalidate] in iOS
How to Make a Conical Gradient in iOS Using Core Graphics/Quartz 2D
Parsing JSON Using the New Swift 3 and Alamofire
Admob 7.3.1 and Swift 2.0 - Module Not Found
Autolayout Ignores Multi-Line Detailtextlabel When Calculating Uitableviewcell Height (All Styles)