File transfer issue from iPhone to Watch after iOS 17.5 & WatchOS 10.5 update

After updating to iOS 17.5 & WatchOS 10.5, the didFinish response from WCSessionDelegate does not come when transferring files from iPhone to Watch.

It worked normally until 17.4 & 10.4.

There is no problem with checking file completion even if a didFinish response is not received, but I think Apple needs to check this issue and update.

File transfer is done using the transferFile function of WCSession. The file being transferred is a single file and its size does not exceed 30MB.

When you try to transfer Pi, the message below appears in the Xcode log section.

-[WCFileStorage persistOutgoingFileTransfer:] error serializing file transfer <WCSessionFileTransfer: 0x300155d60, session file: <WCSessionFile: 0x3001575c0, identifier: 0C8857EC-7D74-4E78-BA28-6C5526DE8949, file: /private/var/mobile/Containers/Data/Application/DD797847-DED1-42C0-989F-34CD05825007/tmp/C042D096-F12B-4B50-8792-868475DBBF47.zip, hasMetadata: YES>, transferring: YES> due to Error Domain=NSCocoaErrorDomain Code=4866 "Caught exception during archival: This object may only be encoded by an NSXPCCoder. ( 0 CoreFoundation 0x000000019b064f2c 00E76A98-210C-3CB5-930B-F236807FF24C + 540460 1 libobjc.A.dylib 0x0000000192ef6018 objc_exception_throw + 60 2 Foundation 0x0000000199fe7778 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 1419128 3 Foundation 0x0000000199ea0e14 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 81428 4 WatchConnectivity 0x000000021d055f60 1AB4DDD6-9238-3965-B744-819F2916C8CC + 126816 5 Foundation 0x0000000199ea0e14 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 81428 6 WatchConnectivity 0x000000021d0567f0 1AB4DDD6-9238-3965-B744-819F2916C8CC + 129008 7 Foundation 0x0000000199ea0e14 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 81428 8 Foundation 0x0000000199f30628 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 669224 9 WatchConnectivity 0x000000021d0583ac 1AB4DDD6-9238-3965-B744-819F2916C8CC + 136108 10 WatchConnectivity 0x000000021d04390c 1AB4DDD6-9238-3965-B744-819F2916C8CC + 51468 11 WatchConnectivity 0x000000021d046640 1AB4DDD6-9238-3965-B744-819F2916C8CC + 63040 12 Foundation 0x0000000199ea9be0 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 117728 13 Foundation 0x0000000199ea9aa0 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 117408 14 Foundation 0x0000000199ea98a0 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 116896 15 Foundation 0x0000000199ea7b40 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 109376 16 Foundation 0x0000000199f2c558 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 652632 17 Foundation 0x0000000199f2c1a4 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 651684 18 libdispatch.dylib 0x0000000105ed7764 _dispatch_block_async_invoke2 + 148 19 libdispatch.dylib 0x0000000105ec67bc _dispatch_client_callout + 20 20 libdispatch.dylib 0x0000000105ec98e0 _dispatch_continuation_pop + 676 21 libdispatch.dylib 0x0000000105ec8bb8 _dispatch_async_redirect_invoke + 680 22 libdispatch.dylib 0x0000000105edaae4 _dispatch_root_queue_drain + 404 23 libdispatch.dylib 0x0000000105edb4d8 _dispatch_worker_thread2 + 188 24 libsystem_pthread.dylib 0x00000001f7ebb8f8 _pthread_wqthread + 228 25 libsystem_pthread.dylib 0x00000001f7eb80cc start_wqthread + 8 )" UserInfo={NSDebugDescription=Caught exception during archival: This object may only be encoded by an NSXPCCoder. ( 0 CoreFoundation 0x000000019b064f2c 00E76A98-210C-3CB5-930B-F236807FF24C + 540460 1 libobjc.A.dylib 0x0000000192ef6018 objc_exception_throw + 60 2 Foundation 0x0000000199fe7778 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 1419128 3 Foundation 0x0000000199ea0e14 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 81428 4 WatchConnectivity 0x000000021d055f60 1AB4DDD6-9238-3965-B744-819F2916C8CC + 126816 5 Foundation 0x0000000199ea0e14 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 81428 6 WatchConnectivity 0x000000021d0567f0 1AB4DDD6-9238-3965-B744-819F2916C8CC + 129008 7 Foundation 0x0000000199ea0e14 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 81428 8 Foundation 0x0000000199f30628 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 669224 9 WatchConnectivity 0x000000021d0583ac 1AB4DDD6-9238-3965-B744-819F2916C8CC + 136108 10 WatchConnectivity 0x000000021d04390c 1AB4DDD6-9238-3965-B744-819F2916C8CC + 51468 11 WatchConnectivity 0x000000021d046640 1AB4DDD6-9238-3965-B744-819F2916C8CC + 63040 12 Foundation 0x0000000199ea9be0 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 117728 13 Foundation 0x0000000199ea9aa0 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 117408 14 Foundation 0x0000000199ea98a0 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 116896 15 Foundation 0x0000000199ea7b40 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 109376 16 Foundation 0x0000000199f2c558 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 652632 17 Foundation 0x0000000199f2c1a4 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 651684 18 libdispatch.dylib 0x0000000105ed7764 _dispatch_block_async_invoke2 + 148 19 libdispatch.dylib 0x0000000105ec67bc _dispatch_client_callout + 20 20 libdispatch.dylib 0x0000000105ec98e0 _dispatch_continuation_pop + 676 21 libdispatch.dylib 0x0000000105ec8bb8 _dispatch_async_redirect_invoke + 680 22 libdispatch.dylib 0x0000000105edaae4 _dispatch_root_queue_drain + 404 23 libdispatch.dylib 0x0000000105edb4d8 _dispatch_worker_thread2 + 188 24 libsystem_pthread.dylib 0x00000001f7ebb8f8 _pthread_wqthread + 228 25 libsystem_pthread.dylib 0x00000001f7eb80cc start_wqthread + 8 )}

