We are having iPhone application which is communicating with apple watch application using network classes. We are using NWConnection and NWListener for peer to peer communication.
We have created UdpClient which is using bonjour service "camera.udp"
please check the code below UDPClient.swift
import Foundation
import Network
import WatchKit
protocol UDPClientDelegate {
func connectionDone()
func dataSendSuccesfully()
func socketConnectionStoped()
func receivedReplyWithDict(dict : [String : Any])
}
enum ConnectionState {
case settingUP
case started
case dataBeingSent
case disconnected
}
class UDPClient {
var count : Int = 0
var udpDelegate: UDPClientDelegate?
var connection : NWConnection?
var queue : DispatchQueue = DispatchQueue.global(qos: .userInitiated)
var serviceName : String?
var connectedState : ConnectionState = .disconnected
var dataArray : Array<Any>
static let sharedInstance: UDPClient = {
let instance = UDPClient()
return instance
}()
init(){
dataArray = Array()
}
func setupConnection(name: String){
serviceName = name
let parameters = NWParameters.udp
// Create the connection
connection = NWConnection(to: .service(name: name, type: "_camera._udp", domain: "local", interface: nil), using: parameters)
// Set the state update handler
connection?.stateUpdateHandler = { (newState) in
switch (newState){
case .ready:
print("Ready To Send")
case .failed(let error):
print("Connection State: \(error)")
case .preparing:
print("Preparing...")
case .waiting(let error):
print("Waiting: \(error)")
default:
print("def")
break
}
}
connectedState = .settingUP
setupReceive()
}
func startConnection() {
// Start the connection
if(connectedState == .settingUP){
connection?.start(queue: queue)
connectedState = .started
}
}
func stopConnection(){
sendDisconnectACK()
connection?.cancelCurrentEndpoint()
connectedState = .disconnected
connection = nil
print("Stopped")
}
//MARK:- Receive Data
func setupReceive() {
if connection != nil{
connection?.receiveMessage { (content, context, isComplete, error) in
if content != nil{
self.processReplyFromIOS(content: content!)
}
self.setupReceive()
}
}else{
return
}
}
func processReplyFromIOS(content : Data){
var receivedData = [:] as [String : Any]
do{
if let oppData = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(content){
receivedData = oppData as! [String : Any]
}
}catch let error{
print(error)
}
if receivedData["Connected"] != nil{
print("Got Connected")
self.connectedState = .dataBeingSent
}else{
}
}
//MARK:- Send Data
// Send Connection data
func sendConnectionRequest(){
			 WKInterfaceDevice.current().isBatteryMonitoringEnabled = true
	 let dic = ["ConnetionRequest":"Request","batteryLevel":watchBatteryPercentage] as [String : Any]
let dataExample: Data = NSKeyedArchiver.archivedData(withRootObject: dic)
connection?.send(content: dataExample, completion: .contentProcessed({ (error) in
if let error = error{
print("Send error \(error)")
}
}))
}
var watchBatteryPercentage:Int {
return Int(roundf(WKInterfaceDevice.current().batteryLevel * 100))
}
func sendData(dic :[String : Any]){
let data: Data = NSKeyedArchiver.archivedData(withRootObject: dic) connection?.send(content: data, completion: .idempotent)
}
// Send Disconnection Ack
func sendDisconnectACK(){
let disconnectionData = ["Disconnected" : true] as [String : Any]
let dataExample: Data = NSKeyedArchiver.archivedData(withRootObject: disconnectionData)
connection?.send(content: dataExample, completion: .contentProcessed({ (error) in
if let error = error{
print("Send error \(error)")
}
}))
}
}
Post
Replies
Boosts
Views
Activity
Development OS & Xcode used :
WatchOS 7 beta 7
IOS 14 beta 7
Xcode 12 beta 5
Problem faced :
We are able to run and get the desired result when running this project in iOS 13 &
watchOS 6, But while running in the beta versions I’m getting error that “Failed to attach socket protocol.”
Console Log:
2020-08-29
18:33:52.099781+0530
dataSend Extension[562:368916] [default] lookupMainFuncAddressInMachHeader:71: Invalid Swift entry
point data
2020-08-29
18:33:52.100530+0530
dataSend Extension[562:368916] [default] lookupMainFuncAddressInMachHeader:77: Swift entry point
addres could not be determined
.
2020-08-29
18:34:40.702492+0530
dataSend Extension[562:368916] [bgapprefresh] -[SPApplicationDelegate
prepareForSnapshotWithReason:userInfo:completion:]:3030: PrepareForSnapshot called on an application that is running in the dock or
foreground, completing immediately
2020-08-29
18:36:03.781503+0530
dataSend Extension[562:369291] [] nwendpointproxycopysynthesizedurl Endpoint type is not an
address or host, cannot synthesize URL
2020-08-29
18:36:03.781910+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.782083+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.782456+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.782623+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.788047+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.788627+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.789221+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.790063+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.790239+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
2020-08-29
18:36:03.790397+0530
dataSend Extension[562:369291] [connection] nwendpointproxymatchesexception [C1
MinderService.camera.udp.local. inprogress proxy (unsatisfied (Path was denied by NECP policy), interface: ipsec2, ipv4, ipv6)] invalid
proxy endpoint type 3
Preparing
...
Waiting: POSIXErrorCode: Network is down
2020-08-29
18:36:05.668966+0530
dataSend Extension[562:369291] [connection] nwsocketinitializesocket [C1.1:3] Data mode 0
unrecognized
2020-08-29
18:36:05.669092+0530
dataSend Extension[562:369291] [connection] nwsocketaddinputhandler [C1.1:3] Failed to initialize
socket
2020-08-29
18:36:05.669265+0530
dataSend Extension[562:369291] [connection] nwendpointflowattachprotocols [C1.1
fd74:6572:6d6e:7573:d:8ea4:c65a:3cd3.62742 in_progress socket-flow (satisfied (Path is satisfied), interface: ipsec2, scoped, ipv4,
ipv6)] Failed to attach socket protocol
Waiting: POSIXErrorCode: Network is down
Measures Taken:
Have seen the WWDC2020 video on changes in privacy settings
.
https://developer.apple.com/videos/play/wwdc2020/10110
/
inPlist for iOS:
Added Privacy - Local Network Usage Description
Bonjour Services - in array added the Service as camera.udp
Other doubts:
camera._udp is a public service right?. If we needed to make a private service for
our app do we need to register the service to IANA
This is a screenshot of the Transcript of the WWDC video that we are following . Can
you please explain if registering our own service is good for our app or if we should
continue using public services
If you want I can add test project that we have created which is also working fine on iOS 13 and watch OS 6 but not working on iOS 14 beta and watch 7 beta