@@ -76,6 +76,15 @@ func getBundleIdentifier() -> String {
7676 #endif
7777}
7878
79+ /**
80+ Determines if the current process is an extension target.
81+
82+ App extensions have bundle paths ending in ".appex"
83+ */
84+ func isExtension( ) -> Bool {
85+ Bundle . main. bundlePath. hasSuffix ( " .appex " )
86+ }
87+
7988/**
8089 Merges content from a legacy container directory into the current app group container.
8190
@@ -84,7 +93,7 @@ func getBundleIdentifier() -> String {
8493
8594 Migration rules:
8695 - Files that already exist at the destination are skipped (no overwrite)
87- - The anonymousId from the first processed container (legacy or current) is preserved to maintain user identity
96+ - Identity-related keys (distinctId, anonymousId, etc.) are only migrated from the main app target
8897 - Successfully migrated files are deleted from the source
8998 - Empty directories are cleaned up after migration
9099 - The entire folder structure is preserved during migration
@@ -99,10 +108,26 @@ func mergeLegacyContainerIfNeeded(within libraryUrl: URL?, to destinationUrl: UR
99108 return
100109 }
101110
102- hedgeLog ( " Legacy folder found at \( sourceUrl) , merging... " )
111+ let skipKeys : [ PostHogStorage . StorageKey ]
112+ if isExtension ( ) {
113+ // Extensions should skip migrating identity-related keys to ensure consistent user identity with main app target
114+ skipKeys = [
115+ . distinctId,
116+ . anonymousId,
117+ . isIdentified,
118+ . groups,
119+ . registerProperties,
120+ . personPropertiesForFlags,
121+ . groupPropertiesForFlags,
122+ ]
123+ hedgeLog ( " Legacy folder found at \( sourceUrl) , merging from extension... (skipping \( skipKeys. count) identity keys) " )
124+ } else {
125+ skipKeys = [ ]
126+ hedgeLog ( " Legacy folder found at \( sourceUrl) , merging from main app... (migrating all keys) " )
127+ }
103128
104- // Migrate all contents from the legacy container
105- migrateDirectoryContents ( from: sourceUrl, to: destinationUrl)
129+ // Migrate contents from the legacy container
130+ migrateDirectoryContents ( from: sourceUrl, to: destinationUrl, skipKeys : skipKeys )
106131
107132 // Try to remove the source directory if it's empty
108133 if removeIfEmpty ( sourceUrl) {
@@ -141,10 +166,11 @@ func removeIfEmpty(_ url: URL) -> Bool {
141166 - Parameters:
142167 - sourceFile: The source file URL
143168 - destinationFile: The destination file URL
169+ - skipCopy: Wether to skip copying file to desitnation
144170 - Throws: Any errors that occur during file operations
145171 */
146- func migrateFile( from sourceFile: URL , to destinationFile: URL ) throws {
147- if !FileManager. default. fileExists ( atPath: destinationFile. path) {
172+ func migrateFile( from sourceFile: URL , to destinationFile: URL , skipCopy : Bool ) throws {
173+ if !skipCopy , ! FileManager. default. fileExists ( atPath: destinationFile. path) {
148174 try FileManager . default. copyItem ( at: sourceFile, to: destinationFile)
149175 }
150176 // Always delete source file after processing (whether copied or skipped)
@@ -157,8 +183,9 @@ func migrateFile(from sourceFile: URL, to destinationFile: URL) throws {
157183 - Parameters:
158184 - sourceDir: The source directory URL
159185 - destinationDir: The destination directory URL
186+ - skipKeys: Array of storage keys that should be skipped during migration
160187 */
161- func migrateDirectoryContents( from sourceDir: URL , to destinationDir: URL ) {
188+ func migrateDirectoryContents( from sourceDir: URL , to destinationDir: URL , skipKeys : [ PostHogStorage . StorageKey ] = [ ] ) {
162189 do {
163190 // Create destination directory if it doesn't exist (we need to call this here again as the function is recursive)
164191 createDirectoryAtURLIfNeeded ( url: destinationDir)
@@ -174,13 +201,16 @@ func migrateDirectoryContents(from sourceDir: URL, to destinationDir: URL) {
174201 if FileManager . default. fileExists ( atPath: item. path, isDirectory: & isDirectory) {
175202 if isDirectory. boolValue {
176203 // Recursively migrate subdirectory (preserving the folder structure)
177- migrateDirectoryContents ( from: item, to: destinationItem)
204+ migrateDirectoryContents ( from: item, to: destinationItem, skipKeys : skipKeys )
178205 // Remove empty directory after migration
179206 removeIfEmpty ( item)
180207 } else {
208+ let fileName = item. lastPathComponent
209+ let shouldSkip = skipKeys. contains ( where: { $0. rawValue == fileName } )
210+
181211 // Migrate file
182212 do {
183- try migrateFile ( from: item, to: destinationItem)
213+ try migrateFile ( from: item, to: destinationItem, skipCopy : shouldSkip )
184214 } catch {
185215 hedgeLog ( " Failed to migrate file from \( item. path) to \( destinationItem. path) : \( error) " )
186216 }
0 commit comments