Per Erik Gransøe
Per Erik Gransøe

Reputation: 489

Problem with WatchConnectivity transferFile (watch -> iphone)

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.

Upvotes: 4

Views: 1308

Answers (1)

Shalugin
Shalugin

Reputation: 1204

It seems to be a bug of iOS 13/watchOS 6 simulator. I've tried to change Xcode simulators to iOS 12 and watchOS 5, how it's suggested in this thread and the issue disappeared.

Upvotes: 0

Related Questions