WatchConnectivity's transferFile issue:

I want to send a file created on the watch to the iOS companion-app, using WatchConnectivity and a setup WCSession, but it does not get through to the iPhone. When I use send a message containing a Dictionary in stead, the data does get to the iPhone.

Both AppDelegate and ExtensionDelegate uses NotificationCenter to communicate with ViewController and ExtensionController. They are left out for simplicity, but the notifications work fine.

iOS' AppDelegate.swift

extension AppDelegate: WCSessionDelegate {
  // 1
  func sessionDidBecomeInactive(_ session: WCSession) {
  print("WC Session did become inactive")
  }

  // 2
  func sessionDidDeactivate(_ session: WCSession) {
  print("WC Session did deactivate")
  WCSession.default.activate()
  }

  // 3
  func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
  if let error = error {
  print("WC Session activation failed with error: \(error.localizedDescription)")
  return
  }
  print("WC Session activated with state: \(activationState.rawValue)")
  }

  func setupWatchConnectivity() {
  // 1
  if WCSession.isSupported() {
  // 2
  let session = WCSession.default
  // 3
  session.delegate = self
  // 4
  session.activate()
  }
  }

  func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) {
  print("didFinish fileTransfer")
  }

  func session(_ session: WCSession, didReceive file: WCSessionFile) {
  print("didReceive file")
  }


  func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { // 2
  print("didReceiveMessage reached")
  }
}


On the watch I have:

ExtensionDelegate.swift

extension ExtensionDelegate: WCSessionDelegate {

  func setupWatchConnectivity() {
  if WCSession.isSupported() {
  let session = WCSession.default
  session.delegate = self
  session.activate()
  }
  }

  func session(_ session: WCSession, activationDidCompleteWith
  activationState: WCSessionActivationState, error: Error?) {
  if let error = error {
  print("WC Session activation failed with error: " +
  "\(error.localizedDescription)")
  return
  }
  print("WC Session activated with state: " +
  "\(activationState.rawValue)")
  }

  func sendFileToPhone(_ notification:Notification) {
  // 1
  if WCSession.isSupported() && WCSession.default.isReachable {
  // 2
  if let fileURL = notification.object as? URL {
  print("Sending file for URL: \(fileURL.absoluteURL.absoluteString)")
  WCSession.default.transferFile(fileURL, metadata: nil) // <- if I use sendMessage here stuff works...
  }
  }
  }

  func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) {
  // handle filed transfer completion
  print("File transfer complete")
  print("Outstanding file transfers: \(WCSession.default.outstandingFileTransfers)")
  print("Has content pending: \(WCSession.default.hasContentPending)")
  }

  func session(_session: WCSession, didFinishFileTransfer fileTransfer: WCSessionFileTransfer, error: NSError?) {
  print("error: ", error as Any)
  }
}


After the file is sent from the Watch I inspect, as you see,

outstandingFileTransfers
and
hasContentPending
properties of the
WCSession
, and they indicate that the file should have been transferred, but my
:didReceive:
method of my AppDelegate extension doesn't get called. Again, when I use sendMessage, the AppDelegate's
:didReceiveMessage:
is invoked as expected.

What am I missing?


Note: I've tried to run this Apple's demo project that features the different communication methods, and I experience the same thing: transferFile does not trigger anything on counterpart.

Replies

I got the same issue with Xcode 11.3.1 (11C504) , iOS 13.3 and watchOS 6.1.1. I looks like Apple broke something, becuse everything worked fine before the update and I didn't changes any code in my app.

Same issue as well. Was working before, not it's not working any more 😟 (Xcode 11.4.1, iOS 13.4.1)

Does anybody have any solution?

I have the exact same problem.
On the Watch side, everything seems to work just fine and

session( session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?)

will be called (with no error).

But on the iPhone side

session(
session: WCSession, didReceive file: WCSessionFile)

just won't be called.
Same issue here. Most annoying.