Answered by rolf.fox@4iiii.com in 794999022

I have tried out the workaround suggested by Ziqiao Chen - using the Progress property of WCSessionFileTransfer.progress - so far in testing this has worked very well as a substitute for the session(_:didFinish:error:) callback. Seems to me that an advantage of this approach is that it happens all on the Watch side, and you don't have to rely on receiving a message from the companion app.

I followed the usage pattern exemplified in the sample project "Implementing Two-Way Communication Using Watch Connectivity" - see the FileTransferObservers class.

Thanks again, Ziqiao!

Adding my voice to the chorus here - my Watch app is showing the same symptoms of this bug, e.g. the same stack trace featuring the message "Caught exception during archival: This object may only be encoded by an NSXPCCoder".

I know my users are experiencing the issue because in my analytics reports I am seeing on the order of hundreds per day per user of incomplete file transfers from the Watch to the companion iOS app. Doubtless this is because the "func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?)" WCSessionDelegate delegate method does not get called by the system, and so the Watch app can't know that the file was transferred successfully, and doesn't delete it.

I have filed with Feedback - FB14064179.

Hoping for some guidance from Apple on this - can/will it be fixed in the next watchOS/iOS update - or do I have to provide a workaround of the type discussed by others in this thread?

Same issue here. Would be nice if it could be fixed soon :-) Just writing here to get notified on updates!

Thanks for filing the feedback reports, which are now under the investigation of the Watch Connectivity folks.

I see that WCSessionFileTransfer.progress still reflects the progress. So for the issue of session(_:didFinish:error:) not being triggered, you might be able to work around it by checking if the file transfer progress is 100% completed.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thanks for the suggestion, I will look into that.

I have tried out the workaround suggested by Ziqiao Chen - using the Progress property of WCSessionFileTransfer.progress - so far in testing this has worked very well as a substitute for the session(_:didFinish:error:) callback. Seems to me that an advantage of this approach is that it happens all on the Watch side, and you don't have to rely on receiving a message from the companion app.

I followed the usage pattern exemplified in the sample project "Implementing Two-Way Communication Using Watch Connectivity" - see the FileTransferObservers class.

Thanks again, Ziqiao!

I am facing similar issue.

My watch recording is getting published to my iPhone, but there is no acknowledgement to watch back.

func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) is not getting called.

using progress observer of WCSessionFileTransfer, it is fixed.

But no idea whether there is any fix from apple in iOS 17.6 and watch os 10.6.

Any update on whether this is planned to be fixed?

Bug still not fixed on RC version of watchOS 11 running on AW S8:

[WCFileStorage persistOutgoingFileTransfer:] error serializing file transfer <WCSessionFileTransfer: 0x14d2a8d0, session file: <WCSessionFile: 0x14dfcbd0, identifier: DCDDB467-B718-4A54-82EB-F9D96587E77D, file: /var/mobile/Containers/Data/PluginKitPlugin/0E6EF953-0A18-42AE-907E-BF786E3D8B19/Documents/blob.data, hasMetadata: NO>, transferring: YES> due to Error Domain=NSCocoaErrorDomain Code=4866 "Caught exception during archival: This object may only be encoded by an NSXPCCoder.

