From cf49685c5e58f8d5079774872596192fb86663b9 Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Sat, 18 Apr 2020 10:36:31 -0400 Subject: [PATCH 1/7] Update MMWormhole to support multiple individual message payloads --- .../MMWormhole.xcodeproj/project.pbxproj | 69 +++++---- MMWormhole.podspec | 2 +- Source/MMWormhole.h | 2 + Source/MMWormhole.m | 4 + Source/MMWormholeManifestFileTransiting.h | 37 +++++ Source/MMWormholeManifestFileTransiting.m | 144 ++++++++++++++++++ 6 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 Source/MMWormholeManifestFileTransiting.h create mode 100644 Source/MMWormholeManifestFileTransiting.m diff --git a/Example/MMWormhole/MMWormhole.xcodeproj/project.pbxproj b/Example/MMWormhole/MMWormhole.xcodeproj/project.pbxproj index 8da6fc7..6db4211 100644 --- a/Example/MMWormhole/MMWormhole.xcodeproj/project.pbxproj +++ b/Example/MMWormhole/MMWormhole.xcodeproj/project.pbxproj @@ -21,34 +21,34 @@ 2679DC051A33C45200961787 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2679DC041A33C45200961787 /* Interface.storyboard */; }; 2679DC071A33C45200961787 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2679DC061A33C45200961787 /* Images.xcassets */; }; 2679DC0A1A33C45200961787 /* MMWormhole WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2679DBEF1A33C45200961787 /* MMWormhole WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 26C184D21BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D31BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D41BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D51BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D71BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D81BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184D91BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184DA1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184DB1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184DC1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184DD1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184DE1BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; settings = {ASSET_TAGS = (); }; }; - 26C184DF1BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E01BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E11BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E21BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E31BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E41BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E51BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E61BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E71BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E81BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184E91BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184EA1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184EB1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184EC1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; settings = {ASSET_TAGS = (); }; }; - 26C184ED1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; settings = {ASSET_TAGS = (); }; }; + 26C184D21BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; }; + 26C184D31BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; }; + 26C184D41BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; }; + 26C184D51BA5DDA5001A8063 /* MMWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C41BA5DDA5001A8063 /* MMWormhole.m */; }; + 26C184D61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; }; + 26C184D71BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; }; + 26C184D81BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; }; + 26C184D91BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m */; }; + 26C184DA1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; }; + 26C184DB1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; }; + 26C184DC1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; }; + 26C184DD1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184C81BA5DDA5001A8063 /* MMWormholeFileTransiting.m */; }; + 26C184DE1BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; }; + 26C184DF1BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; }; + 26C184E01BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; }; + 26C184E11BA5DDA5001A8063 /* MMWormholeSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CA1BA5DDA5001A8063 /* MMWormholeSession.m */; }; + 26C184E21BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; }; + 26C184E31BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; }; + 26C184E41BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; }; + 26C184E51BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CC1BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m */; }; + 26C184E61BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; }; + 26C184E71BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; }; + 26C184E81BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; }; + 26C184E91BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184CE1BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m */; }; + 26C184EA1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; }; + 26C184EB1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; }; + 26C184EC1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; }; + 26C184ED1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */; }; 55030BCD1B163680005EFC19 /* MMWormholeFileTransitingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 55030BCC1B163680005EFC19 /* MMWormholeFileTransitingTests.m */; }; 55030BD51B165857005EFC19 /* MMWormholeCoordinatedFileTransitingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 55030BD41B165857005EFC19 /* MMWormholeCoordinatedFileTransitingTests.m */; }; 55D935F41A38A4F200AD1A1C /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D935F31A38A4F200AD1A1C /* NotificationCenter.framework */; }; @@ -62,6 +62,10 @@ 55E647011B2659FB006ADC7F /* ExtensionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E647001B2659FB006ADC7F /* ExtensionDelegate.m */; }; 55E6470C1B2659FB006ADC7F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55E6470B1B2659FB006ADC7F /* Assets.xcassets */; }; 55E647101B2659FB006ADC7F /* watchOS.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 55E646E91B2659FB006ADC7F /* watchOS.app */; }; + B5217F2E244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = B5217F2C244B2EEA00D811BC /* MMWormholeManifestFileTransiting.m */; }; + B5217F2F244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = B5217F2C244B2EEA00D811BC /* MMWormholeManifestFileTransiting.m */; }; + B5217F30244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = B5217F2C244B2EEA00D811BC /* MMWormholeManifestFileTransiting.m */; }; + B5217F31244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */ = {isa = PBXBuildFile; fileRef = B5217F2C244B2EEA00D811BC /* MMWormholeManifestFileTransiting.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -209,6 +213,8 @@ 55E6470B1B2659FB006ADC7F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55E6470D1B2659FB006ADC7F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55E6471C1B265AFA006ADC7F /* watchOS Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "watchOS Extension.entitlements"; sourceTree = ""; }; + B5217F2C244B2EEA00D811BC /* MMWormholeManifestFileTransiting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MMWormholeManifestFileTransiting.m; path = ../../../Source/MMWormholeManifestFileTransiting.m; sourceTree = ""; }; + B5217F2D244B2EEA00D811BC /* MMWormholeManifestFileTransiting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MMWormholeManifestFileTransiting.h; path = ../../../Source/MMWormholeManifestFileTransiting.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -399,6 +405,8 @@ 26C184CF1BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.h */, 26C184D01BA5DDA5001A8063 /* MMWormholeSessionMessageTransiting.m */, 26C184D11BA5DDA5001A8063 /* MMWormholeTransiting.h */, + B5217F2D244B2EEA00D811BC /* MMWormholeManifestFileTransiting.h */, + B5217F2C244B2EEA00D811BC /* MMWormholeManifestFileTransiting.m */, ); name = MMWormhole; sourceTree = ""; @@ -648,6 +656,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -740,6 +749,7 @@ 26C184DA1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */, 26C184E21BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */, 2679DBC51A33B7C700961787 /* AppDelegate.m in Sources */, + B5217F2E244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */, 26C184D61BA5DDA5001A8063 /* MMWormholeCoordinatedFileTransiting.m in Sources */, 26C184D21BA5DDA5001A8063 /* MMWormhole.m in Sources */, 2679DBC21A33B7C700961787 /* main.m in Sources */, @@ -768,6 +778,7 @@ 26C184E31BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */, 26C184D31BA5DDA5001A8063 /* MMWormhole.m in Sources */, 2679DBF81A33C45200961787 /* InterfaceController.m in Sources */, + B5217F2F244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */, 26C184DB1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */, 26C184E71BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */, ); @@ -783,6 +794,7 @@ 26C184E41BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */, 26C184D41BA5DDA5001A8063 /* MMWormhole.m in Sources */, 55D935FA1A38A4F200AD1A1C /* TodayViewController.m in Sources */, + B5217F30244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */, 26C184DC1BA5DDA5001A8063 /* MMWormholeFileTransiting.m in Sources */, 26C184E81BA5DDA5001A8063 /* MMWormholeSessionFileTransiting.m in Sources */, ); @@ -792,6 +804,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B5217F31244B2EEB00D811BC /* MMWormholeManifestFileTransiting.m in Sources */, 26C184E51BA5DDA5001A8063 /* MMWormholeSessionContextTransiting.m in Sources */, 55E647011B2659FB006ADC7F /* ExtensionDelegate.m in Sources */, 55E646FE1B2659FB006ADC7F /* InterfaceController.m in Sources */, diff --git a/MMWormhole.podspec b/MMWormhole.podspec index d8855f8..580657a 100644 --- a/MMWormhole.podspec +++ b/MMWormhole.podspec @@ -21,6 +21,6 @@ Pod::Spec.new do |s| s.subspec 'Core' do |core| core.ios.source_files = 'Source/*.{h,m}' core.watchos.source_files = 'Source/*.{h,m}' - core.osx.source_files = 'Source/MMWormhole.{h,m}', 'Source/MMWormholeFileTransiting.{h,m}', 'Source/MMWormholeCoordinatedFileTransiting.{h,m}', 'Source/MMWormholeTransiting.h' + core.osx.source_files = 'Source/MMWormhole.{h,m}', 'Source/MMWormholeFileTransiting.{h,m}', 'Source/MMWormholeManifestFileTransiting.{h,m}', 'Source/MMWormholeCoordinatedFileTransiting.{h,m}', 'Source/MMWormholeTransiting.h' end end diff --git a/Source/MMWormhole.h b/Source/MMWormhole.h index b56d0b8..1df9670 100644 --- a/Source/MMWormhole.h +++ b/Source/MMWormhole.h @@ -24,6 +24,7 @@ #import #import "MMWormholeCoordinatedFileTransiting.h" +#import "MMWormholeManifestFileTransiting.h" #import "MMWormholeFileTransiting.h" #if ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 ) @@ -37,6 +38,7 @@ typedef NS_ENUM(NSInteger, MMWormholeTransitingType) { MMWormholeTransitingTypeFile = 0, MMWormholeTransitingTypeCoordinatedFile, + MMWormholeTransitingTypeManifestFile, MMWormholeTransitingTypeSessionContext, MMWormholeTransitingTypeSessionMessage, MMWormholeTransitingTypeSessionFile diff --git a/Source/MMWormhole.m b/Source/MMWormhole.m index 68bf429..30d2f46 100644 --- a/Source/MMWormhole.m +++ b/Source/MMWormhole.m @@ -92,6 +92,10 @@ - (instancetype)initWithApplicationGroupIdentifier:(nullable NSString *)identifi self.wormholeMessenger = [[MMWormholeCoordinatedFileTransiting alloc] initWithApplicationGroupIdentifier:identifier optionalDirectory:directory]; break; + case MMWormholeTransitingTypeManifestFile: + self.wormholeMessenger = [[MMWormholeManifestFileTransiting alloc] initWithApplicationGroupIdentifier:identifier + optionalDirectory:directory]; + break; case MMWormholeTransitingTypeSessionContext: #if ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 ) self.wormholeMessenger = [[MMWormholeSessionContextTransiting alloc] initWithApplicationGroupIdentifier:identifier diff --git a/Source/MMWormholeManifestFileTransiting.h b/Source/MMWormholeManifestFileTransiting.h new file mode 100644 index 0000000..2416247 --- /dev/null +++ b/Source/MMWormholeManifestFileTransiting.h @@ -0,0 +1,37 @@ +// +// MMWormholeCoordinatedFileTransiting.h +// +// Copyright (c) 2015 Mutual Mobile (http://www.mutualmobile.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "MMWormholeFileTransiting.h" + +/** +This class inherits from the default implementation of the MMWormholeTransiting protocol +and copies the message transiting implementation from MMWormholeCoordinatedFileTransiting. + +In addition, it utilizes a manifest object (a wrapping NSArray) to store unique object copies, thus enabling +multiple unique message storage and replay. +*/ +@interface MMWormholeManifestFileTransiting : MMWormholeFileTransiting + +@property (nonatomic, assign) NSDataWritingOptions additionalFileWritingOptions; + +@end diff --git a/Source/MMWormholeManifestFileTransiting.m b/Source/MMWormholeManifestFileTransiting.m new file mode 100644 index 0000000..8b926a7 --- /dev/null +++ b/Source/MMWormholeManifestFileTransiting.m @@ -0,0 +1,144 @@ +// +// MMWormholeCoordinatedFileTransiting.h +// +// Copyright (c) 2015 Mutual Mobile (http://www.mutualmobile.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "MMWormholeManifestFileTransiting.h" + +@implementation MMWormholeManifestFileTransiting + +#pragma mark - MMWormholeTransiting Methods + +- (BOOL)writeMessageObject:(id)messageObject forIdentifier:(NSString *)identifier { + if (identifier == nil) { + return NO; + } + + if (messageObject) { + //Insert into manifest + NSMutableArray *storageArray = nil; + NSArray *potentialOnDiskArray = (NSArray *)[self _arrayForIdentifier:identifier]; + if (potentialOnDiskArray) { + storageArray = [NSMutableArray arrayWithArray:potentialOnDiskArray]; + } else { + storageArray = [[NSMutableArray alloc] init]; + } + [storageArray addObject:messageObject]; + + //Encode manifest instead of message object + BOOL success = [self _writeArrayToDisk:storageArray forIdentifier:identifier]; + + if (!success) { + return NO; + } + } + + return YES; +} + + +- (id)messageObjectForIdentifier:(NSString *)identifier { + if (identifier == nil) { + return nil; + } + + //Arguably unsafe as something else could change us on disk + //TODO: utilize encrypted container with NSSecureCoding to avoid above + NSArray *storageArray = [self _arrayForIdentifier:identifier]; + if ([storageArray count] == 0) { + return nil; + } + id messageObject = storageArray[0]; + NSMutableArray *arrayToWrite = [NSMutableArray arrayWithArray:storageArray]; + [arrayToWrite removeObjectAtIndex:0]; + + //TODO: What to do if this fails? + [self _writeArrayToDisk:arrayToWrite forIdentifier:identifier]; + + return messageObject; +} + +#pragma mark - Helper Methods + +- (BOOL)_writeArrayToDisk:(NSArray *)array forIdentifier:(NSString *)identifier{ + //Encode manifest instead of message object + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array]; + NSString *filePath = [self filePathForIdentifier:identifier]; + NSURL *fileURL = [NSURL fileURLWithPath:filePath]; + + if (data == nil || filePath == nil || fileURL == nil) { + return NO; + } + + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; + NSError *error = nil; + __block BOOL success = NO; + + [fileCoordinator + coordinateWritingItemAtURL:fileURL + options:0 + error:&error + byAccessor:^(NSURL *newURL) { + NSError *writeError = nil; + + success = [data writeToURL:newURL + options:NSDataWritingAtomic | self.additionalFileWritingOptions + error:&writeError]; + }]; + + return success; +} + +- (nullable NSArray*)_arrayForIdentifier:(NSString *)identifier{ + if (identifier == nil) { + return nil; + } + + NSString *filePath = [self filePathForIdentifier:identifier]; + NSURL *fileURL = [NSURL fileURLWithPath:filePath]; + + if (filePath == nil || fileURL == nil) { + return nil; + } + + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; + NSError *error = nil; + __block NSData *data = nil; + + [fileCoordinator + coordinateReadingItemAtURL:fileURL + options:0 + error:&error + byAccessor:^(NSURL *newURL) { + data = [NSData dataWithContentsOfURL:newURL]; + }]; + + if (data == nil) { + return nil; + } + + //Arguably unsafe as something else could change us on disk + //TODO: utilize encrypted container with NSSecureCoding to avoid above + NSArray *storageArray = (NSArray *)[NSKeyedUnarchiver unarchiveObjectWithData:data]; + return storageArray; +} + +@end From 1aec78f638a4be32af0d322229bc9d4dadcea329 Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Sat, 18 Apr 2020 10:45:08 -0400 Subject: [PATCH 2/7] Whitespace --- Source/MMWormholeManifestFileTransiting.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/MMWormholeManifestFileTransiting.m b/Source/MMWormholeManifestFileTransiting.m index 8b926a7..4f2c349 100644 --- a/Source/MMWormholeManifestFileTransiting.m +++ b/Source/MMWormholeManifestFileTransiting.m @@ -54,7 +54,6 @@ - (BOOL)writeMessageObject:(id)messageObject forIdentifier:(NSString * return YES; } - - (id)messageObjectForIdentifier:(NSString *)identifier { if (identifier == nil) { return nil; From 987b7fb02060868e94b64b9978cd2c518d80a823 Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Sat, 18 Apr 2020 10:48:40 -0400 Subject: [PATCH 3/7] Comments cleanup --- Source/MMWormholeManifestFileTransiting.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/MMWormholeManifestFileTransiting.m b/Source/MMWormholeManifestFileTransiting.m index 4f2c349..5aafdce 100644 --- a/Source/MMWormholeManifestFileTransiting.m +++ b/Source/MMWormholeManifestFileTransiting.m @@ -59,8 +59,6 @@ - (BOOL)writeMessageObject:(id)messageObject forIdentifier:(NSString * return nil; } - //Arguably unsafe as something else could change us on disk - //TODO: utilize encrypted container with NSSecureCoding to avoid above NSArray *storageArray = [self _arrayForIdentifier:identifier]; if ([storageArray count] == 0) { return nil; @@ -78,7 +76,6 @@ - (BOOL)writeMessageObject:(id)messageObject forIdentifier:(NSString * #pragma mark - Helper Methods - (BOOL)_writeArrayToDisk:(NSArray *)array forIdentifier:(NSString *)identifier{ - //Encode manifest instead of message object NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array]; NSString *filePath = [self filePathForIdentifier:identifier]; NSURL *fileURL = [NSURL fileURLWithPath:filePath]; From 28505d02447aa540d44083f79fbfb34a773d45e0 Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Fri, 24 Apr 2020 08:13:45 -0400 Subject: [PATCH 4/7] Resolve crash in write --- Source/MMWormholeManifestFileTransiting.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/MMWormholeManifestFileTransiting.m b/Source/MMWormholeManifestFileTransiting.m index 5aafdce..c940866 100644 --- a/Source/MMWormholeManifestFileTransiting.m +++ b/Source/MMWormholeManifestFileTransiting.m @@ -36,7 +36,8 @@ - (BOOL)writeMessageObject:(id)messageObject forIdentifier:(NSString * //Insert into manifest NSMutableArray *storageArray = nil; NSArray *potentialOnDiskArray = (NSArray *)[self _arrayForIdentifier:identifier]; - if (potentialOnDiskArray) { + //Covers edge cases where a crash can occur when changing to using this transit style from other styles + if ([potentialOnDiskArray isKindOfClass:[NSArray class]]) { storageArray = [NSMutableArray arrayWithArray:potentialOnDiskArray]; } else { storageArray = [[NSMutableArray alloc] init]; From 57b157c89ab218c588779645d8e2e03a0400bdc3 Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Thu, 30 Apr 2020 22:32:19 -0400 Subject: [PATCH 5/7] Make iOS send coordinated messages for all messages --- Source/MMWormhole.m | 17 ++++++++++++++--- Source/MMWormholeManifestFileTransiting.m | 9 +++++++++ Source/MMWormholeTransiting.h | 10 +++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Source/MMWormhole.m b/Source/MMWormhole.m index 30d2f46..c7af102 100644 --- a/Source/MMWormhole.m +++ b/Source/MMWormhole.m @@ -179,12 +179,23 @@ - (void)didReceiveMessageNotification:(NSNotification *)notification { NSString *identifier = [userInfo valueForKey:@"identifier"]; if (identifier != nil) { - id messageObject = [self.wormholeMessenger messageObjectForIdentifier:identifier]; - - [self notifyListenerForMessageWithIdentifier:identifier message:messageObject]; +#if ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 ) + if ([self.wormholeMessenger respondsToSelector:@selector(numberOfMessageItemsforIdentifier:)]) { + NSInteger messageCount = [self.wormholeMessenger numberOfMessageItemsforIdentifier:identifier]; + for (int i = 0; i < messageCount; i++) { + [self _sendNotificationForIdentifier:identifier]; + } + } +#endif + [self _sendNotificationForIdentifier:identifier]; } } +- (void)_sendNotificationForIdentifier:(NSString *)identifier { + id messageObject = [self.wormholeMessenger messageObjectForIdentifier:identifier]; + [self notifyListenerForMessageWithIdentifier:identifier message:messageObject]; +} + - (id)listenerBlockForIdentifier:(NSString *)identifier { return [self.listenerBlocks valueForKey:identifier]; } diff --git a/Source/MMWormholeManifestFileTransiting.m b/Source/MMWormholeManifestFileTransiting.m index c940866..d61de1a 100644 --- a/Source/MMWormholeManifestFileTransiting.m +++ b/Source/MMWormholeManifestFileTransiting.m @@ -74,6 +74,15 @@ - (BOOL)writeMessageObject:(id)messageObject forIdentifier:(NSString * return messageObject; } + +- (NSInteger)numberOfMessageItemsforIdentifier:(NSString *)identifier { + NSArray *array = [self _arrayForIdentifier:identifier]; + if ([array isKindOfClass:[NSArray class]]) { + return array.count; + } + return 0; +} + #pragma mark - Helper Methods - (BOOL)_writeArrayToDisk:(NSArray *)array forIdentifier:(NSString *)identifier{ diff --git a/Source/MMWormholeTransiting.h b/Source/MMWormholeTransiting.h index 29b1278..9ce00c0 100644 --- a/Source/MMWormholeTransiting.h +++ b/Source/MMWormholeTransiting.h @@ -68,6 +68,14 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)deleteContentForAllMessages; +@optional + +/** + This method returns the total number of items on disk we need to dispatch messages for. Used on iOS 13+ + to enqueue multiple messages for dispatch + */ +- (NSInteger)numberOfMessageItemsforIdentifier:(NSString *)identifier; + @end @protocol MMWormholeTransitingDelegate @@ -76,4 +84,4 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END \ No newline at end of file +NS_ASSUME_NONNULL_END From 2df113e8757782fe0141a76ca7b0a2556721ad0e Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Thu, 30 Apr 2020 22:33:28 -0400 Subject: [PATCH 6/7] Return out correctly --- Source/MMWormhole.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/MMWormhole.m b/Source/MMWormhole.m index c7af102..6115ca0 100644 --- a/Source/MMWormhole.m +++ b/Source/MMWormhole.m @@ -185,6 +185,7 @@ - (void)didReceiveMessageNotification:(NSNotification *)notification { for (int i = 0; i < messageCount; i++) { [self _sendNotificationForIdentifier:identifier]; } + return; } #endif [self _sendNotificationForIdentifier:identifier]; From 60695b9b4216ed20cd8378de590625d35ab84ec0 Mon Sep 17 00:00:00 2001 From: Matt Smollinger Date: Fri, 1 May 2020 22:49:27 -0400 Subject: [PATCH 7/7] Add additional logic for iOS to replay all stored messages --- Source/MMWormhole.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/MMWormhole.m b/Source/MMWormhole.m index 6115ca0..a704c44 100644 --- a/Source/MMWormhole.m +++ b/Source/MMWormhole.m @@ -179,7 +179,7 @@ - (void)didReceiveMessageNotification:(NSNotification *)notification { NSString *identifier = [userInfo valueForKey:@"identifier"]; if (identifier != nil) { -#if ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 ) +#if ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 && !TARGET_OS_SIMULATOR ) if ([self.wormholeMessenger respondsToSelector:@selector(numberOfMessageItemsforIdentifier:)]) { NSInteger messageCount = [self.wormholeMessenger numberOfMessageItemsforIdentifier:identifier]; for (int i = 0; i < messageCount; i++) {