Data Transfer iPhone To Watch using SwiftUI

Connecting your Phone to your Watch to send data has never been easier! Follow this easy step-by-step guide, to discover how to pair them as well as what are the most common errors you might encounter.

For the porpouse of the article we will use the sendMessage(_:replyHandler:errorHandler:) method, which works also on the Simulator.

First of all create a project in Xcode that has both the iOS app and the Watch app

Step_01: Click Xcode then choose Create New Project...

Step_02: Then select from WatchOS segment App. If you are already running Xcode, then choose File->New->Project. Then click next.

Step_03: Now give your App name select team & also give Organization Identifier. Finally select Watch App with new Companion iOS app then click Next.

iPhone Section

Step_04: Select ContentView from iphone section & refactor it by PhoneView. Add PhoneVM swift file and write this below code in PhoneVM file:

import Foundation
import UIKit
import SwiftUI
import WatchConnectivity

class PhoneVM: NSObject, ObservableObject {
    
    private let session: WCSession
    
    init(session: WCSession = .default){
           self.session = session
           super.init()
           session.delegate = self
           session.activate()
        
        #if os(iOS)
        print("Connection provider initialized on phone")
        #endif

        #if os(watchOS)
        print("Connection provider initialized on watch")
        #endif
        
        self.connect()
        
   }
    
    func connect(){
        guard WCSession.isSupported() else {
            print("WCSession not supported")
            return
        }
        
        session.activate()
    }
    
}

extension PhoneVM: WCSessionDelegate {
    
    func send(message: [String: Any]) -> Void {
        session.sendMessage(message, replyHandler: nil) { error in
            print(error.localizedDescription)
        }
    }
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        if let error {
            print("session activation failed with error: \(error.localizedDescription)")
        }
    }
    
    #if os(iOS)
    func sessionDidBecomeInactive(_ session: WCSession) {
        session.activate()
    }
    
    func sessionDidDeactivate(_ session: WCSession) {
        session.activate()
    }
    #endif
}

Here, first of all i imported WatchConnectivity framework. Then i initialize WCSession where i tried to activate this session. When only WCSession.isSupported() is true then this session will be activated. In our PhoneVM extension we implemented WCSessionDelegate & its protocols. In send(message: [String: Any]) function i tried to sent data to watch. Here, i didn’t acceped reply, so that i sent this parameter nil. Remember that data transfer will be only Dictionaries way i means [String: Any] this way.

Step_05: In PhoneView implemented this below code:

import SwiftUI

struct PhoneView: View {
    
    var vm = PhoneVM()
    
    var body: some View {
        VStack{
            Text("Sent Data To Watch")
                .onTapGesture {
                    vm.send(message: ["iPhone":  "Hey Joynal Vai"])
                }
        }
    }
}

#Preview {
    PhoneView()
}

In PhoneView i created object of PhoneVM class. Using vm object i called send(message: [String: Any]) method & passed data to watch. When user will click “Sent Data To Watch” then this given data will be sent to watch.

Watch Section:

Step_06: Above this same way we will create WatchVM swift file & refactor ContentView to WatchView. Add this below code in WatchVM file.

import Foundation
import UIKit
import SwiftUI
import WatchConnectivity

class WatchVM: NSObject, ObservableObject {
    
    @Published var getDataFromPhone = ""
    
    private let session: WCSession
    
    init(session: WCSession = .default){
           self.session = session
           super.init()
           session.delegate = self
           session.activate()
        
        #if os(iOS)
        print("Connection provider initialized on phone")
        #endif

        #if os(watchOS)
        print("Connection provider initialized on watch")
        #endif
        
        self.connect()
        
   }
    
    func connect(){
        guard WCSession.isSupported() else {
            print("WCSession not supported")
            return
        }
        
        session.activate()
    }
    
}

extension WatchVM: WCSessionDelegate {
    
     
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        if let error {
            print("session activation failed with error: \(error.localizedDescription)")
        }
    }
    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
            if let value = message["iPhone"] as? String {
                self.getDataFromPhone = value
            }
        }

}

The same way of PhoneVM here i imported WatchConnectivity framework & activated WCSession. Only one extra method i called here named session(_ session: WCSession, didReceiveMessage message: [String : Any]). I received value Dictionary way & assign this value above declare the variable in WatchVM.

Step_07: Now it’s hight time to show data in Watch. Write this below code in WatchView:

import SwiftUI

struct WatchView: View {
    
    @StateObject private var vm = WatchVM()
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Loading Data...")
            Text(vm.getDataFromPhone)
        }
        .padding()
    }
}

#Preview {
    WatchView()
}

Here, i created object of WatchVM & get data from getDataFromPhone variable & assign it to Text() view.

Step_08: Pair your iPhone & Apple Watch & select iPhoneToWatchDT App Watch App. Run your application & you will see this output:

129 thoughts on “Data Transfer iPhone To Watch using SwiftUI

Leave a Reply

Your email address will not be published. Required fields are marked *