Even people far smarter than I am find the syntax for NSExtensionActivationRule
arcane, but even a fool like me should be able to copy/paste examples, no? Unfortunately I can't even get Apple's examples to work. The host app for my action extension crashes when you hit the share sheet button (stack trace below).
You should be able to just set NSExtensionActivationRule
as a string, right? It works fine when I set it to TRUEPREDICATE
for debugging purposes. But if I take this simple example from Apple (slightly modified for public.image
) and paste it in, I get a crash:
{extensionItems = ({
attachments = ({
registeredTypeIdentifiers = (
"public.image"
);
});
})}
I've tried the SUBQUERY
thing too:
SUBQUERY($extensionItem.attachments, $attachment,
ANY $attachment.registeredTypeIdentifiers
UTI-CONFORMS-TO "public.image").@count >= 1
Ideally I'd like to avoid this altogether by just using NSExtensionActivationSupportsImageWithMaxCount
but as this person found, it doesn't seem to get activated for jpgs.
Anyway, that stack trace as promised:
2015-02-21 23:28:08.644 MobileSlideShow[56997:2414043] Communications error: <OS_xpc_error: <error: 0x4c985f4> { count = 1, contents =
"XPCErrorDescription" => <string: 0x4c9883c> { length = 22, contents = "Connection interrupted" }
}>
2015-02-21 23:28:08.651 MobileSlideShow[56997:2413473] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray removeObjectsAtIndexes:]: index set cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x04060686 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x03b35a97 objc_exception_throw + 44
2 CoreFoundation 0x03f84ffe -[NSMutableArray removeObjectsAtIndexes:] + 654
3 UIKit 0x01d71d78 _UIApplicationExtensionDiscoveryGetPostprocessedExtensions + 350
4 UIKit 0x01d718e3 -[_UIActivityApplicationExtensionDiscovery activitiesMatchingInputItems:error:updateBlock:] + 1237
5 UIKit 0x01c342f2 -[UIActivityViewController _availableActivitiesForItems:applicationExtensionActivities:] + 594
6 UIKit 0x01c3409b -[UIActivityViewController _availableActivitiesForItems:] + 48
7 UIKit 0x01c3519a -[UIActivityViewController _availableActivities] + 57
8 UIKit 0x01c39552 -[UIActivityViewController activityGroupViewController:availableActivitiesInCategory:] + 65
9 UIKit 0x0195c47f -[UIActivityGroupViewController collectionView:didSelectItemAtIndexPath:] + 251
10 UIKit 0x01b8d94d -[UICollectionView _selectItemAtIndexPath:animated:scrollPosition:notifyDelegate:] + 591
11 UIKit 0x01baced4 -[UICollectionView _userSelectItemAtIndexPath:] + 191
12 UIKit 0x01bad0c8 -[UICollectionView touchesEnded:withEvent:] + 492
13 libobjc.A.dylib 0x03b4b7cd -[NSObject performSelector:withObject:withObject:] + 84
14 UIKit 0x0164f714 forwardTouchMethod + 270
15 UIKit 0x0164f784 -[UIResponder touchesEnded:withEvent:] + 31
16 libobjc.A.dylib 0x03b4b7cd -[NSObject performSelector:withObject:withObject:] + 84
17 UIKit 0x0164f714 forwardTouchMethod + 270
18 UIKit 0x0164f784 -[UIResponder touchesEnded:withEvent:] + 31
19 UIKit 0x014e714a -[UIWindow _sendTouchesForEvent:] + 874
20 UIKit 0x014e7c24 -[UIWindow sendEvent:] + 790
21 UIKit 0x014a5d81 -[UIApplication sendEvent:] + 242
22 UIKit 0x014b613b _UIApplicationHandleEventFromQueueEvent + 21263
23 UIKit 0x01489599 _UIApplicationHandleEventQueue + 2206
24 CoreFoundation 0x03f820ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
25 CoreFoundation 0x03f77c0d __CFRunLoopDoSources0 + 253
26 CoreFoundation 0x03f77168 __CFRunLoopRun + 952
27 CoreFoundation 0x03f76aeb CFRunLoopRunSpecific + 443
28 CoreFoundation 0x03f7691b CFRunLoopRunInMode + 123
29 GraphicsServices 0x0089e2c9 GSEventRunModal + 192
30 GraphicsServices 0x0089e106 GSEventRun + 104
31 UIKit 0x0148d366 UIApplicationMain + 1526
32 MobileSlideShow 0x00092724 MobileSlideShow + 63268
33 libdyld.dylib 0x049dcac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Predicates move the conditions (sometimes business logic) to a central place. This helps in unit-testing them separately. Any code change need not be duplicated into multiple places thus predicates improve the code maintenance. The names predicates such as “ isAdultFemale () ” are much more readable than writing a if-else block.
static Predicate isEqual (Object targetRef) Returns a predicate that tests if two arguments are equal according to Objects.equals (Object, Object).
Java 8 Predicates Usage. In Java 8, Predicate is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
For example, we can use predicates in these real-life usecases: and so on… 1.2. Using Predicate with Stream As we know, Predicate is a functional interface that means we can pass it in lambda expressions wherever a predicate is expected. For example, one such method is filter () method from Stream interface.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With