Thank you all for posting your successful experience with the progress observer. After implementing this, I still have several questions. I would appreciate it, when others, such as @rolf.fox@4iiii.com or Ziqiao from Apple DTS Engineer, can comment.

Still Error

With my progress observer for fractionCompleted I can track completion. But I still see the -[WCFileStorage persistOutgoingFileTransfer:] error serializing file transfer error in the Debug Console.

Do you have the same?

Compatibility

Did you completely replace session:didFinishFileTransfer:error: by the progress observer, or did you only implement the progress observer for iOS 17.5 and above?

I ask this because the docu of WCSessionFileTransfer's property progress is set to have a minimum of iOS 12.0 and watchOS 5.0. My app supports a minimum of iOS 12.0 and watchOS 4.0.

I only use WCSessionFileTransfer from iOS to send files to the Watch, so it seems that progress is then available in iOS. But this is an assumption, and I don't know whether a connected Watch with watchOS 4.0 will provide the progress back to iOS. I can't verify it, because latest Xcode cannot run Simulators lower than iOS 15.0 and watchOS 8.0.

Follow-up on my previous comment (1)

I have added an available(iOS 17.0) condition to the progress observer. In order to validate whether the existing implementation with session:didFinishFileTransfer:error: still works for older iOS versions, I created a new Simulator pair in Xcode 15.4:

  • iPhone 11 with iOS 15.5
  • Watch Series 4 with watchOS 9.4

Although the Debug Console shows all expected NSLog() from the iPhone part, where file transfer works flawlessly via session:didFinishFileTransfer:error:, the files are never received on the Watch Simulator. Method session:didReceiveFile: of WCSessionDelegate is never called, despite the fact that the iOS part successfully called session:didFinishFileTransfer:error:. ❌

Even after removing the whole fix with the progress observer for iOS 17.5/watchOS 10.5, method session:didReceiveFile: of WCSessionDelegate is never called on the Watch Simulator. ❌

On a real Watch Series 6 with watchOS 10.6.1, method session:didReceiveFile: is called successfully. ✅

I'm extremely puzzled now. I hope this is an Xcode Simulator issue.

Next step: get an old iPhone 7 (iOS 15.8.3) and Watch Series 1 up-and-running, to validate on device...

@Apple, please clarify what's going on. And explain why your developers have to continually experience deteriorating quality of your tools and software.

(1) Seriously Apple, why is it not possible to edit an existing post within an hour?

Martijn: with regards to your questions:

Error:

Yes, the -[WCFileStorage persistOutgoingFileTransfer:] exception message continues to show in the debug console - I think this will continue to be the case until Apple fixes the bug. But I don't think you need to worry about that - there seems to be no ill effects.

Compatibility:

Yes, I completely replaced the func session( session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?)_ method - just commented it out altogether. But my app runs on only watchOS 9 and newer and I'm not worried about older devices than Series 6 watches.

One more thing:

On occasion a file with size zero can be created by my Watch app - this proved to be an issue because the Progress observer appears to not be happy with zero size files - I suppose it's not a case it was designed to handle because it never signals that the copy is complete. The result was that zero size files would accumulate on the Watch and never be deleted. But as it's an obscure edge case I just added a check for file size and made sure zero size files were deleted instead of the transfer being attempted.

Wtih regards to your Simulator issues - I can't comment - perhaps because I'm working with newer Watches I've never had to resort to using the Simulator, except for testing layouts - I've always been able to get the debugger to work with the actual Watch.

Help! How can transfer img file from phone to watch?

I meet below problem:

Compress: 84317 bytes Save to: ../Application/06FB8B02-39C8-4844-B13B-D3860EE5B564/tmp/compressed_image.jpg Read file scuccess: 84317 bytes

-[WCFileStorage persistOutgoingFileTransfer:] error serializing file transfer <WCSessionFileTransfer: 0x600002123200, session file: <WCSessionFile: 0x600002120fa0, identifier: 13616C1F-7E6F-47C2-9478-EA15A88391D4, file: ../Application/06FB8B02-39C8-4844-B13B-D3860EE5B564/tmp/compressed_image.jpg, hasMetadata: NO>, transferring: YES> due to Error Domain=NSCocoaErrorDomain Code=4866 "Caught exception during archival: This object may only be encoded by an NSXPCCoder.

File transfer issue from iPhone to Watch after iOS 17.5 &amp; WatchOS 10.5 update
 
 
Q