From e01be483da34f03e494a371f23917762ca7ef892 Mon Sep 17 00:00:00 2001
From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
Date: Thu, 9 Jun 2022 17:29:58 +0100
Subject: [PATCH] file provider service is working
---
apps/ios/MyService/Info.plist | 11 -
.../ios/MyService/MyService-Bridging-Header.h | 4 -
apps/ios/MyService/MyService.h | 14 --
apps/ios/MyService/MyService.m | 19 --
apps/ios/MyService/MyService.swift | 16 --
apps/ios/MyService/MyServiceDelegate.swift | 20 --
apps/ios/MyService/MyServiceProtocol.h | 36 ---
apps/ios/MyService/MyServiceProtocol.swift | 14 --
apps/ios/MyService/main.m | 49 ----
apps/ios/MyService/main.swift | 16 --
apps/ios/Shared/FPService.swift | 13 +-
apps/ios/Shared/SimpleXApp.swift | 82 +++---
.../ios/SimpleX NSE/NotificationService.swift | 73 ++++++
.../FileProviderEnumerator.swift | 1 +
.../FileProviderExtension.swift | 23 +-
.../SimpleX Service/FileProviderItem.swift | 1 +
.../SimpleX Service/SimpleXFPService.swift | 80 +++---
apps/ios/SimpleX.xcodeproj/project.pbxproj | 236 +++++++++++-------
.../SimpleXChatAPI.docc/SimpleXChatAPI.md | 13 +
apps/ios/SimpleXChatAPI/SimpleXChatAPI.h | 19 ++
.../ServiceProtocol.swift | 20 ++
21 files changed, 370 insertions(+), 390 deletions(-)
delete mode 100644 apps/ios/MyService/Info.plist
delete mode 100644 apps/ios/MyService/MyService-Bridging-Header.h
delete mode 100644 apps/ios/MyService/MyService.h
delete mode 100644 apps/ios/MyService/MyService.m
delete mode 100644 apps/ios/MyService/MyService.swift
delete mode 100644 apps/ios/MyService/MyServiceDelegate.swift
delete mode 100644 apps/ios/MyService/MyServiceProtocol.h
delete mode 100644 apps/ios/MyService/MyServiceProtocol.swift
delete mode 100644 apps/ios/MyService/main.m
delete mode 100644 apps/ios/MyService/main.swift
create mode 100755 apps/ios/SimpleXChatAPI/SimpleXChatAPI.docc/SimpleXChatAPI.md
create mode 100644 apps/ios/SimpleXChatAPI/SimpleXChatAPI.h
create mode 100644 apps/ios/SimpleXServiceProtocol/ServiceProtocol.swift
diff --git a/apps/ios/MyService/Info.plist b/apps/ios/MyService/Info.plist
deleted file mode 100644
index c123a5d138..0000000000
--- a/apps/ios/MyService/Info.plist
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
- XPCService
-
- ServiceType
- Application
-
-
-
diff --git a/apps/ios/MyService/MyService-Bridging-Header.h b/apps/ios/MyService/MyService-Bridging-Header.h
deleted file mode 100644
index 1b2cb5d6d0..0000000000
--- a/apps/ios/MyService/MyService-Bridging-Header.h
+++ /dev/null
@@ -1,4 +0,0 @@
-//
-// Use this file to import your target's public headers that you would like to expose to Swift.
-//
-
diff --git a/apps/ios/MyService/MyService.h b/apps/ios/MyService/MyService.h
deleted file mode 100644
index 3b7cfeca34..0000000000
--- a/apps/ios/MyService/MyService.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// MyService.h
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-#import
-#import "MyServiceProtocol.h"
-
-// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection.
-@interface MyService : NSObject
-@end
diff --git a/apps/ios/MyService/MyService.m b/apps/ios/MyService/MyService.m
deleted file mode 100644
index 41ba02945c..0000000000
--- a/apps/ios/MyService/MyService.m
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// MyService.m
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-#import "MyService.h"
-
-@implementation MyService
-
-// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol.
-- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply {
- NSString *response = [aString uppercaseString];
- reply(response);
-}
-
-@end
diff --git a/apps/ios/MyService/MyService.swift b/apps/ios/MyService/MyService.swift
deleted file mode 100644
index 4eda2a9439..0000000000
--- a/apps/ios/MyService/MyService.swift
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-// MyService.swift
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-import Foundation
-
-class MyService: NSObject, MyServiceProtocol {
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) {
- let response = string.uppercased()
- reply(response)
- }
-}
diff --git a/apps/ios/MyService/MyServiceDelegate.swift b/apps/ios/MyService/MyServiceDelegate.swift
deleted file mode 100644
index 4426ecd853..0000000000
--- a/apps/ios/MyService/MyServiceDelegate.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// MyServiceDelegate.swift
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-// MyServiceDelegate.swift
-import Foundation
-
-class MyServiceDelegate: NSObject, NSXPCListenerDelegate {
- func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
- let exportedObject = MyService()
- newConnection.exportedInterface = NSXPCInterface(with: MyServiceProtocol.self)
- newConnection.exportedObject = exportedObject
- newConnection.resume()
- return true
- }
-}
diff --git a/apps/ios/MyService/MyServiceProtocol.h b/apps/ios/MyService/MyServiceProtocol.h
deleted file mode 100644
index 91956f6a61..0000000000
--- a/apps/ios/MyService/MyServiceProtocol.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// MyServiceProtocol.h
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-#import
-
-// The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service.
-@protocol MyServiceProtocol
-
-// Replace the API of this protocol with an API appropriate to the service you are vending.
-- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply;
-
-@end
-
-/*
- To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this:
-
- _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"chat.simplex.MyService"];
- _connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyServiceProtocol)];
- [_connectionToService resume];
-
-Once you have a connection to the service, you can use it like this:
-
- [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) {
- // We have received a response. Update our text field, but do it on the main thread.
- NSLog(@"Result string was: %@", aString);
- }];
-
- And, when you are finished with the service, clean up the connection like this:
-
- [_connectionToService invalidate];
-*/
diff --git a/apps/ios/MyService/MyServiceProtocol.swift b/apps/ios/MyService/MyServiceProtocol.swift
deleted file mode 100644
index 94ab1fcada..0000000000
--- a/apps/ios/MyService/MyServiceProtocol.swift
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// MyServiceProtocol.swift
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-import Foundation
-
-@objc public protocol MyServiceProtocol {
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void)
-}
-
diff --git a/apps/ios/MyService/main.m b/apps/ios/MyService/main.m
deleted file mode 100644
index f8ee94c9cd..0000000000
--- a/apps/ios/MyService/main.m
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// main.m
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-#import
-#import "MyService.h"
-
-@interface ServiceDelegate : NSObject
-@end
-
-@implementation ServiceDelegate
-
-- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
- // This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection.
-
- // Configure the connection.
- // First, set the interface that the exported object implements.
- newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyServiceProtocol)];
-
- // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object.
- MyService *exportedObject = [MyService new];
- newConnection.exportedObject = exportedObject;
-
- // Resuming the connection allows the system to deliver more incoming messages.
- [newConnection resume];
-
- // Returning YES from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call -invalidate on the connection and return NO.
- return YES;
-}
-
-@end
-
-int main(int argc, const char *argv[])
-{
- // Create the delegate for the service.
- ServiceDelegate *delegate = [ServiceDelegate new];
-
- // Set up the one NSXPCListener for this service. It will handle all incoming connections.
- NSXPCListener *listener = [NSXPCListener serviceListener];
- listener.delegate = delegate;
-
- // Resuming the serviceListener starts this service. This method does not return.
- [listener resume];
- return 0;
-}
diff --git a/apps/ios/MyService/main.swift b/apps/ios/MyService/main.swift
deleted file mode 100644
index bae4ce0d0e..0000000000
--- a/apps/ios/MyService/main.swift
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-// main.swift
-// MyService
-//
-// Created by Evgeny on 01/06/2022.
-// Copyright © 2022 SimpleX Chat. All rights reserved.
-//
-
-import Foundation
-
-import Foundation
-
-let delegate = MyServiceDelegate()
-let listener = NSXPCListener.service()
-listener.delegate = delegate
-listener.resume()
diff --git a/apps/ios/Shared/FPService.swift b/apps/ios/Shared/FPService.swift
index 9447e5fbb4..de2dd4e690 100644
--- a/apps/ios/Shared/FPService.swift
+++ b/apps/ios/Shared/FPService.swift
@@ -8,17 +8,8 @@
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"
-//let SERVICE_PROXY_ITEM_URL = URL(string: SERVICE_PROXY_ITEM)!
-let SERVICE_PROXY_ITEM_ID = NSFileProviderItemIdentifier(SERVICE_PROXY_ITEM)
-
-@objc public protocol SimpleXFPServiceProtocol {
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void)
-}
+import SimpleXServiceProtocol
func testFPService() {
logger.debug("testFPService get services")
@@ -59,7 +50,7 @@ func testFPService() {
}
// Set the remote interface.
- connection.remoteObjectInterface = NSXPCInterface(with: SimpleXFPServiceProtocol.self)
+ connection.remoteObjectInterface = simpleXServiceInterface
// Start the connection.
connection.resume()
diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift
index 2a1f09a98d..80bdc437cf 100644
--- a/apps/ios/Shared/SimpleXApp.swift
+++ b/apps/ios/Shared/SimpleXApp.swift
@@ -11,42 +11,42 @@ import SimpleXChat
let logger = Logger()
-let machMessenger = MachMessenger(APP_MACH_PORT, callback: receivedMachMessage)
-
-func receivedMachMessage(msgId: Int32, msg: String) -> String? {
- logger.debug("MachMessenger: receivedMachMessage from FPS")
-// return "reply from App to: \(msg)"
-
- if let data = msg.data(using: .utf8) {
- logger.debug("receivedMachMessage has data")
- let endpoint = try! NSKeyedUnarchiver.unarchivedObject(ofClass: NSXPCListenerEndpoint.self, from: data)!
- logger.debug("receivedMachMessage has endpoint")
- let connection = NSXPCConnection(listenerEndpoint: endpoint)
- logger.debug("receivedMachMessage has connection")
- 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("receivedMachMessage calling service")
- proxy.upperCaseString("hello to service", withReply: { reply in
- logger.debug("receivedMachMessage reply from service \(reply)")
- })
-
- }
- return nil
-}
+//let machMessenger = MachMessenger(APP_MACH_PORT, callback: receivedMachMessage)
+//
+//func receivedMachMessage(msgId: Int32, msg: String) -> String? {
+// logger.debug("MachMessenger: receivedMachMessage from FPS")
+//// return "reply from App to: \(msg)"
+//
+// if let data = msg.data(using: .utf8) {
+// logger.debug("receivedMachMessage has data")
+// let endpoint = try! NSKeyedUnarchiver.unarchivedObject(ofClass: NSXPCListenerEndpoint.self, from: data)!
+// logger.debug("receivedMachMessage has endpoint")
+// let connection = NSXPCConnection(listenerEndpoint: endpoint)
+// logger.debug("receivedMachMessage has connection")
+// 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("receivedMachMessage calling service")
+// proxy.upperCaseString("hello to service", withReply: { reply in
+// logger.debug("receivedMachMessage reply from service \(reply)")
+// })
+//
+// }
+// return nil
+//}
@main
struct SimpleXApp: App {
@@ -64,7 +64,7 @@ struct SimpleXApp: App {
UserDefaults.standard.register(defaults: appDefaults)
BGManager.shared.register()
NtfManager.shared.registerCategories()
- machMessenger.start()
+// machMessenger.start()
// test service comms
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
@@ -85,8 +85,8 @@ struct SimpleXApp: App {
}
.onChange(of: scenePhase) { phase in
logger.debug("scenePhase \(String(describing: scenePhase))")
- let res = machMessenger.sendMessageWithReply(NSE_MACH_PORT, msg: "App scenePhase changed to \(String(describing: scenePhase))")
- logger.debug("MachMessenger \(String(describing: res), privacy: .public)")
+// let res = machMessenger.sendMessageWithReply(NSE_MACH_PORT, msg: "App scenePhase changed to \(String(describing: scenePhase))")
+// logger.debug("MachMessenger \(String(describing: res), privacy: .public)")
setAppState(phase)
switch (phase) {
case .background:
@@ -95,10 +95,10 @@ struct SimpleXApp: App {
enteredBackground = ProcessInfo.processInfo.systemUptime
}
doAuthenticate = false
- machMessenger.stop()
+// machMessenger.stop()
case .active:
doAuthenticate = authenticationExpired()
- machMessenger.start()
+// machMessenger.start()
default:
break
}
diff --git a/apps/ios/SimpleX NSE/NotificationService.swift b/apps/ios/SimpleX NSE/NotificationService.swift
index 41668e9543..03d881dea8 100644
--- a/apps/ios/SimpleX NSE/NotificationService.swift
+++ b/apps/ios/SimpleX NSE/NotificationService.swift
@@ -8,7 +8,11 @@
import UserNotifications
import OSLog
+import FileProvider
import SimpleXChat
+import SimpleXServiceProtocol
+
+import Foundation
let logger = Logger()
@@ -19,6 +23,8 @@ class NotificationService: UNNotificationServiceExtension {
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
+ testFPService()
+
logger.debug("NotificationService.didReceive")
machMessenger.start()
let res = machMessenger.sendMessageWithReply(APP_MACH_PORT, msg: "starting NSE didReceive")
@@ -145,3 +151,70 @@ func apiSetFilesFolder(filesFolder: String) throws {
throw r
}
+
+
+
+
+func testFPService() {
+ logger.debug("testFPService get services")
+ 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 {
+ logger.debug("testFPService error getting service")
+ print(error!) // <-- this prints the error I posted
+ // Handle the error here...
+ return
+ }
+
+ if let desiredService = services?[SIMPLEX_SERVICE_NAME] {
+ logger.debug("testFPService has desiredService")
+
+ // The named service is available for the item at the provided URL.
+ // To use the service, get the connection object.
+ desiredService.getFileProviderConnection(completionHandler: { (connectionOrNil, connectionError) in
+
+ guard connectionError == nil else {
+ // Handle the error here...
+ return
+ }
+
+ guard let connection = connectionOrNil else {
+ // No connection object found.
+ return
+ }
+
+ // Set the remote interface.
+ connection.remoteObjectInterface = simpleXServiceInterface
+
+ // 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, privacy: .public)")
+ })
+ })
+ }
+ }
+}
diff --git a/apps/ios/SimpleX Service/FileProviderEnumerator.swift b/apps/ios/SimpleX Service/FileProviderEnumerator.swift
index 4c2cb990d7..47882739aa 100644
--- a/apps/ios/SimpleX Service/FileProviderEnumerator.swift
+++ b/apps/ios/SimpleX Service/FileProviderEnumerator.swift
@@ -7,6 +7,7 @@
//
import FileProvider
+import SimpleXServiceProtocol
class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
diff --git a/apps/ios/SimpleX Service/FileProviderExtension.swift b/apps/ios/SimpleX Service/FileProviderExtension.swift
index 604742809e..cb5f03bfb2 100644
--- a/apps/ios/SimpleX Service/FileProviderExtension.swift
+++ b/apps/ios/SimpleX Service/FileProviderExtension.swift
@@ -9,11 +9,12 @@
import FileProvider
import OSLog
import SimpleXChat
+import SimpleXServiceProtocol
let logger = Logger()
-let serviceListener = NSXPCListener.anonymous()
-let listenerDelegate = SimpleXFPServiceDelegate()
-var machMessenger = MachMessenger(FPS_MACH_PORT, callback: receivedAppMachMessage)
+//let serviceListener = NSXPCListener.anonymous()
+//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")
@@ -26,11 +27,11 @@ class FileProviderExtension: NSFileProviderExtension {
override init() {
logger.debug("FileProviderExtension.init")
super.init()
- machMessenger.start()
- serviceListener.delegate = listenerDelegate
- Task { serviceListener.resume() }
+// machMessenger.start()
+// serviceListener.delegate = listenerDelegate
+// Task { serviceListener.resume() }
- do {
+// do {
// logger.debug("FileProviderExtension.endPointData...")
// let data = NSMutableData()
// let coder = NSXPCCoder()
@@ -41,9 +42,9 @@ class FileProviderExtension: NSFileProviderExtension {
// 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)")
- }
+// } catch let err {
+// logger.debug("FileProviderExtension.MachMessenger.sendMessage error \(String(describing: err), privacy: .public)")
+// }
let manager = NSFileProviderManager.default
@@ -66,7 +67,7 @@ class FileProviderExtension: NSFileProviderExtension {
}
}
- Task { serviceListener.resume() }
+// Task { serviceListener.resume() }
}
override func item(for identifier: NSFileProviderItemIdentifier) throws -> NSFileProviderItem {
diff --git a/apps/ios/SimpleX Service/FileProviderItem.swift b/apps/ios/SimpleX Service/FileProviderItem.swift
index 6ed18c85c5..c87f3d56ee 100644
--- a/apps/ios/SimpleX Service/FileProviderItem.swift
+++ b/apps/ios/SimpleX Service/FileProviderItem.swift
@@ -8,6 +8,7 @@
import FileProvider
import UniformTypeIdentifiers
+import SimpleXServiceProtocol
class FileProviderItem: NSObject, NSFileProviderItem {
diff --git a/apps/ios/SimpleX Service/SimpleXFPService.swift b/apps/ios/SimpleX Service/SimpleXFPService.swift
index 780d700cee..f0430f9975 100644
--- a/apps/ios/SimpleX Service/SimpleXFPService.swift
+++ b/apps/ios/SimpleX Service/SimpleXFPService.swift
@@ -8,44 +8,58 @@
import Foundation
import FileProvider
+import SimpleXServiceProtocol
-let SIMPLEX_SERVICE_NAME = NSFileProviderServiceName("group.chat.simplex.app.service")
-//let SERVICE_PROXY_ITEM = "chat.simplex.service:/123"
-//let SERVICE_PROXY_ITEM_URL = URL(string: SERVICE_PROXY_ITEM)!
-let SERVICE_PROXY_ITEM_ID = NSFileProviderItemIdentifier("123")
+extension FileProviderExtension {
+ class SimpleXFPService: NSObject, NSFileProviderServiceSource, SimpleXFPServiceProtocol, NSXPCListenerDelegate {
+ var serviceName: NSFileProviderServiceName { SIMPLEX_SERVICE_NAME }
-class SimpleXFPService: SimpleXFPServiceProtocol {
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) {
- logger.debug("FileProviderExtension SimpleXFPService.upperCaseString")
- let response = string.uppercased()
- reply(response)
+ func makeListenerEndpoint() throws -> NSXPCListenerEndpoint {
+ logger.debug("SimpleXFPService.makeListenerEndpoint")
+ let listener = NSXPCListener.anonymous()
+ listener.delegate = self
+ synchronized(self) {
+ listeners.add(listener)
+ }
+ listener.resume()
+ return listener.endpoint
+ }
+
+ func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
+ logger.debug("SimpleXFPService.listener")
+ newConnection.exportedInterface = simpleXServiceInterface
+ newConnection.exportedObject = self
+
+ synchronized(self) {
+ listeners.remove(listener)
+ }
+
+ newConnection.resume()
+ return true
+ }
+
+ weak var ext: FileProviderExtension?
+ let listeners = NSHashTable()
+
+ init(_ ext: FileProviderExtension) {
+ self.ext = ext
+ }
+
+ func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) {
+ logger.debug("FileProviderExtension SimpleXFPService.upperCaseString")
+ let response = string.uppercased()
+ reply(response)
+ }
}
-}
-@objc public protocol SimpleXFPServiceProtocol {
- func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void)
-}
-
-class SimpleXFPServiceDelegate: NSObject, NSXPCListenerDelegate {
- func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
- logger.debug("FileProviderExtension SimpleXFPServiceDelegate.listener")
- newConnection.exportedInterface = NSXPCInterface(with: SimpleXFPServiceProtocol.self)
- newConnection.exportedObject = SimpleXFPService()
- newConnection.resume()
- return true
- }
-}
-
-extension FileProviderExtension: NSFileProviderServiceSource {
override func supportedServiceSources(for itemIdentifier: NSFileProviderItemIdentifier) throws -> [NSFileProviderServiceSource] {
logger.debug("FileProviderExtension.supportedServiceSources")
- return [self]
- }
-
- var serviceName: NSFileProviderServiceName { SIMPLEX_SERVICE_NAME }
-
- func makeListenerEndpoint() throws -> NSXPCListenerEndpoint {
- logger.debug("FileProviderExtension.makeListenerEndpoint")
- return serviceListener.endpoint
+ return [SimpleXFPService(self)]
}
}
+
+public func synchronized(_ lock: AnyObject, _ closure: () throws -> T) rethrows -> T {
+ objc_sync_enter(lock)
+ defer { objc_sync_exit(lock) }
+ return try closure()
+}
diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj
index 11af64fe6c..1ce1beb3e4 100644
--- a/apps/ios/SimpleX.xcodeproj/project.pbxproj
+++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj
@@ -26,12 +26,6 @@
5C1CAA282847D7C0009E5C72 /* SimpleXFPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA272847D7C0009E5C72 /* SimpleXFPService.swift */; };
5C1CAA322847DDA0009E5C72 /* SimpleXServiceProtocol.docc in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA312847DDA0009E5C72 /* SimpleXServiceProtocol.docc */; };
5C1CAA332847DDA0009E5C72 /* SimpleXServiceProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1CAA302847DDA0009E5C72 /* SimpleXServiceProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 5C1CAA562847EBC0009E5C72 /* MyService.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA552847EBC0009E5C72 /* MyService.m */; };
- 5C1CAA582847EBC0009E5C72 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA572847EBC0009E5C72 /* main.m */; };
- 5C1CAA5F2847EC81009E5C72 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA5E2847EC81009E5C72 /* main.swift */; };
- 5C1CAA612847EC9C009E5C72 /* MyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA602847EC9C009E5C72 /* MyService.swift */; };
- 5C1CAA632847ECC6009E5C72 /* MyServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1CAA622847ECC6009E5C72 /* MyServiceDelegate.swift */; };
- 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; };
@@ -61,6 +55,14 @@
5C69D5B42852379F009B27A4 /* libHSsimplex-chat-2.2.0-3TOca6xkke4IR3YLgDepFy-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C6F2A3A28522C9A00103588 /* libHSsimplex-chat-2.2.0-3TOca6xkke4IR3YLgDepFy-ghc8.10.7.a */; };
5C69D5B52852379F009B27A4 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C6F2A3828522C9A00103588 /* libffi.a */; };
5C69D5B62852379F009B27A4 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C6F2A3928522C9A00103588 /* libgmpxx.a */; };
+ 5C69D5C028524D67009B27A4 /* SimpleXChatAPI.docc in Sources */ = {isa = PBXBuildFile; fileRef = 5C69D5BF28524D67009B27A4 /* SimpleXChatAPI.docc */; };
+ 5C69D5C128524D67009B27A4 /* SimpleXChatAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C69D5BE28524D67009B27A4 /* SimpleXChatAPI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 5C69D5C428524D67009B27A4 /* SimpleXChatAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C69D5BC28524D67009B27A4 /* SimpleXChatAPI.framework */; };
+ 5C69D5C528524D67009B27A4 /* SimpleXChatAPI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5C69D5BC28524D67009B27A4 /* SimpleXChatAPI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 5C69D5CA28525085009B27A4 /* ServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C69D5C928525085009B27A4 /* ServiceProtocol.swift */; };
+ 5C69D5CB285250FB009B27A4 /* SimpleXServiceProtocol.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C1CAA2E2847DDA0009E5C72 /* SimpleXServiceProtocol.framework */; platformFilter = ios; };
+ 5C69D5CC285250FB009B27A4 /* SimpleXServiceProtocol.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5C1CAA2E2847DDA0009E5C72 /* SimpleXServiceProtocol.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 5C69D5CF28525108009B27A4 /* SimpleXServiceProtocol.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C1CAA2E2847DDA0009E5C72 /* SimpleXServiceProtocol.framework */; platformFilter = ios; };
5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6AD81227A834E300348BD7 /* NewChatButton.swift */; };
5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A127B65FDB00BE3227 /* CIMetaView.swift */; };
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; };
@@ -146,6 +148,27 @@
remoteGlobalIDString = 5CE2BA672845308900EC33A6;
remoteInfo = SimpleXChat;
};
+ 5C69D5C228524D67009B27A4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 5C69D5BB28524D67009B27A4;
+ remoteInfo = SimpleXChatAPI;
+ };
+ 5C69D5CD285250FB009B27A4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 5C1CAA2D2847DDA0009E5C72;
+ remoteInfo = SimpleXServiceProtocol;
+ };
+ 5C69D5D128525108009B27A4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 5C1CAA2D2847DDA0009E5C72;
+ remoteInfo = SimpleXServiceProtocol;
+ };
5CA059D8279559F40002BEB4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5CA059BE279559F40002BEB4 /* Project object */;
@@ -183,7 +206,9 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
+ 5C69D5C528524D67009B27A4 /* SimpleXChatAPI.framework in Embed Frameworks */,
5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */,
+ 5C69D5CC285250FB009B27A4 /* SimpleXServiceProtocol.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -228,17 +253,6 @@
5C1CAA302847DDA0009E5C72 /* SimpleXServiceProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleXServiceProtocol.h; sourceTree = ""; };
5C1CAA312847DDA0009E5C72 /* SimpleXServiceProtocol.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SimpleXServiceProtocol.docc; sourceTree = ""; };
5C1CAA3B2847DE88009E5C72 /* FPService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPService.swift; sourceTree = ""; };
- 5C1CAA512847EBC0009E5C72 /* MyService.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = MyService.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
- 5C1CAA532847EBC0009E5C72 /* MyServiceProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyServiceProtocol.h; sourceTree = ""; };
- 5C1CAA542847EBC0009E5C72 /* MyService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyService.h; sourceTree = ""; };
- 5C1CAA552847EBC0009E5C72 /* MyService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyService.m; sourceTree = ""; };
- 5C1CAA572847EBC0009E5C72 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
- 5C1CAA592847EBC0009E5C72 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 5C1CAA5D2847EC81009E5C72 /* MyService-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MyService-Bridging-Header.h"; sourceTree = ""; };
- 5C1CAA5E2847EC81009E5C72 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
- 5C1CAA602847EC9C009E5C72 /* MyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyService.swift; sourceTree = ""; };
- 5C1CAA622847ECC6009E5C72 /* MyServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyServiceDelegate.swift; sourceTree = ""; };
- 5C1CAA642847ED13009E5C72 /* MyServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyServiceProtocol.swift; sourceTree = ""; };
5C2E260627A2941F00F70299 /* SimpleXAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXAPI.swift; sourceTree = ""; };
5C2E260A27A30CFA00F70299 /* ChatListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListView.swift; sourceTree = ""; };
5C2E260E27A30FDC00F70299 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = ""; };
@@ -262,6 +276,10 @@
5C5E5D3C282447AB00B0488A /* CallTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallTypes.swift; sourceTree = ""; };
5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; };
5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileImage.swift; sourceTree = ""; };
+ 5C69D5BC28524D67009B27A4 /* SimpleXChatAPI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SimpleXChatAPI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5C69D5BE28524D67009B27A4 /* SimpleXChatAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleXChatAPI.h; sourceTree = ""; };
+ 5C69D5BF28524D67009B27A4 /* SimpleXChatAPI.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SimpleXChatAPI.docc; sourceTree = ""; };
+ 5C69D5C928525085009B27A4 /* ServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceProtocol.swift; sourceTree = ""; };
5C6AD81227A834E300348BD7 /* NewChatButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatButton.swift; sourceTree = ""; };
5C6F2A3728522C9A00103588 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; };
5C6F2A3828522C9A00103588 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; };
@@ -344,6 +362,7 @@
files = (
5C1CAA172847C5C8009E5C72 /* UniformTypeIdentifiers.framework in Frameworks */,
5C1CAA6A2849119A009E5C72 /* SimpleXChat.framework in Frameworks */,
+ 5C69D5CF28525108009B27A4 /* SimpleXServiceProtocol.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -354,7 +373,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 5C1CAA4E2847EBC0009E5C72 /* Frameworks */ = {
+ 5C69D5B928524D67009B27A4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -365,6 +384,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5C69D5C428524D67009B27A4 /* SimpleXChatAPI.framework in Frameworks */,
+ 5C69D5CB285250FB009B27A4 /* SimpleXServiceProtocol.framework in Frameworks */,
5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */,
646BB38C283BEEB9001CE359 /* LocalAuthentication.framework in Frameworks */,
5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */,
@@ -433,29 +454,13 @@
5C1CAA2F2847DDA0009E5C72 /* SimpleXServiceProtocol */ = {
isa = PBXGroup;
children = (
+ 5C69D5C928525085009B27A4 /* ServiceProtocol.swift */,
5C1CAA302847DDA0009E5C72 /* SimpleXServiceProtocol.h */,
5C1CAA312847DDA0009E5C72 /* SimpleXServiceProtocol.docc */,
);
path = SimpleXServiceProtocol;
sourceTree = "";
};
- 5C1CAA522847EBC0009E5C72 /* MyService */ = {
- isa = PBXGroup;
- children = (
- 5C1CAA5E2847EC81009E5C72 /* main.swift */,
- 5C1CAA602847EC9C009E5C72 /* MyService.swift */,
- 5C1CAA622847ECC6009E5C72 /* MyServiceDelegate.swift */,
- 5C1CAA642847ED13009E5C72 /* MyServiceProtocol.swift */,
- 5C1CAA532847EBC0009E5C72 /* MyServiceProtocol.h */,
- 5C1CAA542847EBC0009E5C72 /* MyService.h */,
- 5C1CAA552847EBC0009E5C72 /* MyService.m */,
- 5C1CAA572847EBC0009E5C72 /* main.m */,
- 5C1CAA592847EBC0009E5C72 /* Info.plist */,
- 5C1CAA5D2847EC81009E5C72 /* MyService-Bridging-Header.h */,
- );
- path = MyService;
- sourceTree = "";
- };
5C2E260D27A30E2400F70299 /* Views */ = {
isa = PBXGroup;
children = (
@@ -485,6 +490,15 @@
path = Chat;
sourceTree = "";
};
+ 5C69D5BD28524D67009B27A4 /* SimpleXChatAPI */ = {
+ isa = PBXGroup;
+ children = (
+ 5C69D5BE28524D67009B27A4 /* SimpleXChatAPI.h */,
+ 5C69D5BF28524D67009B27A4 /* SimpleXChatAPI.docc */,
+ );
+ path = SimpleXChatAPI;
+ sourceTree = "";
+ };
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
@@ -544,12 +558,12 @@
5C422A7C27A9A6FA0097A1E1 /* SimpleX (iOS).entitlements */,
5C764E5C279C70B7000C6508 /* Libraries */,
5CA059C2279559F40002BEB4 /* Shared */,
- 5CE2BA692845308900EC33A6 /* SimpleXChat */,
5CDCAD462818589900503DA2 /* SimpleX NSE */,
5C1CAA182847C5C8009E5C72 /* SimpleX Service */,
5C1CAA2F2847DDA0009E5C72 /* SimpleXServiceProtocol */,
+ 5C69D5BD28524D67009B27A4 /* SimpleXChatAPI */,
+ 5CE2BA692845308900EC33A6 /* SimpleXChat */,
5CA059DA279559F40002BEB4 /* Tests iOS */,
- 5C1CAA522847EBC0009E5C72 /* MyService */,
5CA059CB279559F40002BEB4 /* Products */,
5C764E7A279C71D4000C6508 /* Frameworks */,
);
@@ -579,7 +593,7 @@
5CE2BA682845308900EC33A6 /* SimpleXChat.framework */,
5C1CAA152847C5C8009E5C72 /* SimpleX Service.appex */,
5C1CAA2E2847DDA0009E5C72 /* SimpleXServiceProtocol.framework */,
- 5C1CAA512847EBC0009E5C72 /* MyService.xpc */,
+ 5C69D5BC28524D67009B27A4 /* SimpleXChatAPI.framework */,
);
name = Products;
sourceTree = "";
@@ -719,6 +733,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 5C69D5B728524D67009B27A4 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5C69D5C128524D67009B27A4 /* SimpleXChatAPI.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
5CE2BA632845308900EC33A6 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
@@ -743,6 +765,7 @@
);
dependencies = (
5C1CAA6D2849119A009E5C72 /* PBXTargetDependency */,
+ 5C69D5D228525108009B27A4 /* PBXTargetDependency */,
);
name = "SimpleX Service";
productName = "SimpleX Service";
@@ -767,22 +790,23 @@
productReference = 5C1CAA2E2847DDA0009E5C72 /* SimpleXServiceProtocol.framework */;
productType = "com.apple.product-type.framework";
};
- 5C1CAA502847EBC0009E5C72 /* MyService */ = {
+ 5C69D5BB28524D67009B27A4 /* SimpleXChatAPI */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 5C1CAA5A2847EBC0009E5C72 /* Build configuration list for PBXNativeTarget "MyService" */;
+ buildConfigurationList = 5C69D5C628524D67009B27A4 /* Build configuration list for PBXNativeTarget "SimpleXChatAPI" */;
buildPhases = (
- 5C1CAA4D2847EBC0009E5C72 /* Sources */,
- 5C1CAA4E2847EBC0009E5C72 /* Frameworks */,
- 5C1CAA4F2847EBC0009E5C72 /* Resources */,
+ 5C69D5B728524D67009B27A4 /* Headers */,
+ 5C69D5B828524D67009B27A4 /* Sources */,
+ 5C69D5B928524D67009B27A4 /* Frameworks */,
+ 5C69D5BA28524D67009B27A4 /* Resources */,
);
buildRules = (
);
dependencies = (
);
- name = MyService;
- productName = MyService;
- productReference = 5C1CAA512847EBC0009E5C72 /* MyService.xpc */;
- productType = "com.apple.product-type.xpc-service";
+ name = SimpleXChatAPI;
+ productName = SimpleXChatAPI;
+ productReference = 5C69D5BC28524D67009B27A4 /* SimpleXChatAPI.framework */;
+ productType = "com.apple.product-type.framework";
};
5CA059C9279559F40002BEB4 /* SimpleX (iOS) */ = {
isa = PBXNativeTarget;
@@ -800,6 +824,8 @@
5CE2BA6F2845308900EC33A6 /* PBXTargetDependency */,
5CE2BA9F284555F500EC33A6 /* PBXTargetDependency */,
5C1CAA692848168A009E5C72 /* PBXTargetDependency */,
+ 5C69D5C328524D67009B27A4 /* PBXTargetDependency */,
+ 5C69D5CE285250FB009B27A4 /* PBXTargetDependency */,
);
name = "SimpleX (iOS)";
packageProductDependencies = (
@@ -880,9 +906,8 @@
5C1CAA2D2847DDA0009E5C72 = {
CreatedOnToolsVersion = 13.3;
};
- 5C1CAA502847EBC0009E5C72 = {
+ 5C69D5BB28524D67009B27A4 = {
CreatedOnToolsVersion = 13.3;
- LastSwiftMigration = 1330;
};
5CA059C9279559F40002BEB4 = {
CreatedOnToolsVersion = 13.2.1;
@@ -920,11 +945,11 @@
targets = (
5CA059C9279559F40002BEB4 /* SimpleX (iOS) */,
5CA059D6279559F40002BEB4 /* Tests iOS */,
- 5CE2BA672845308900EC33A6 /* SimpleXChat */,
5CDCAD442818589900503DA2 /* SimpleX NSE */,
5C1CAA142847C5C8009E5C72 /* SimpleX Service */,
5C1CAA2D2847DDA0009E5C72 /* SimpleXServiceProtocol */,
- 5C1CAA502847EBC0009E5C72 /* MyService */,
+ 5C69D5BB28524D67009B27A4 /* SimpleXChatAPI */,
+ 5CE2BA672845308900EC33A6 /* SimpleXChat */,
);
};
/* End PBXProject section */
@@ -944,7 +969,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 5C1CAA4F2847EBC0009E5C72 /* Resources */ = {
+ 5C69D5BA28524D67009B27A4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1005,19 +1030,15 @@
buildActionMask = 2147483647;
files = (
5C1CAA322847DDA0009E5C72 /* SimpleXServiceProtocol.docc in Sources */,
+ 5C69D5CA28525085009B27A4 /* ServiceProtocol.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- 5C1CAA4D2847EBC0009E5C72 /* Sources */ = {
+ 5C69D5B828524D67009B27A4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 5C1CAA582847EBC0009E5C72 /* main.m in Sources */,
- 5C1CAA652847ED13009E5C72 /* MyServiceProtocol.swift in Sources */,
- 5C1CAA632847ECC6009E5C72 /* MyServiceDelegate.swift in Sources */,
- 5C1CAA612847EC9C009E5C72 /* MyService.swift in Sources */,
- 5C1CAA562847EBC0009E5C72 /* MyService.m in Sources */,
- 5C1CAA5F2847EC81009E5C72 /* main.swift in Sources */,
+ 5C69D5C028524D67009B27A4 /* SimpleXChatAPI.docc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1148,6 +1169,23 @@
target = 5CE2BA672845308900EC33A6 /* SimpleXChat */;
targetProxy = 5C1CAA6C2849119A009E5C72 /* PBXContainerItemProxy */;
};
+ 5C69D5C328524D67009B27A4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 5C69D5BB28524D67009B27A4 /* SimpleXChatAPI */;
+ targetProxy = 5C69D5C228524D67009B27A4 /* PBXContainerItemProxy */;
+ };
+ 5C69D5CE285250FB009B27A4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ platformFilter = ios;
+ target = 5C1CAA2D2847DDA0009E5C72 /* SimpleXServiceProtocol */;
+ targetProxy = 5C69D5CD285250FB009B27A4 /* PBXContainerItemProxy */;
+ };
+ 5C69D5D228525108009B27A4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ platformFilter = ios;
+ target = 5C1CAA2D2847DDA0009E5C72 /* SimpleXServiceProtocol */;
+ targetProxy = 5C69D5D128525108009B27A4 /* PBXContainerItemProxy */;
+ };
5CA059D9279559F40002BEB4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 5CA059C9279559F40002BEB4 /* SimpleX (iOS) */;
@@ -1213,7 +1251,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "SimpleX Service/SimpleX_Service.entitlements";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 51;
+ CURRENT_PROJECT_VERSION = 53;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
@@ -1226,14 +1264,14 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 2.2;
+ MARKETING_VERSION = 2.2.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-Service";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
};
@@ -1242,7 +1280,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "SimpleX Service/SimpleX_Service.entitlements";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 51;
+ CURRENT_PROJECT_VERSION = 53;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
@@ -1255,14 +1293,14 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 2.2;
+ MARKETING_VERSION = 2.2.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-Service";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -1336,64 +1374,72 @@
};
name = Release;
};
- 5C1CAA5B2847EBC0009E5C72 /* Debug */ = {
+ 5C69D5C728524D67009B27A4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ENABLE_MODULES = YES;
+ APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_STYLE = Automatic;
- COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
- ENABLE_HARDENED_RUNTIME = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
GENERATE_INFOPLIST_FILE = YES;
- INFOPLIST_FILE = MyService/Info.plist;
- INFOPLIST_KEY_CFBundleDisplayName = MyService;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 SimpleX Chat. All rights reserved.";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
- "@executable_path/../Frameworks",
- "@loader_path/../Frameworks",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
);
- MACOSX_DEPLOYMENT_TARGET = 12.2;
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.MyService;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SDKROOT = macosx;
+ PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChatAPI;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
- SWIFT_OBJC_BRIDGING_HEADER = "MyService/MyService-Bridging-Header.h";
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
};
name = Debug;
};
- 5C1CAA5C2847EBC0009E5C72 /* Release */ = {
+ 5C69D5C828524D67009B27A4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ENABLE_MODULES = YES;
+ APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_STYLE = Automatic;
- COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
- ENABLE_HARDENED_RUNTIME = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
GENERATE_INFOPLIST_FILE = YES;
- INFOPLIST_FILE = MyService/Info.plist;
- INFOPLIST_KEY_CFBundleDisplayName = MyService;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 SimpleX Chat. All rights reserved.";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
- "@executable_path/../Frameworks",
- "@loader_path/../Frameworks",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
);
- MACOSX_DEPLOYMENT_TARGET = 12.2;
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.MyService;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SDKROOT = macosx;
+ PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChatAPI;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
- SWIFT_OBJC_BRIDGING_HEADER = "MyService/MyService-Bridging-Header.h";
SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
};
name = Release;
};
@@ -1838,11 +1884,11 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 5C1CAA5A2847EBC0009E5C72 /* Build configuration list for PBXNativeTarget "MyService" */ = {
+ 5C69D5C628524D67009B27A4 /* Build configuration list for PBXNativeTarget "SimpleXChatAPI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 5C1CAA5B2847EBC0009E5C72 /* Debug */,
- 5C1CAA5C2847EBC0009E5C72 /* Release */,
+ 5C69D5C728524D67009B27A4 /* Debug */,
+ 5C69D5C828524D67009B27A4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/apps/ios/SimpleXChatAPI/SimpleXChatAPI.docc/SimpleXChatAPI.md b/apps/ios/SimpleXChatAPI/SimpleXChatAPI.docc/SimpleXChatAPI.md
new file mode 100755
index 0000000000..e94a5f23b5
--- /dev/null
+++ b/apps/ios/SimpleXChatAPI/SimpleXChatAPI.docc/SimpleXChatAPI.md
@@ -0,0 +1,13 @@
+# ``SimpleXChatAPI``
+
+Summary
+
+## Overview
+
+Text
+
+## Topics
+
+### Group
+
+- ``Symbol``
\ No newline at end of file
diff --git a/apps/ios/SimpleXChatAPI/SimpleXChatAPI.h b/apps/ios/SimpleXChatAPI/SimpleXChatAPI.h
new file mode 100644
index 0000000000..48e9d0988d
--- /dev/null
+++ b/apps/ios/SimpleXChatAPI/SimpleXChatAPI.h
@@ -0,0 +1,19 @@
+//
+// SimpleXChatAPI.h
+// SimpleXChatAPI
+//
+// Created by Evgeny on 09/06/2022.
+// Copyright © 2022 SimpleX Chat. All rights reserved.
+//
+
+#import
+
+//! Project version number for SimpleXChatAPI.
+FOUNDATION_EXPORT double SimpleXChatAPIVersionNumber;
+
+//! Project version string for SimpleXChatAPI.
+FOUNDATION_EXPORT const unsigned char SimpleXChatAPIVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+
+
diff --git a/apps/ios/SimpleXServiceProtocol/ServiceProtocol.swift b/apps/ios/SimpleXServiceProtocol/ServiceProtocol.swift
new file mode 100644
index 0000000000..268da04e3c
--- /dev/null
+++ b/apps/ios/SimpleXServiceProtocol/ServiceProtocol.swift
@@ -0,0 +1,20 @@
+//
+// ServiceProtocol.swift
+// SimpleXServiceProtocol
+//
+// Created by Evgeny on 09/06/2022.
+// Copyright © 2022 SimpleX Chat. All rights reserved.
+//
+
+import Foundation
+import FileProvider
+
+public let SIMPLEX_SERVICE_NAME = NSFileProviderServiceName("group.chat.simplex.app.service")
+public let SERVICE_PROXY_ITEM_ID = NSFileProviderItemIdentifier("123")
+public let simpleXServiceInterface: NSXPCInterface = {
+ NSXPCInterface(with: SimpleXFPServiceProtocol.self)
+}()
+
+@objc public protocol SimpleXFPServiceProtocol {
+ func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void)
+}