Skip to content

Commit

Permalink
Add code to create new notes from the share extension
Browse files Browse the repository at this point in the history
  • Loading branch information
atomicbird committed Nov 14, 2014
1 parent e9a638c commit c7a7a85
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 2 deletions.
31 changes: 31 additions & 0 deletions DemoNotes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
EE9A19D81A16898800CBD6AD /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9A19D71A16898800CBD6AD /* ShareViewController.m */; };
EE9A19DA1A16898800CBD6AD /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EE9A19D91A16898800CBD6AD /* MainInterface.storyboard */; };
EE9A19DD1A16898800CBD6AD /* Share to Note.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = EE9A19D21A16898800CBD6AD /* Share to Note.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
EE9A19E21A168BFD00CBD6AD /* DemoPreprocessor.js in Resources */ = {isa = PBXBuildFile; fileRef = EE9A19E11A168BFD00CBD6AD /* DemoPreprocessor.js */; };
EE9A19E41A168EEA00CBD6AD /* DemoSharedCode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEDE71E71A156423007CD3D8 /* DemoSharedCode.framework */; };
EEDE71A21A141B9A007CD3D8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDE71A11A141B9A007CD3D8 /* main.m */; };
EEDE71A51A141B9A007CD3D8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDE71A41A141B9A007CD3D8 /* AppDelegate.m */; };
EEDE71A81A141B9A007CD3D8 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDE71A71A141B9A007CD3D8 /* MasterViewController.m */; };
Expand Down Expand Up @@ -40,6 +42,13 @@
remoteGlobalIDString = EE9A19D11A16898800CBD6AD;
remoteInfo = "Share to Note";
};
EE9A19E51A168EF900CBD6AD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = EEDE71941A141B9A007CD3D8 /* Project object */;
proxyType = 1;
remoteGlobalIDString = EEDE71E61A156423007CD3D8;
remoteInfo = DemoSharedCode;
};
EEDE71B91A141B9A007CD3D8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = EEDE71941A141B9A007CD3D8 /* Project object */;
Expand Down Expand Up @@ -116,6 +125,8 @@
EE9A19D61A16898800CBD6AD /* ShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareViewController.h; sourceTree = "<group>"; };
EE9A19D71A16898800CBD6AD /* ShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareViewController.m; sourceTree = "<group>"; };
EE9A19D91A16898800CBD6AD /* MainInterface.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MainInterface.storyboard; sourceTree = "<group>"; };
EE9A19E11A168BFD00CBD6AD /* DemoPreprocessor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = DemoPreprocessor.js; sourceTree = "<group>"; };
EE9A19E31A168C0D00CBD6AD /* Share to Note.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Share to Note.entitlements"; sourceTree = "<group>"; };
EEDE719C1A141B9A007CD3D8 /* DemoNotes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoNotes.app; sourceTree = BUILT_PRODUCTS_DIR; };
EEDE71A01A141B9A007CD3D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
EEDE71A11A141B9A007CD3D8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -154,6 +165,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
EE9A19E41A168EEA00CBD6AD /* DemoSharedCode.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -202,6 +214,8 @@
EE9A19D31A16898800CBD6AD /* Share to Note */ = {
isa = PBXGroup;
children = (
EE9A19E31A168C0D00CBD6AD /* Share to Note.entitlements */,
EE9A19E11A168BFD00CBD6AD /* DemoPreprocessor.js */,
EE9A19D61A16898800CBD6AD /* ShareViewController.h */,
EE9A19D71A16898800CBD6AD /* ShareViewController.m */,
EE9A19D91A16898800CBD6AD /* MainInterface.storyboard */,
Expand Down Expand Up @@ -379,6 +393,7 @@
buildRules = (
);
dependencies = (
EE9A19E61A168EF900CBD6AD /* PBXTargetDependency */,
);
name = "Share to Note";
productName = "Share to Note";
Expand Down Expand Up @@ -492,6 +507,11 @@
EE9A19D11A16898800CBD6AD = {
CreatedOnToolsVersion = 6.1;
DevelopmentTeam = FZTVR399HK;
SystemCapabilities = {
com.apple.ApplicationGroups.iOS = {
enabled = 1;
};
};
};
EEDE719B1A141B9A007CD3D8 = {
CreatedOnToolsVersion = 6.1;
Expand Down Expand Up @@ -552,6 +572,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
EE9A19E21A168BFD00CBD6AD /* DemoPreprocessor.js in Resources */,
EE9A19DA1A16898800CBD6AD /* MainInterface.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -657,6 +678,11 @@
target = EE9A19D11A16898800CBD6AD /* Share to Note */;
targetProxy = EE9A19DB1A16898800CBD6AD /* PBXContainerItemProxy */;
};
EE9A19E61A168EF900CBD6AD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = EEDE71E61A156423007CD3D8 /* DemoSharedCode */;
targetProxy = EE9A19E51A168EF900CBD6AD /* PBXContainerItemProxy */;
};
EEDE71BA1A141B9A007CD3D8 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = EEDE719B1A141B9A007CD3D8 /* DemoNotes */;
Expand Down Expand Up @@ -712,6 +738,7 @@
EE9A19DF1A16898800CBD6AD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Share to Note/Share to Note.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PREPROCESSOR_DEFINITIONS = (
Expand All @@ -721,18 +748,21 @@
INFOPLIST_FILE = "Share to Note/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
EE9A19E01A16898800CBD6AD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Share to Note/Share to Note.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
INFOPLIST_FILE = "Share to Note/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
SKIP_INSTALL = YES;
};
name = Release;
Expand Down Expand Up @@ -993,6 +1023,7 @@
EE9A19E01A16898800CBD6AD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
EEDE71971A141B9A007CD3D8 /* Build configuration list for PBXProject "DemoNotes" */ = {
isa = XCConfigurationList;
Expand Down
9 changes: 9 additions & 0 deletions Share to Note/DemoPreprocessor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var MyPreprocessor = function() {};

MyPreprocessor.prototype = {
run: function(arguments) {
arguments.completionFunction({"URL": document.URL, "pageSource": document.documentElement.outerHTML, "title": document.title, "selection": window.getSelection().toString()});
}
};

var ExtensionPreprocessingJS = new MyPreprocessor;
11 changes: 10 additions & 1 deletion Share to Note/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>TRUEPREDICATE</string>
<dict>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionJavaScriptPreprocessingFile</key>
<string>DemoPreprocessor</string>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
Expand Down
10 changes: 10 additions & 0 deletions Share to Note/Share to Note.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.atomicbird.demonotes</string>
</array>
</dict>
</plist>
62 changes: 61 additions & 1 deletion Share to Note/ShareViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
//

#import "ShareViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <DemoSharedCode/DemoSharedCode.h>

NSString *const kDemoNoteFilename = @"notes.bin";

@interface ShareViewController ()

Expand All @@ -19,9 +23,65 @@ - (BOOL)isContentValid {
return YES;
}

- (void)viewDidLoad
{
[super viewDidLoad];

for (NSExtensionItem *item in self.extensionContext.inputItems) {
for (NSItemProvider *itemProvider in item.attachments) {
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypePropertyList]) {
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(NSDictionary *jsDict, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *jsPreprocessingResults = jsDict[NSExtensionJavaScriptPreprocessingResultsKey];
NSString *selectedText = jsPreprocessingResults[@"selection"];
NSString *pageTitle = jsPreprocessingResults[@"title"];
if ([selectedText length] > 0) {
self.textView.text = selectedText;
} else if ([pageTitle length] > 0) {
self.textView.text = pageTitle;
}
});
}];

break;
}
}

}

}

- (NSURL *)demoNoteFileURL
{
NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.atomicbird.demonotes"];
NSURL *fileURL = [groupURL URLByAppendingPathComponent:kDemoNoteFilename];
return fileURL;
}

- (void)didSelectPost {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
// Load existing notes
NSMutableArray *objects;

NSData *savedData = [NSData dataWithContentsOfURL:[self demoNoteFileURL]];
if (savedData != nil) {
NSArray *savedObjects = [NSKeyedUnarchiver unarchiveObjectWithData:savedData];
if (savedObjects != nil) {
objects = [savedObjects mutableCopy];
}
}

if (objects == nil) {
objects = [NSMutableArray array];
}

// Create a new note with the current text
DemoNote *newNote = [[DemoNote alloc] initWithText:self.textView.text];
[objects insertObject:newNote atIndex:0];

// Save notes back to the file
NSData *saveData = [NSKeyedArchiver archivedDataWithRootObject:objects];
[saveData writeToURL:[self demoNoteFileURL] atomically:YES];

// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
}
Expand Down

0 comments on commit c7a7a85

Please sign in to comment.