Last active
November 16, 2023 18:37
-
-
Save 0xilis/4fdf458b917327e6eab9382247c3771b to your computer and use it in GitHub Desktop.
Import Unsigned Shortcuts on iOS 15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Snoolie K | |
* 16 November 2023 (EST) | |
* Import Unsigned Shortcuts Example | |
*/ | |
#import <UIKit/UIKit.h> | |
@interface WFFileRepresentation : NSObject | |
@property (readonly, nonatomic) NSData *data; // ivar: _data | |
@end | |
@interface WFWorkflowFileDescriptor : NSObject | |
@property (readonly, nonatomic) WFFileRepresentation *file; | |
-(id)initWithFile:(id)file name:(id)name; | |
@end | |
@interface WFWorkflowFile : NSObject | |
-(id)recordRepresentationWithError:(NSError*)err; | |
-(id)initWithDescriptor:(id)fileDesc error:(NSError*)err; | |
-(id)initWithFileData:(id)fileData name:(id)name error:(NSError*)err; | |
@end | |
@interface WFDatabase : NSObject | |
+(id)defaultDatabase; | |
@end | |
@interface WFDatabaseProxy : NSObject | |
-(void)createWorkflowWithWorkflowRecord:(id)workflowRecord nameCollisionBehavior:(int)nameCollisionBehavior error:(NSError*)err; | |
-(id)initWithDatabase:(id)database; | |
@end | |
@interface WFShortcutExtractor : NSObject | |
@property (readonly, nonatomic) WFFileRepresentation *extractingFile; | |
-(void)extractShortcutWithCompletion:(id)completion; | |
-(id)initWithURL:(NSURL *)url allowsOldFormatFile:(BOOL)allowOldFileFormat suggestedName:(NSString *)suggestName sourceApplication:(NSString *)app; | |
@end | |
#define UNSIGNED_SHORTCUT_PATH "/Users/0xilis/Downloads/0/GitGub/WorkflowKit-Ent-Testing/unsignedShortcut.shortcut" | |
/* Notice: recordRepresentationWithError: method requires com.apple.developer.icloud-services entitlement to list CloudKit. WFDatabase/WFDatabaseProxy may also require entitlements, I'm not sure :P */ | |
int main(void) { | |
/* load WorkflowKit framework */ | |
NSBundle *container = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/WorkflowKit.framework"]; | |
if ([container load]) { | |
/* get classes */ | |
Class WFWorkflowFileDescriptorClass = objc_getClass("WFWorkflowFileDescriptor"); | |
Class WFWorkflowFileClass = objc_getClass("WFWorkflowFile"); | |
Class WFDatabaseClass = objc_getClass("WFDatabase"); | |
Class WFDatabaseProxyClass = objc_getClass("WFDatabaseProxy"); | |
Class WFShortcutExtractorClass = objc_getClass("WFShortcutExtractor"); | |
/* get WFWorkflowRecord from file */ | |
WFShortcutExtractor* shortcutExtractor = [[WFShortcutExtractorClass alloc]initWithURL:[NSURL fileURLWithPath:@UNSIGNED_SHORTCUT_PATH] allowsOldFormatFile:YES suggestedName:@"suggestedName" sourceApplication:nil]; | |
/* this doesn't actually call the completion method like it should for some reason but its fine since afterward we should have extractingFile */ | |
[shortcutExtractor extractShortcutWithCompletion:^(id arg0, id arg1){ | |
NSLog(@"we here"); | |
NSLog(@"arg0: %@",arg0); | |
NSLog(@"arg1: %@",arg1); | |
}]; | |
WFFileRepresentation *fileRep = [shortcutExtractor extractingFile]; | |
WFWorkflowFileDescriptor *fileDesc = [[WFWorkflowFileDescriptorClass alloc] initWithFile:fileRep name:@"SnoolieShortcut"]; | |
WFWorkflowFile *wFile = [[WFWorkflowFileClass alloc] initWithDescriptor:fileDesc error:nil]; | |
WFWorkflowRecord *workflowRecord = [wFile recordRepresentationWithError:nil]; /* requires cloudkit entitlement */ | |
/* now actually add shortcut to database */ | |
WFDatabaseProxy *databaseProxy = [[WFDatabaseProxyClass alloc]initWithDatabase:[WFDatabaseClass defaultDatabase]]; | |
[databaseProxy createWorkflowWithWorkflowRecord:workflowRecord nameCollisionBehavior:0x0 error:nil]; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment