trying to send service endpoint via mach message - it does not work

This commit is contained in:
Evgeny Poberezkin
2022-06-02 18:24:45 +01:00
parent af3dcc4a9a
commit b62f2acca7
5 changed files with 99 additions and 12 deletions

View File

@@ -9,6 +9,7 @@
import Foundation
import FileProvider
import SimpleX_Service
import SimpleXChat
let SIMPLEX_SERVICE_NAME = NSFileProviderServiceName("group.chat.simplex.app.service")
let SERVICE_PROXY_ITEM = "chat.simplex.service:/123"
@@ -24,8 +25,13 @@ func testFPService() {
let manager = NSFileProviderManager.default
// TODO try access file
logger.debug("testFPService NSFileProviderManager.documentStorageURL \(manager.documentStorageURL, privacy: .public)")
// let res = machMessenger.sendMessageWithReply(FPS_MACH_PORT, msg: "machMessenger before getFileProviderServicesForItem")
// print("reply 1", res)
FileManager.default.getFileProviderServicesForItem(at: URL(string: "\(manager.documentStorageURL)123")!) { (services, error) in
// let res = machMessenger.sendMessageWithReply(FPS_MACH_PORT, msg: "machMessenger after getFileProviderServicesForItem")
// print("reply 2", res)
// Check to see if an error occurred.
guard error == nil else {

View File

@@ -11,11 +11,38 @@ import SimpleXChat
let logger = Logger()
let machMessenger = MachMessenger(APP_MACH_PORT, callback: receivedNSEMachMessage)
let machMessenger = MachMessenger(APP_MACH_PORT, callback: receivedMachMessage)
func receivedNSEMachMessage(msgId: Int32, msg: String) -> String? {
logger.debug("MachMessenger: receivedNSEMachMessage \"\(msg)\" from NSE, replying")
return "reply from App to: \(msg)"
func receivedMachMessage(msgId: Int32, msg: String) -> String? {
// logger.debug("MachMessenger: receivedMachMessage \"\(msg)\" from NSE, replying")
// return "reply from App to: \(msg)"
if let data = msg.data(using: .utf8) {
let endpoint = try! NSKeyedUnarchiver.unarchivedObject(ofClass: NSXPCListenerEndpoint.self, from: data)!
let connection = NSXPCConnection(listenerEndpoint: endpoint)
connection.remoteObjectInterface = NSXPCInterface(with: SimpleXFPServiceProtocol.self)
// Start the connection.
connection.resume()
// Get the proxy object.
let rawProxy = connection.remoteObjectProxyWithErrorHandler({ (errorAccessingRemoteObject) in
// Handle the error here...
})
// Cast the proxy object to the interface's protocol.
guard let proxy = rawProxy as? SimpleXFPServiceProtocol else {
// If the interface is set up properly, this should never fail.
fatalError("*** Unable to cast \(rawProxy) to a DesiredProtocol instance ***")
}
logger.debug("testFPService calling service")
proxy.upperCaseString("hello to service", withReply: { reply in
logger.debug("testFPService reply from service \(reply)")
})
}
return nil
}
@main

View File

@@ -8,10 +8,17 @@
import FileProvider
import OSLog
import SimpleXChat
let logger = Logger()
var serviceListener = NSXPCListener.service()
var listenerDelegate = SimpleXFPServiceDelegate()
let serviceListener = NSXPCListener.service()
let listenerDelegate = SimpleXFPServiceDelegate()
var machMessenger = MachMessenger(FPS_MACH_PORT, callback: receivedAppMachMessage)
func receivedAppMachMessage(_ msgId: Int32, msg: String) -> String? {
logger.debug("MachMessenger: FileProviderExtension receivedAppMachMessage \"\(msg)\" from App, replying")
return "reply from FPS to: \(msg)"
}
class FileProviderExtension: NSFileProviderExtension {
var fileManager = FileManager()
@@ -19,6 +26,19 @@ class FileProviderExtension: NSFileProviderExtension {
override init() {
logger.debug("FileProviderExtension.init")
super.init()
machMessenger.start()
serviceListener.delegate = listenerDelegate
do {
let endPointData = try NSKeyedArchiver.archivedData(withRootObject: serviceListener.endpoint, requiringSecureCoding: true)
let err = machMessenger.sendMessage(APP_MACH_PORT, data: endPointData)
logger.debug("FileProviderExtension.MachMessenger.sendMessage with endpoint res \(String(describing: err), privacy: .public)")
// let res = machMessenger.sendMessageWithReply(APP_MACH_PORT, msg: "machMessenger in FileProviderExtension")
// logger.debug("FileProviderExtension MachMessenger app reply \(String(describing: res), privacy: .public)")
} catch let err {
logger.debug("FileProviderExtension.MachMessenger.sendMessage error \(String(describing: err), privacy: .public)")
}
let manager = NSFileProviderManager.default
logger.debug("FileProviderExtension.init NSFileProviderManager \(manager.documentStorageURL, privacy: .public)")
@@ -40,7 +60,6 @@ class FileProviderExtension: NSFileProviderExtension {
}
}
serviceListener.delegate = listenerDelegate
Task { serviceListener.resume() }
}

View File

@@ -34,6 +34,7 @@
5C1CAA652847ED13009E5C72 /* MyServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA642847ED13009E5C72 /* MyServiceProtocol.swift */; };
5C1CAA662847F5BD009E5C72 /* FPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA3B2847DE88009E5C72 /* FPService.swift */; };
5C1CAA672848168A009E5C72 /* SimpleX Service.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5C1CAA152847C5C8009E5C72 /* SimpleX Service.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
5C1CAA6A2849119A009E5C72 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; platformFilter = ios; };
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260627A2941F00F70299 /* SimpleXAPI.swift */; };
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260A27A30CFA00F70299 /* ChatListView.swift */; };
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260E27A30FDC00F70299 /* ChatView.swift */; };
@@ -138,6 +139,13 @@
remoteGlobalIDString = 5C1CAA142847C5C8009E5C72;
remoteInfo = "SimpleX Service";
};
5C1CAA6C2849119A009E5C72 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 5CE2BA672845308900EC33A6;
remoteInfo = SimpleXChat;
};
5CA059D8279559F40002BEB4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
@@ -337,6 +345,7 @@
buildActionMask = 2147483647;
files = (
5C1CAA172847C5C8009E5C72 /* UniformTypeIdentifiers.framework in Frameworks */,
5C1CAA6A2849119A009E5C72 /* SimpleXChat.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -737,6 +746,7 @@
buildRules = (
);
dependencies = (
5C1CAA6D2849119A009E5C72 /* PBXTargetDependency */,
);
name = "SimpleX Service";
productName = "SimpleX Service";
@@ -1136,6 +1146,12 @@
target = 5C1CAA142847C5C8009E5C72 /* SimpleX Service */;
targetProxy = 5C1CAA682848168A009E5C72 /* PBXContainerItemProxy */;
};
5C1CAA6D2849119A009E5C72 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
platformFilter = ios;
target = 5CE2BA672845308900EC33A6 /* SimpleXChat */;
targetProxy = 5C1CAA6C2849119A009E5C72 /* PBXContainerItemProxy */;
};
5CA059D9279559F40002BEB4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 5CA059C9279559F40002BEB4 /* SimpleX (iOS) */;
@@ -1203,6 +1219,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 51;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SimpleX Service/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "SimpleX Service";
@@ -1231,6 +1248,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 51;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "SimpleX Service/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "SimpleX Service";

View File

@@ -17,6 +17,8 @@ public let NSE_MACH_PORT = "\(APP_GROUP_NAME).nse" as CFString
public let APP_MACH_PORT = "\(APP_GROUP_NAME).app" as CFString
public let FPS_MACH_PORT = "\(APP_GROUP_NAME).fps" as CFString
func getGroupDefaults() -> UserDefaults? {
UserDefaults(suiteName: APP_GROUP_NAME)
}
@@ -55,6 +57,7 @@ public class MachMessenger {
case sndTimeout
case rcvTimeout
case portInvalid
case portBecameInvalid
case sendError(Int32)
case msgError
}
@@ -75,7 +78,7 @@ public class MachMessenger {
case kCFMessagePortSendTimeout: return .sndTimeout
case kCFMessagePortReceiveTimeout: return .rcvTimeout
case kCFMessagePortIsInvalid: return .portInvalid
case kCFMessagePortBecameInvalidError: return .portInvalid
case kCFMessagePortBecameInvalidError: return .portBecameInvalid
default: return .sendError(code)
}
}
@@ -104,6 +107,17 @@ public class MachMessenger {
}
}
public func sendMessage(_ remotePortName: CFString, msgId: Int32 = 0, data: Data) -> SendError? {
logger.debug("MachMessenger.sendMessage")
if let port = createRemotePort(remotePortName) {
logger.debug("MachMessenger.sendMessage: sending...")
return sendMessage(port, msgId: msgId, data: data)
} else {
logger.debug("MachMessenger.sendMessage: no remote port")
return .portInvalid
}
}
public func sendMessageWithReply(_ remotePortName: CFString, msgId: Int32 = 0, msg: String) -> Result<String?, SendError> {
logger.debug("MachMessenger.sendMessageWithReply")
if let port = createRemotePort(remotePortName) {
@@ -149,14 +163,17 @@ public class MachMessenger {
private func sendMessage(_ remotePort: CFMessagePort, msgId: Int32 = 0, msg: String) -> SendError? {
if let data = msg.data(using: .utf8) {
logger.debug("MachMessenger sendMessage")
let msgData = data as CFData
let code = CFMessagePortSendRequest(remotePort, msgId, msgData, MACH_SEND_TIMEOUT, 0, nil, nil)
logger.debug("MachMessenger sendMessage \(code)")
return MachMessenger.sendError(code)
return sendMessage(remotePort, msgId: msgId, data: data)
}
return .msgError
}
private func sendMessage(_ remotePort: CFMessagePort, msgId: Int32 = 0, data: Data) -> SendError? {
let code = CFMessagePortSendRequest(remotePort, msgId, data as CFData, MACH_SEND_TIMEOUT, 0, nil, nil)
logger.debug("MachMessenger sendMessage \(code)")
return MachMessenger.sendError(code)
}
private func sendMessageWithReply(_ remotePort: CFMessagePort, msgId: Int32 = 0, msg: String) -> Result<String?, SendError> {
if let data = msg.data(using: .utf8) {
let msgData = data as CFData