mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-11 18:24:43 +02:00
iOS: Add share extension (#4492)
This commit is contained in:
parent
e95ea48ce9
commit
da8cc73df6
@ -11,13 +11,42 @@
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
46E31F54C547C341F605BB66 /* libPods-Joplin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */; };
|
||||
5E556FC75AECECB13464A724 /* libPods-ShareExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC957496DFD2368FFE3C360 /* libPods-ShareExtension.a */; };
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||
AE152142260F770400217DCB /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AE152141260F770400217DCB /* ShareViewController.m */; };
|
||||
AE82E4AF2599FA3A0013551B /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AE82E4AD2599FA3A0013551B /* MainInterface.storyboard */; };
|
||||
AE82E4B32599FA3A0013551B /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = AE82E4A82599FA3A0013551B /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
AE82E4B12599FA3A0013551B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = AE82E4A72599FA3A0013551B;
|
||||
remoteInfo = ShareExtension;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
AE82E4B42599FA3A0013551B /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
AE82E4B32599FA3A0013551B /* ShareExtension.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* JoplinTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JoplinTests.m; sourceTree = "<group>"; };
|
||||
0473A2D469A3555053E69327 /* Pods-ShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.release.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
09056573D4C040FBD5FEB93A /* Pods-Joplin-JoplinTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-JoplinTests.debug.xcconfig"; path = "Target Support Files/Pods-Joplin-JoplinTests/Pods-Joplin-JoplinTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* Joplin.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Joplin.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Joplin/AppDelegate.h; sourceTree = "<group>"; };
|
||||
@ -32,13 +61,22 @@
|
||||
2DA44D9A347489A29B995F73 /* Pods-Joplin-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOSTests/Pods-Joplin-tvOSTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
37DBC181C4AD99CBE0D07EEB /* Pods-Joplin-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOSTests/Pods-Joplin-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
505CB61090817F4453631957 /* Pods-Joplin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin.debug.xcconfig"; path = "Target Support Files/Pods-Joplin/Pods-Joplin.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
5DE39012F71F18423C665C57 /* Pods-ShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.debug.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = Joplin/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
A3FEB746EE7F1B0FF28528E1 /* Pods-Joplin-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Joplin-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Joplin-tvOS/Pods-Joplin-tvOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
AE152140260F770400217DCB /* ShareViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ShareViewController.h; path = Source/ShareExtension/ShareViewController.h; sourceTree = "<group>"; };
|
||||
AE152141260F770400217DCB /* ShareViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ShareViewController.m; path = Source/ShareExtension/ShareViewController.m; sourceTree = "<group>"; };
|
||||
AE7945DB259C9A2500051BE2 /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = "<group>"; };
|
||||
AE7945E6259C9AEE00051BE2 /* Joplin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Joplin.entitlements; path = Joplin/Joplin.entitlements; sourceTree = "<group>"; };
|
||||
AE82E4A82599FA3A0013551B /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
AE82E4AE2599FA3A0013551B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
AE82E4B02599FA3A0013551B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
B61798F36B3BC123BF8EA4D9 /* libPods-Joplin-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||
F69B873C692CE22F1C4C9264 /* libPods-Joplin-JoplinTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Joplin-JoplinTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FAC957496DFD2368FFE3C360 /* libPods-ShareExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ShareExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -50,6 +88,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
AE82E4A52599FA3A0013551B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5E556FC75AECECB13464A724 /* libPods-ShareExtension.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@ -73,6 +119,7 @@
|
||||
13B07FAE1A68108700A75B9A /* Joplin */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AE7945E6259C9AEE00051BE2 /* Joplin.entitlements */,
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
@ -93,6 +140,7 @@
|
||||
258F823D616BE3D6A52BC900 /* libPods-Joplin-tvOSTests.a */,
|
||||
A5E1CD825FABD6C4E704EA54 /* libPods-Joplin.a */,
|
||||
F69B873C692CE22F1C4C9264 /* libPods-Joplin-JoplinTests.a */,
|
||||
FAC957496DFD2368FFE3C360 /* libPods-ShareExtension.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -110,6 +158,7 @@
|
||||
13B07FAE1A68108700A75B9A /* Joplin */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
00E356EF1AD99517003FC87E /* JoplinTests */,
|
||||
AE82E4A92599FA3A0013551B /* ShareExtension */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
9CDB1D9DB6483D893504BFCB /* Pods */,
|
||||
@ -123,6 +172,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* Joplin.app */,
|
||||
AE82E4A82599FA3A0013551B /* ShareExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -138,10 +188,24 @@
|
||||
245A6EBAE2E874DB706B16DB /* Pods-Joplin-tvOS.release.xcconfig */,
|
||||
2DA44D9A347489A29B995F73 /* Pods-Joplin-tvOSTests.debug.xcconfig */,
|
||||
37DBC181C4AD99CBE0D07EEB /* Pods-Joplin-tvOSTests.release.xcconfig */,
|
||||
5DE39012F71F18423C665C57 /* Pods-ShareExtension.debug.xcconfig */,
|
||||
0473A2D469A3555053E69327 /* Pods-ShareExtension.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AE82E4A92599FA3A0013551B /* ShareExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AE152140260F770400217DCB /* ShareViewController.h */,
|
||||
AE152141260F770400217DCB /* ShareViewController.m */,
|
||||
AE7945DB259C9A2500051BE2 /* ShareExtension.entitlements */,
|
||||
AE82E4AD2599FA3A0013551B /* MainInterface.storyboard */,
|
||||
AE82E4B02599FA3A0013551B /* Info.plist */,
|
||||
);
|
||||
path = ShareExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -156,16 +220,36 @@
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
CBC8354E4CF5CF4E15F2FCDE /* [CP] Copy Pods Resources */,
|
||||
AE82E4B42599FA3A0013551B /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
AE82E4B22599FA3A0013551B /* PBXTargetDependency */,
|
||||
);
|
||||
name = Joplin;
|
||||
productName = Joplin;
|
||||
productReference = 13B07F961A680F5B00A75B9A /* Joplin.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
AE82E4A72599FA3A0013551B /* ShareExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = AE82E4B72599FA3A0013551B /* Build configuration list for PBXNativeTarget "ShareExtension" */;
|
||||
buildPhases = (
|
||||
027E2AA6B101F8CFCA582EC1 /* [CP] Check Pods Manifest.lock */,
|
||||
AE82E4A42599FA3A0013551B /* Sources */,
|
||||
AE82E4A52599FA3A0013551B /* Frameworks */,
|
||||
AE82E4A62599FA3A0013551B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ShareExtension;
|
||||
productName = ShareExtension;
|
||||
productReference = AE82E4A82599FA3A0013551B /* ShareExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
@ -179,6 +263,10 @@
|
||||
DevelopmentTeam = A9BXAFS6CT;
|
||||
LastSwiftMigration = 1120;
|
||||
};
|
||||
AE82E4A72599FA3A0013551B = {
|
||||
CreatedOnToolsVersion = 12.0.1;
|
||||
DevelopmentTeam = A9BXAFS6CT;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Joplin" */;
|
||||
@ -195,6 +283,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* Joplin */,
|
||||
AE82E4A72599FA3A0013551B /* ShareExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -209,6 +298,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
AE82E4A62599FA3A0013551B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
AE82E4AF2599FA3A0013551B /* MainInterface.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
@ -226,6 +323,28 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=/usr/local/opt/node@12/bin/node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
027E2AA6B101F8CFCA582EC1 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-ShareExtension-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
335ACF4DE85695BEBB18D8A3 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -329,8 +448,35 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
AE82E4A42599FA3A0013551B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
AE152142260F770400217DCB /* ShareViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
AE82E4B22599FA3A0013551B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = AE82E4A72599FA3A0013551B /* ShareExtension */;
|
||||
targetProxy = AE82E4B12599FA3A0013551B /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
AE82E4AD2599FA3A0013551B /* MainInterface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
AE82E4AE2599FA3A0013551B /* Base */,
|
||||
);
|
||||
name = MainInterface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
@ -338,6 +484,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 63;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -365,6 +512,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 63;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
@ -497,6 +645,62 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
AE82E4B52599FA3A0013551B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 5DE39012F71F18423C665C57 /* Pods-ShareExtension.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
AE82E4B62599FA3A0013551B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 0473A2D469A3555053E69327 /* Pods-ShareExtension.release.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@ -518,6 +722,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
AE82E4B72599FA3A0013551B /* Build configuration list for PBXNativeTarget "ShareExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
AE82E4B52599FA3A0013551B /* Debug */,
|
||||
AE82E4B62599FA3A0013551B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
|
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1200"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "AE82E4A72599FA3A0013551B"
|
||||
BuildableName = "ShareExtension.appex"
|
||||
BlueprintName = "ShareExtension"
|
||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Joplin.app"
|
||||
BlueprintName = "Joplin"
|
||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
askForAppToLaunch = "Yes"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Joplin.app"
|
||||
BlueprintName = "Joplin"
|
||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Joplin.app"
|
||||
BlueprintName = "Joplin"
|
||||
ReferencedContainer = "container:Joplin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -3,6 +3,7 @@
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <RNCPushNotificationIOS.h>
|
||||
#import "RNQuickActionManager.h"
|
||||
@ -103,4 +104,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
|
||||
return [RCTLinkingManager application:app openURL:url options:options];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -20,6 +20,19 @@
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>net.cozic.joplin</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>joplin</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
10
packages/app-mobile/ios/Joplin/Joplin.entitlements
Normal file
10
packages/app-mobile/ios/Joplin/Joplin.entitlements
Normal file
@ -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.net.cozic.joplin</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
@ -11,6 +11,7 @@ target 'Joplin' do
|
||||
use_react_native!(:path => config["reactNativePath"])
|
||||
|
||||
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||
pod 'JoplinRNShareExtension', :path => 'ShareExtension'
|
||||
|
||||
# Enables Flipper.
|
||||
#
|
||||
@ -21,3 +22,7 @@ target 'Joplin' do
|
||||
flipper_post_install(installer)
|
||||
end
|
||||
end
|
||||
|
||||
target 'ShareExtension' do
|
||||
pod 'JoplinCommonShareExtension', :path => 'ShareExtension'
|
||||
end
|
||||
|
@ -67,6 +67,10 @@ PODS:
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- glog (0.3.5)
|
||||
- JoplinCommonShareExtension (1.0.0)
|
||||
- JoplinRNShareExtension (1.0.0):
|
||||
- JoplinCommonShareExtension
|
||||
- React (= 0.63.3)
|
||||
- OpenSSL-Universal (1.0.2.20):
|
||||
- OpenSSL-Universal/Static (= 1.0.2.20)
|
||||
- OpenSSL-Universal/Static (1.0.2.20)
|
||||
@ -373,6 +377,8 @@ DEPENDENCIES:
|
||||
- FlipperKit/SKIOSNetworkPlugin (~> 0.54.0)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- JoplinCommonShareExtension (from `ShareExtension`)
|
||||
- JoplinRNShareExtension (from `ShareExtension`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
@ -444,6 +450,10 @@ EXTERNAL SOURCES:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
JoplinCommonShareExtension:
|
||||
:path: ShareExtension
|
||||
JoplinRNShareExtension:
|
||||
:path: ShareExtension
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired"
|
||||
RCTTypeSafety:
|
||||
@ -545,6 +555,8 @@ SPEC CHECKSUMS:
|
||||
FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
||||
JoplinCommonShareExtension: 270b4f8eb4e22828eeda433a04ed689fc1fd09b5
|
||||
JoplinRNShareExtension: 89e042edc89e290bc88955fe3ac7f1aaea97cbc8
|
||||
OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd
|
||||
RCTRequired: 48884c74035a0b5b76dbb7a998bd93bcfc5f2047
|
||||
RCTTypeSafety: edf4b618033c2f1c5b7bc3d90d8e085ed95ba2ab
|
||||
@ -590,6 +602,6 @@ SPEC CHECKSUMS:
|
||||
Yoga: 7d13633d129fd179e01b8953d38d47be90db185a
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: a0d1ca4e385ef46f9103f02206ebf612107dd508
|
||||
PODFILE CHECKSUM: 6f558aa823c0fd07348253cc01996e4ee3de75c4
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="xea-QC-Aqw">
|
||||
<rect key="frame" x="197" y="443" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="xea-QC-Aqw" firstAttribute="centerX" secondItem="1Xd-am-t49" secondAttribute="centerX" id="Al3-qb-mVX"/>
|
||||
<constraint firstItem="xea-QC-Aqw" firstAttribute="centerY" secondItem="1Xd-am-t49" secondAttribute="centerY" id="k5g-vk-GHv"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="xea-QC-Aqw" id="qxC-bS-d1N"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="139" y="101"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
47
packages/app-mobile/ios/ShareExtension/Info.plist
Normal file
47
packages/app-mobile/ios/ShareExtension/Info.plist
Normal file
@ -0,0 +1,47 @@
|
||||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>ShareExtension</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationDictionaryVersion</key>
|
||||
<integer>2</integer>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>10</integer>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>10</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "JoplinCommonShareExtension"
|
||||
spec.version = "1.0.0"
|
||||
spec.summary = "Common Share Extension code for Joplin."
|
||||
spec.description = "Common Share Extension for Joplin"
|
||||
spec.homepage = "https://github.com/laurent22/joplin"
|
||||
spec.license = { :type => "MIT" }
|
||||
spec.author = { "Duncan Cunningham" => "duncanc4@gmail.com" }
|
||||
spec.platform = :ios, "9.0"
|
||||
spec.source = { :path => "." }
|
||||
spec.source_files = "Source/Common/**/*.{h,m}"
|
||||
end
|
@ -0,0 +1,14 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "JoplinRNShareExtension"
|
||||
spec.version = "1.0.0"
|
||||
spec.summary = "React Native module for Joplin to access the data from the share extension."
|
||||
spec.description = "React Native Share Extension module for Joplin"
|
||||
spec.homepage = "https://github.com/laurent22/joplin"
|
||||
spec.license = { :type => "MIT" }
|
||||
spec.author = { "Duncan Cunningham" => "duncanc4@gmail.com" }
|
||||
spec.platform = :ios, "9.0"
|
||||
spec.source = { :path => "." }
|
||||
spec.source_files = "Source/RNShareExtension/**/*.{h,m}"
|
||||
spec.dependency "React", "0.63.3"
|
||||
spec.dependency "JoplinCommonShareExtension"
|
||||
end
|
29
packages/app-mobile/ios/ShareExtension/README.md
Normal file
29
packages/app-mobile/ios/ShareExtension/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Share Extension Creation Instructions
|
||||
## Creating the Target
|
||||
2. In Xcode select File->New->Target
|
||||
3. Then search for Share Extension
|
||||
4. Select Share Extension and click Next
|
||||
5. In Product Name enter ShareExtension
|
||||
6. Leave the rest of the options and click Finish
|
||||
7. If the Activate "ShareExtension" scheme popup comes, click Activate
|
||||
|
||||
## Configuring the Share Extension
|
||||
1. Delete *ShareViewController.h* and *ShareViewController.m* from the project. (Select files and right click, then Delete)
|
||||
2. On the confirmation popup, select Move to Trash
|
||||
3. Now add *ShareViewController.h* and *ShareViewController.m* from *ShareExtension/Source/ShareExtenstion*. This can be done by right clicking on the *ShareExtension* folder in Xcode and selecting Add Files to "Joplin". Double check that the ShareExtension is checked for Add to targets and click Add.
|
||||
4. Switch over to git and reset the changes done to *ShareExtension/Base.lproj/Maininterface.storyboard* and *ShareExtension/Info.plist*, as Xcode generated new versions of these files and overwrote ours.
|
||||
5. Now select the ShareExtension Target and go to Signing & Capabilities
|
||||
6. Click the + Capability and search for App Groups and add it
|
||||
7. Back in git reset *ShareExtension/ShareExtension.entitlements* as Xcode just overwrote it. Back in Xcode you should see the app group set
|
||||
8. Now switch to General, just left of Signing & Capabilites
|
||||
9. Under Deployment Info, change the iOS version to match the Joplin target version, which is 9.0
|
||||
|
||||
## Configuring Joplin
|
||||
1. We need to perform the same steps to add the App Group as done for the Share Extension, the only difference is the entitlements files is *Joplin.entitlements*
|
||||
|
||||
## Final Steps
|
||||
1. Run pod install from the ios directory to install the new pods
|
||||
|
||||
# Other Information
|
||||
## App Group
|
||||
If the app group name needs to be changed for some reason, it needs to be changed for both the Share Extension and Joplin. Also *ShareExtensionGroupIdentifier* in *ShareExtension/Source/Common/ShareExtensionConstants.m* needs to be changed to match the new app group.
|
@ -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.net.cozic.joplin</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,24 @@
|
||||
//
|
||||
// ShareData.h
|
||||
// ShareExtension
|
||||
//
|
||||
// Created by Duncan Cunningham on 2/6/21.
|
||||
// Copyright © 2021 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface ShareData : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSString* title;
|
||||
@property (nonatomic, strong) NSString* text;
|
||||
@property (nonatomic, strong) NSArray<NSDictionary*>* resources;
|
||||
|
||||
- (id)initWithDictionary:(NSDictionary*)dictionary;
|
||||
|
||||
- (NSDictionary*)encodeToDictionary;
|
||||
|
||||
+ (NSDictionary*)resourceDictionaryForURL:(NSString*)url withName:(NSString*)name andMimeType:(NSString*)mimeType;
|
||||
+ (NSString*)resourceURLFromDictionary:(NSDictionary*)dictionary;
|
||||
|
||||
@end
|
@ -0,0 +1,53 @@
|
||||
//
|
||||
// ShareData.m
|
||||
// ShareExtension
|
||||
//
|
||||
// Created by Duncan Cunningham on 2/6/21.
|
||||
// Copyright © 2021 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ShareData.h"
|
||||
|
||||
static NSString* const ShareDataTitleKey = @"title";
|
||||
static NSString* const ShareDataTextKey = @"text";
|
||||
static NSString* const ShareDataResourcesKey = @"resources";
|
||||
|
||||
static NSString* const ShareDataResourceUriKey = @"uri";
|
||||
static NSString* const ShareDataResourceNameKey = @"name";
|
||||
static NSString* const ShareDataResourceMimeTypeKey = @"mimeType";
|
||||
|
||||
@implementation ShareData
|
||||
|
||||
- (id)initWithDictionary:(NSDictionary*)dictionary {
|
||||
self = [super init];
|
||||
|
||||
if (self != nil) {
|
||||
self.title = [dictionary objectForKey:ShareDataTitleKey];
|
||||
self.text = [dictionary objectForKey:ShareDataTextKey];
|
||||
self.resources = [dictionary objectForKey:ShareDataResourcesKey];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary*)encodeToDictionary {
|
||||
NSString* title = (self.title == nil) ? @"" : self.title;
|
||||
NSString* text = (self.text == nil) ? @"" : self.text;
|
||||
NSArray* resources = (self.resources == nil) ? @[] : self.resources;
|
||||
|
||||
return @{ShareDataTitleKey: title,
|
||||
ShareDataTextKey: text,
|
||||
ShareDataResourcesKey: resources};
|
||||
}
|
||||
|
||||
+ (NSDictionary*)resourceDictionaryForURL:(NSString*)url withName:(NSString*)name andMimeType:(NSString*)mimeType {
|
||||
return @{ShareDataResourceUriKey: url,
|
||||
ShareDataResourceNameKey: name,
|
||||
ShareDataResourceMimeTypeKey: mimeType};
|
||||
}
|
||||
|
||||
+ (NSString*)resourceURLFromDictionary:(NSDictionary*)dictionary {
|
||||
return [dictionary objectForKey:ShareDataResourceUriKey];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,16 @@
|
||||
//
|
||||
// ShareExtensionConstants.h
|
||||
// Joplin
|
||||
//
|
||||
// Created by Duncan Cunningham on 2/6/21.
|
||||
// Copyright © 2021 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef ShareExtensionConstants_h
|
||||
#define ShareExtensionConstants_h
|
||||
|
||||
extern NSString* const ShareExtensionGroupIdentifier;
|
||||
extern NSString* const ShareExtensionShareURL;
|
||||
extern NSString* const ShareExtensionShareDataFilename;
|
||||
|
||||
#endif /* ShareExtensionConstants_h */
|
@ -0,0 +1,13 @@
|
||||
//
|
||||
// ShareExtensionConstants.m
|
||||
// Joplin
|
||||
//
|
||||
// Created by Duncan Cunningham on 2/6/21.
|
||||
// Copyright © 2021 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NSString* const ShareExtensionGroupIdentifier = @"group.net.cozic.joplin";
|
||||
NSString* const ShareExtensionShareURL = @"joplin://shareData";
|
||||
NSString* const ShareExtensionShareDataFilename = @"shareData";
|
@ -0,0 +1,67 @@
|
||||
//
|
||||
// ShareExtension.m
|
||||
// Joplin
|
||||
//
|
||||
// Created by Duncan Cunningham on 2/6/21.
|
||||
// Copyright © 2021 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
#import "ShareData.h"
|
||||
#import "ShareExtensionConstants.h"
|
||||
|
||||
@interface ShareExtension : NSObject <RCTBridgeModule>
|
||||
|
||||
@property (nonatomic, strong) ShareData* shareData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShareExtension
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_REMAP_METHOD(data, resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
NSDictionary* dictionary = [self decodeShareDataFromURL:self.shareDataURL];
|
||||
self.shareData = [[ShareData alloc] initWithDictionary:dictionary];
|
||||
resolve(dictionary);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(close) {
|
||||
if (self.shareData.resources != nil) {
|
||||
for (NSDictionary* resource in self.shareData.resources) {
|
||||
NSString* uri = [ShareData resourceURLFromDictionary:resource];
|
||||
if (uri != nil && [NSFileManager.defaultManager fileExistsAtPath:uri]) {
|
||||
[NSFileManager.defaultManager removeItemAtPath:uri error:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[NSFileManager.defaultManager removeItemAtPath:[[self shareDataURL] path] error:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSDictionary*)constantsToExport {
|
||||
return @{@"SHARE_EXTENSION_SHARE_URL": ShareExtensionShareURL};
|
||||
}
|
||||
|
||||
- (NSDictionary*)decodeShareDataFromURL:(NSURL*)url {
|
||||
NSData* data = [NSData dataWithContentsOfFile:[url path]];
|
||||
if (data != nil) {
|
||||
return [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSURL*)shareDataURL {
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
NSURL* sharedContainerURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:ShareExtensionGroupIdentifier];
|
||||
return [sharedContainerURL URLByAppendingPathComponent:ShareExtensionShareDataFilename];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,13 @@
|
||||
//
|
||||
// ShareViewController.h
|
||||
// ShareExtension
|
||||
//
|
||||
// Created by Duncan Cunningham on 12/28/20.
|
||||
// Copyright © 2020 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ShareViewController : UIViewController
|
||||
|
||||
@end
|
@ -0,0 +1,143 @@
|
||||
//
|
||||
// ShareViewController.m
|
||||
// ShareExtension
|
||||
//
|
||||
// Created by Duncan Cunningham on 12/28/20.
|
||||
// Copyright © 2020 joplinapp.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ShareViewController.h"
|
||||
#import "ShareData.h"
|
||||
#import "ShareExtensionConstants.h"
|
||||
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
@interface ShareViewController ()
|
||||
|
||||
@property (nonatomic, strong) NSURL* sharedContainerURL;
|
||||
|
||||
@property (nonatomic, weak) IBOutlet UIActivityIndicatorView *spinner;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShareViewController
|
||||
|
||||
- (NSURL*)sharedContainerURL {
|
||||
if (_sharedContainerURL == nil) {
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
_sharedContainerURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:ShareExtensionGroupIdentifier];
|
||||
}
|
||||
|
||||
return _sharedContainerURL;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self.spinner startAnimating];
|
||||
|
||||
[self extractDataFromContext:self.extensionContext withCallback:^(ShareData* shareData) {
|
||||
[self serializeShareDataToSharedContainer:shareData];
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^(void){
|
||||
[self.spinner stopAnimating];
|
||||
[self.extensionContext completeRequestReturningItems:nil completionHandler:nil];
|
||||
[self launchMainApp];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)extractDataFromContext:(NSExtensionContext *)context withCallback:(void(^)(ShareData* shareData))callback {
|
||||
__block ShareData* shareData = [[ShareData alloc] init];
|
||||
NSMutableArray* resources = [[NSMutableArray alloc] init];
|
||||
|
||||
NSExtensionItem* item = [context.inputItems firstObject];
|
||||
NSArray* attachments = item.attachments;
|
||||
__block NSUInteger index = 0;
|
||||
|
||||
[attachments enumerateObjectsUsingBlock:^(NSItemProvider* provider, NSUInteger idx, BOOL* stop) {
|
||||
[provider.registeredTypeIdentifiers enumerateObjectsUsingBlock:^(NSString* identifier, NSUInteger idx, BOOL* stop) {
|
||||
[provider loadItemForTypeIdentifier:identifier options:nil completionHandler:^(id<NSSecureCoding> item, NSError* error) {
|
||||
index += 1;
|
||||
|
||||
// is an URL - Can be a path or Web URL
|
||||
if ([(NSObject*)item isKindOfClass:[NSURL class]]) {
|
||||
NSURL* url = (NSURL*)item;
|
||||
if ([[url pathExtension] isEqualToString:@""] || [url.scheme containsString:@"http"]) {
|
||||
shareData.text = [url absoluteString];
|
||||
} else {
|
||||
NSURL* copiedURL = [self copyURLToSharedContainer:url];
|
||||
NSDictionary* resource = [self resourceDictionaryForMediaURL:copiedURL];
|
||||
[resources addObject:resource];
|
||||
}
|
||||
// is a String
|
||||
} else if ([(NSObject*)item isKindOfClass:[NSString class]]) {
|
||||
shareData.text = (NSString*)item;
|
||||
// is an Image
|
||||
} else if ([(NSObject*)item isKindOfClass:[UIImage class]]) {
|
||||
UIImage* sharedImage = (UIImage*)item;
|
||||
NSURL* path = [self copyImageToSharedContainer:sharedImage];
|
||||
NSDictionary* resource = [self resourceDictionaryForMediaURL:path];
|
||||
[resources addObject:resource];
|
||||
}
|
||||
|
||||
if (index == [attachments count]) {
|
||||
shareData.resources = resources;
|
||||
callback(shareData);
|
||||
}
|
||||
}];
|
||||
|
||||
// We'll only use the first provider
|
||||
*stop = YES;
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSURL*)copyImageToSharedContainer:(UIImage*)image {
|
||||
NSString* name = [NSString stringWithFormat:@"%@%@", [NSUUID new].UUIDString, @".png"];
|
||||
NSURL* path = [self.sharedContainerURL URLByAppendingPathComponent:name];
|
||||
[UIImagePNGRepresentation(image) writeToFile:[path path] atomically:YES];
|
||||
return path;
|
||||
}
|
||||
|
||||
- (NSURL*)copyURLToSharedContainer:(NSURL*)url {
|
||||
NSString* name = [url lastPathComponent];
|
||||
NSURL* path = [self.sharedContainerURL URLByAppendingPathComponent:name];
|
||||
[[NSFileManager defaultManager] copyItemAtPath:[url path] toPath:[path path] error:nil];
|
||||
return path;
|
||||
}
|
||||
|
||||
- (void)serializeShareDataToSharedContainer:(ShareData*)shareData {
|
||||
NSData* data = [NSJSONSerialization dataWithJSONObject:[shareData encodeToDictionary] options:0 error:nil];
|
||||
NSURL* path = [self.sharedContainerURL URLByAppendingPathComponent:ShareExtensionShareDataFilename isDirectory:NO];
|
||||
[data writeToFile:[path path] options:NSDataWritingAtomic error: nil];
|
||||
}
|
||||
|
||||
- (NSDictionary*)resourceDictionaryForMediaURL:(NSURL*)url {
|
||||
NSString* name = [url lastPathComponent];
|
||||
NSString* extension = [url pathExtension];
|
||||
NSString* mimeType = [self mimeTypeFor:extension];
|
||||
return [ShareData resourceDictionaryForURL:[url absoluteString] withName:name andMimeType:mimeType];
|
||||
}
|
||||
|
||||
- (NSString*)mimeTypeFor:(NSString*)fileExtension{
|
||||
NSString* UTI = (__bridge_transfer NSString*)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL);
|
||||
NSString* mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
- (void)launchMainApp {
|
||||
SEL selector = NSSelectorFromString(@"openURL:");
|
||||
|
||||
UIResponder* responder = self;
|
||||
while (responder != nil) {
|
||||
if ([responder respondsToSelector:selector]) {
|
||||
[responder performSelector:selector withObject:[NSURL URLWithString:ShareExtensionShareURL]];
|
||||
break;
|
||||
}
|
||||
|
||||
responder = responder.nextResponder;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -27,7 +27,7 @@ import { setLocale, closestSupportedLocale, defaultLocale } from '@joplin/lib/lo
|
||||
import SyncTargetJoplinServer from '@joplin/lib/SyncTargetJoplinServer';
|
||||
import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
|
||||
|
||||
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native');
|
||||
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar, Linking } = require('react-native');
|
||||
|
||||
import NetInfo from '@react-native-community/netinfo';
|
||||
const DropdownAlert = require('react-native-dropdownalert').default;
|
||||
@ -631,6 +631,12 @@ class AppComponent extends React.Component {
|
||||
this.onAppStateChange_ = () => {
|
||||
PoorManIntervals.update();
|
||||
};
|
||||
|
||||
this.handleOpenURL_ = (event: any) => {
|
||||
if (event.url == ShareExtension.shareURL) {
|
||||
void this.handleShareData();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 2020-10-08: It seems the initialisation code is quite fragile in general and should be kept simple.
|
||||
@ -683,6 +689,8 @@ class AppComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
Linking.addEventListener('url', this.handleOpenURL_);
|
||||
|
||||
BackButtonService.initialize(this.backButtonHandler_);
|
||||
|
||||
AlarmService.setInAppNotificationHandler(async (alarmId: string) => {
|
||||
@ -693,21 +701,14 @@ class AppComponent extends React.Component {
|
||||
|
||||
AppState.addEventListener('change', this.onAppStateChange_);
|
||||
|
||||
const sharedData = await ShareExtension.data();
|
||||
if (sharedData) {
|
||||
reg.logger().info('Received shared data');
|
||||
if (this.props.selectedFolderId) {
|
||||
await handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
|
||||
} else {
|
||||
reg.logger().info('Cannot handle share - default folder id is not set');
|
||||
}
|
||||
}
|
||||
await this.handleShareData();
|
||||
|
||||
setUpQuickActions(this.props.dispatch, this.props.selectedFolderId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
AppState.removeEventListener('change', this.onAppStateChange_);
|
||||
Linking.removeEventListener('url', this.handleOpenURL_);
|
||||
if (this.unsubscribeNetInfoHandler_) this.unsubscribeNetInfoHandler_();
|
||||
}
|
||||
|
||||
@ -741,6 +742,18 @@ class AppComponent extends React.Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
async handleShareData() {
|
||||
const sharedData = await ShareExtension.data();
|
||||
if (sharedData) {
|
||||
reg.logger().info('Received shared data');
|
||||
if (this.props.selectedFolderId) {
|
||||
await handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
|
||||
} else {
|
||||
reg.logger().info('Cannot handle share - default folder id is not set');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps: any) {
|
||||
if (newProps.syncStarted != this.lastSyncStarted_) {
|
||||
if (!newProps.syncStarted) FoldersScreenUtils.refreshFolders();
|
||||
|
@ -6,14 +6,16 @@ export interface SharedData {
|
||||
resources?: string[];
|
||||
}
|
||||
|
||||
const ShareExtension = (Platform.OS === 'android' && NativeModules.ShareExtension) ?
|
||||
const ShareExtension = (NativeModules.ShareExtension) ?
|
||||
{
|
||||
data: () => NativeModules.ShareExtension.data(),
|
||||
close: () => NativeModules.ShareExtension.close(),
|
||||
shareURL: (Platform.OS === 'ios') ? NativeModules.ShareExtension.getConstants().SHARE_EXTENSION_SHARE_URL : '',
|
||||
} :
|
||||
{
|
||||
data: () => {},
|
||||
close: () => {},
|
||||
shareURL: '',
|
||||
};
|
||||
|
||||
export default ShareExtension;
|
||||
|
@ -5,16 +5,20 @@ import Note from '@joplin/lib/models/Note';
|
||||
import checkPermissions from './checkPermissions.js';
|
||||
const { ToastAndroid } = require('react-native');
|
||||
const { PermissionsAndroid } = require('react-native');
|
||||
const { Platform } = require('react-native');
|
||||
|
||||
export default async (sharedData: SharedData, folderId: string, dispatch: Function) => {
|
||||
|
||||
if (!!sharedData.resources && sharedData.resources.length > 0) {
|
||||
const response = await checkPermissions(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
|
||||
// No need to check permissions for iOS, the files are already in the shared container
|
||||
if (Platform.OS === 'android') {
|
||||
const response = await checkPermissions(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
|
||||
|
||||
if (response !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||
ToastAndroid.show('Cannot receive shared data - permission denied', ToastAndroid.SHORT);
|
||||
ShareExtension.close();
|
||||
return;
|
||||
if (response !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||
ToastAndroid.show('Cannot receive shared data - permission denied', ToastAndroid.SHORT);
|
||||
ShareExtension.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user