From fa844c48e993a4ad67b2e28bfe8f977a8ae8e159 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Tue, 31 May 2022 07:55:13 +0100 Subject: [PATCH] ios: SimpleXChat framework to be shared by app/NSE (#714) * ios: SimpleXChat framework to be shared by app/NSE * remove bridging headers from pp/NSE * embed & sign --- apps/ios/Shared/AppDelegate.swift | 1 + apps/ios/Shared/Model/ChatModel.swift | 1 + apps/ios/Shared/Model/NtfManager.swift | 1 + apps/ios/Shared/Model/Shared/CallTypes.swift | 72 ---- apps/ios/Shared/Model/SimpleXAPI.swift | 1 + .../Shared/SimpleX (iOS)-Bridging-Header.h | 11 - apps/ios/Shared/SimpleXApp.swift | 1 + .../Shared/Views/Call/ActiveCallView.swift | 1 + .../Shared/Views/Call/CallController.swift | 1 + apps/ios/Shared/Views/Call/CallManager.swift | 1 + .../Shared/Views/Call/IncomingCallView.swift | 1 + apps/ios/Shared/Views/Call/WebRTC.swift | 1 + apps/ios/Shared/Views/Call/WebRTCView.swift | 1 + .../Shared/Views/Chat/ChatInfoToolbar.swift | 1 + apps/ios/Shared/Views/Chat/ChatInfoView.swift | 1 + .../Views/Chat/ChatItem/CICallItemView.swift | 1 + .../Views/Chat/ChatItem/CIFileView.swift | 3 +- .../Views/Chat/ChatItem/CIImageView.swift | 1 + .../Views/Chat/ChatItem/CILinkView.swift | 1 + .../Views/Chat/ChatItem/CIMetaView.swift | 1 + .../Views/Chat/ChatItem/DeletedItemView.swift | 1 + .../Views/Chat/ChatItem/EmojiItemView.swift | 1 + .../Views/Chat/ChatItem/FramedItemView.swift | 1 + .../ChatItem/IntegrityErrorItemView.swift | 1 + .../Views/Chat/ChatItem/MsgContentView.swift | 1 + apps/ios/Shared/Views/Chat/ChatItemView.swift | 1 + apps/ios/Shared/Views/Chat/ChatView.swift | 1 + .../ComposeMessage/ComposeImageView.swift | 1 + .../Chat/ComposeMessage/ComposeLinkView.swift | 2 +- .../Chat/ComposeMessage/ComposeView.swift | 1 + .../Chat/ComposeMessage/ContextItemView.swift | 1 + .../Chat/ComposeMessage/SendMessageView.swift | 1 + .../Views/ChatList/ChatListNavLink.swift | 1 + .../Shared/Views/ChatList/ChatListView.swift | 1 + .../Views/ChatList/ChatPreviewView.swift | 1 + .../ChatList/ContactConnectionView.swift | 1 + .../Views/ChatList/ContactRequestView.swift | 1 + .../Shared/Views/Helpers/ChatInfoImage.swift | 1 + .../Shared/Views/Helpers/ProfileImage.swift | 1 + .../Shared/Views/NewChat/NewChatButton.swift | 1 + .../Views/Onboarding/CreateProfile.swift | 1 + .../Views/Onboarding/MakeConnection.swift | 1 + apps/ios/Shared/Views/TerminalView.swift | 1 + .../Views/UserSettings/SMPServers.swift | 1 + .../Views/UserSettings/SettingsView.swift | 1 + .../Views/UserSettings/UserProfile.swift | 1 + apps/ios/Shared/dummy.m | 23 -- .../ios/SimpleX NSE/NotificationService.swift | 10 +- apps/ios/SimpleX.xcodeproj/project.pbxproj | 368 ++++++++++++++---- .../Model/Shared => SimpleXChat}/API.swift | 8 +- .../Shared => SimpleXChat}/APITypes.swift | 40 +- apps/ios/SimpleXChat/CallTypes.swift | 99 +++++ .../Shared => SimpleXChat}/ChatTypes.swift | 351 +++++++++-------- .../{Shared => SimpleXChat}/FileUtils.swift | 28 +- .../GroupDefaults.swift | 12 +- .../Model/Shared => SimpleXChat}/JSON.swift | 4 +- .../Notifications.swift | 24 +- .../SimpleX.h} | 11 +- .../SimpleXChat.docc/SimpleXChat.md | 13 + apps/ios/SimpleXChat/SimpleXChat.h | 17 + apps/ios/{SimpleX NSE => SimpleXChat}/dummy.m | 4 +- 61 files changed, 733 insertions(+), 409 deletions(-) delete mode 100644 apps/ios/Shared/Model/Shared/CallTypes.swift delete mode 100644 apps/ios/Shared/SimpleX (iOS)-Bridging-Header.h delete mode 100644 apps/ios/Shared/dummy.m rename apps/ios/{Shared/Model/Shared => SimpleXChat}/API.swift (88%) rename apps/ios/{Shared/Model/Shared => SimpleXChat}/APITypes.swift (96%) create mode 100644 apps/ios/SimpleXChat/CallTypes.swift rename apps/ios/{Shared/Model/Shared => SimpleXChat}/ChatTypes.swift (71%) rename apps/ios/{Shared => SimpleXChat}/FileUtils.swift (87%) rename apps/ios/{Shared/Model/Shared => SimpleXChat}/GroupDefaults.swift (54%) rename apps/ios/{Shared/Model/Shared => SimpleXChat}/JSON.swift (92%) rename apps/ios/{Shared/Model/Shared => SimpleXChat}/Notifications.swift (76%) rename apps/ios/{SimpleX NSE/SimpleX NSE-Bridging-Header.h => SimpleXChat/SimpleX.h} (54%) create mode 100755 apps/ios/SimpleXChat/SimpleXChat.docc/SimpleXChat.md create mode 100644 apps/ios/SimpleXChat/SimpleXChat.h rename apps/ios/{SimpleX NSE => SimpleXChat}/dummy.m (89%) diff --git a/apps/ios/Shared/AppDelegate.swift b/apps/ios/Shared/AppDelegate.swift index b3cf044614..ee981ffbba 100644 --- a/apps/ios/Shared/AppDelegate.swift +++ b/apps/ios/Shared/AppDelegate.swift @@ -8,6 +8,7 @@ import Foundation import UIKit +import SimpleXChat class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 4d4ae6ad91..0696b0b6e9 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -10,6 +10,7 @@ import Foundation import Combine import SwiftUI import WebKit +import SimpleXChat final class ChatModel: ObservableObject { @Published var onboardingStage: OnboardingStage? diff --git a/apps/ios/Shared/Model/NtfManager.swift b/apps/ios/Shared/Model/NtfManager.swift index 146075ded4..8a189ef726 100644 --- a/apps/ios/Shared/Model/NtfManager.swift +++ b/apps/ios/Shared/Model/NtfManager.swift @@ -9,6 +9,7 @@ import Foundation import UserNotifications import UIKit +import SimpleXChat let ntfActionAcceptContact = "NTF_ACT_ACCEPT_CONTACT" let ntfActionAcceptCall = "NTF_ACT_ACCEPT_CALL" diff --git a/apps/ios/Shared/Model/Shared/CallTypes.swift b/apps/ios/Shared/Model/Shared/CallTypes.swift deleted file mode 100644 index acb14f2199..0000000000 --- a/apps/ios/Shared/Model/Shared/CallTypes.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// CallTypes.swift -// SimpleX (iOS) -// -// Created by Evgeny on 05/05/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import Foundation -import SwiftUI - -struct WebRTCCallOffer: Encodable { - var callType: CallType - var rtcSession: WebRTCSession -} - -struct WebRTCSession: Codable { - var rtcSession: String - var rtcIceCandidates: String -} - -struct WebRTCExtraInfo: Codable { - var rtcIceCandidates: String -} - -struct CallInvitation { - var contact: Contact - var callkitUUID: UUID? - var peerMedia: CallMediaType - var sharedKey: String? - var callTs: Date - var callTypeText: LocalizedStringKey { - get { - switch peerMedia { - case .video: return sharedKey == nil ? "video call (not e2e encrypted)" : "**e2e encrypted** video call" - case .audio: return sharedKey == nil ? "audio call (not e2e encrypted)" : "**e2e encrypted** audio call" - } - } - } - - static let sampleData = CallInvitation( - contact: Contact.sampleData, - peerMedia: .audio, - callTs: .now - ) -} - -struct CallType: Codable { - var media: CallMediaType - var capabilities: CallCapabilities -} - -enum CallMediaType: String, Codable, Equatable { - case video = "video" - case audio = "audio" -} - -enum VideoCamera: String, Codable, Equatable { - case user = "user" - case environment = "environment" -} - -struct CallCapabilities: Codable, Equatable { - var encryption: Bool -} - -enum WebRTCCallStatus: String, Encodable { - case connected = "connected" - case connecting = "connecting" - case disconnected = "disconnected" - case failed = "failed" -} diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index e44e40ec5e..530c5735c9 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -12,6 +12,7 @@ import Dispatch import BackgroundTasks import SwiftUI import CallKit +import SimpleXChat private var chatController: chat_ctrl? diff --git a/apps/ios/Shared/SimpleX (iOS)-Bridging-Header.h b/apps/ios/Shared/SimpleX (iOS)-Bridging-Header.h deleted file mode 100644 index bc28b42d38..0000000000 --- a/apps/ios/Shared/SimpleX (iOS)-Bridging-Header.h +++ /dev/null @@ -1,11 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - -extern void hs_init(int argc, char **argv[]); - -typedef void* chat_ctrl; - -extern chat_ctrl chat_init(char *path); -extern char *chat_send_cmd(chat_ctrl ctl, char *cmd); -extern char *chat_recv_msg(chat_ctrl ctl); diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift index e1a54748b3..26ec3490ca 100644 --- a/apps/ios/Shared/SimpleXApp.swift +++ b/apps/ios/Shared/SimpleXApp.swift @@ -7,6 +7,7 @@ import SwiftUI import OSLog +import SimpleXChat let logger = Logger() diff --git a/apps/ios/Shared/Views/Call/ActiveCallView.swift b/apps/ios/Shared/Views/Call/ActiveCallView.swift index f61105997c..ad90ecf84d 100644 --- a/apps/ios/Shared/Views/Call/ActiveCallView.swift +++ b/apps/ios/Shared/Views/Call/ActiveCallView.swift @@ -8,6 +8,7 @@ import SwiftUI import WebKit +import SimpleXChat struct ActiveCallView: View { @EnvironmentObject var m: ChatModel diff --git a/apps/ios/Shared/Views/Call/CallController.swift b/apps/ios/Shared/Views/Call/CallController.swift index ff8339b9b2..57af8acca2 100644 --- a/apps/ios/Shared/Views/Call/CallController.swift +++ b/apps/ios/Shared/Views/Call/CallController.swift @@ -9,6 +9,7 @@ import Foundation import CallKit import AVFoundation +import SimpleXChat class CallController: NSObject, CXProviderDelegate, ObservableObject { static let useCallKit = false diff --git a/apps/ios/Shared/Views/Call/CallManager.swift b/apps/ios/Shared/Views/Call/CallManager.swift index 5d0f5af0c6..493a3a1d64 100644 --- a/apps/ios/Shared/Views/Call/CallManager.swift +++ b/apps/ios/Shared/Views/Call/CallManager.swift @@ -7,6 +7,7 @@ // import Foundation +import SimpleXChat class CallManager { func newOutgoingCall(_ contact: Contact, _ media: CallMediaType) -> UUID { diff --git a/apps/ios/Shared/Views/Call/IncomingCallView.swift b/apps/ios/Shared/Views/Call/IncomingCallView.swift index 089ffea5f5..45651b89b1 100644 --- a/apps/ios/Shared/Views/Call/IncomingCallView.swift +++ b/apps/ios/Shared/Views/Call/IncomingCallView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct IncomingCallView: View { @EnvironmentObject var m: ChatModel diff --git a/apps/ios/Shared/Views/Call/WebRTC.swift b/apps/ios/Shared/Views/Call/WebRTC.swift index 0850c0f6bb..7e63f4f499 100644 --- a/apps/ios/Shared/Views/Call/WebRTC.swift +++ b/apps/ios/Shared/Views/Call/WebRTC.swift @@ -8,6 +8,7 @@ import Foundation import SwiftUI +import SimpleXChat class Call: ObservableObject, Equatable { static func == (lhs: Call, rhs: Call) -> Bool { diff --git a/apps/ios/Shared/Views/Call/WebRTCView.swift b/apps/ios/Shared/Views/Call/WebRTCView.swift index 93a61c3f4d..ab48d93a39 100644 --- a/apps/ios/Shared/Views/Call/WebRTCView.swift +++ b/apps/ios/Shared/Views/Call/WebRTCView.swift @@ -8,6 +8,7 @@ import SwiftUI import WebKit +import SimpleXChat class WebRTCCoordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate { var rtcWebView: Binding diff --git a/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift b/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift index 774e8aa1f7..6e3fcfd96d 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat private let chatImageColorLight = Color(red: 0.9, green: 0.9, blue: 0.9) private let chatImageColorDark = Color(red: 0.2, green: 0.2, blue: 0.2 ) diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index b7bd7ef587..fc82d543b6 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ChatInfoView: View { @EnvironmentObject var chatModel: ChatModel diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift index 6b3498900b..a2204cb9b0 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct CICallItemView: View { @EnvironmentObject var m: ChatModel diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift index a7a7119c74..31b90e2ee3 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct CIFileView: View { @Environment(\.colorScheme) var colorScheme @@ -133,7 +134,7 @@ struct CIFileView: View { struct CIFileView_Previews: PreviewProvider { static var previews: some View { - let sentFile = ChatItem( + let sentFile: ChatItem = ChatItem( chatDir: .directSnd, meta: CIMeta.getSample(1, .now, "", .sndSent, false, true, false), content: .sndMsgContent(msgContent: .file("")), diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift index 7b8d2efdfd..9c131cc1c9 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct CIImageView: View { @Environment(\.colorScheme) var colorScheme diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift index a2a4ecedeb..4c12c7312a 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct CILinkView: View { @Environment(\.colorScheme) var colorScheme diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift index 390281c34a..b6de98d816 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct CIMetaView: View { var chatItem: ChatItem diff --git a/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift index 210a4dfd2d..4ac47188ce 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct DeletedItemView: View { var chatItem: ChatItem diff --git a/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift index 260e6e9fe6..e45b5bd183 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct EmojiItemView: View { var chatItem: ChatItem diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index e720ab7416..ddaf6d1d28 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat let sentColorLight = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.12) let sentColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.17) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift index 3a75789210..7a4fa46822 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct IntegrityErrorItemView: View { var chatItem: ChatItem diff --git a/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift b/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift index b0b9928c98..6707f8bde2 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat private let uiLinkColor = UIColor(red: 0, green: 0.533, blue: 1, alpha: 1) private let linkColor = Color(uiColor: uiLinkColor) diff --git a/apps/ios/Shared/Views/Chat/ChatItemView.swift b/apps/ios/Shared/Views/Chat/ChatItemView.swift index d826856953..62edc343ac 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ChatItemView: View { var chatInfo: ChatInfo diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 48d581d2c8..801177e472 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat private let memberImageSize: CGFloat = 34 diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift index c23de72229..3e65600ce5 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ComposeImageView: View { @Environment(\.colorScheme) var colorScheme diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift index 7b24a06f82..335755c00f 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift @@ -8,7 +8,7 @@ import SwiftUI import LinkPresentation - +import SimpleXChat func getLinkPreview(url: URL, cb: @escaping (LinkPreview?) -> Void) { logger.debug("getLinkMetadata: fetching URL preview") diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index 0de0ea5555..87f6c44e39 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat enum ComposePreview { case noPreview diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift index c1245633c3..b9fec65005 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ContextItemView: View { @Environment(\.colorScheme) var colorScheme diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift index 22510808ca..c5269c3804 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct SendMessageView: View { @Binding var composeState: ComposeState diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index f23d29583c..c04fdeb3ba 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ChatListNavLink: View { @EnvironmentObject var chatModel: ChatModel diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 746763583a..f0674af969 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ChatListView: View { @EnvironmentObject var chatModel: ChatModel diff --git a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift index eec99991d6..d1490eaf0c 100644 --- a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ChatPreviewView: View { @ObservedObject var chat: Chat diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift index 5243188c6b..7f9388fc57 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ContactConnectionView: View { var contactConnection: PendingContactConnection diff --git a/apps/ios/Shared/Views/ChatList/ContactRequestView.swift b/apps/ios/Shared/Views/ChatList/ContactRequestView.swift index ac873fc8f9..2edb1ad0ee 100644 --- a/apps/ios/Shared/Views/ChatList/ContactRequestView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactRequestView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ContactRequestView: View { var contactRequest: UserContactRequest diff --git a/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift b/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift index c9a2bdf166..1b344148c0 100644 --- a/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift +++ b/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ChatInfoImage: View { @ObservedObject var chat: Chat diff --git a/apps/ios/Shared/Views/Helpers/ProfileImage.swift b/apps/ios/Shared/Views/Helpers/ProfileImage.swift index f8f75d74d2..cc4f09ae3b 100644 --- a/apps/ios/Shared/Views/Helpers/ProfileImage.swift +++ b/apps/ios/Shared/Views/Helpers/ProfileImage.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct ProfileImage: View { var imageStr: String? = nil diff --git a/apps/ios/Shared/Views/NewChat/NewChatButton.swift b/apps/ios/Shared/Views/NewChat/NewChatButton.swift index ddd693c8f6..3adf3d4c27 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatButton.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatButton.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat enum NewChatAction: Identifiable { case createLink diff --git a/apps/ios/Shared/Views/Onboarding/CreateProfile.swift b/apps/ios/Shared/Views/Onboarding/CreateProfile.swift index 639a161adf..578cd85d64 100644 --- a/apps/ios/Shared/Views/Onboarding/CreateProfile.swift +++ b/apps/ios/Shared/Views/Onboarding/CreateProfile.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct CreateProfile: View { @EnvironmentObject var m: ChatModel diff --git a/apps/ios/Shared/Views/Onboarding/MakeConnection.swift b/apps/ios/Shared/Views/Onboarding/MakeConnection.swift index 3251b16535..88676535b8 100644 --- a/apps/ios/Shared/Views/Onboarding/MakeConnection.swift +++ b/apps/ios/Shared/Views/Onboarding/MakeConnection.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct MakeConnection: View { @EnvironmentObject var m: ChatModel diff --git a/apps/ios/Shared/Views/TerminalView.swift b/apps/ios/Shared/Views/TerminalView.swift index 75198c0977..6aa9e8804c 100644 --- a/apps/ios/Shared/Views/TerminalView.swift +++ b/apps/ios/Shared/Views/TerminalView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat private let terminalFont = Font.custom("Menlo", size: 16) diff --git a/apps/ios/Shared/Views/UserSettings/SMPServers.swift b/apps/ios/Shared/Views/UserSettings/SMPServers.swift index 35909320d6..07913c59ac 100644 --- a/apps/ios/Shared/Views/UserSettings/SMPServers.swift +++ b/apps/ios/Shared/Views/UserSettings/SMPServers.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat private let serversFont = Font.custom("Menlo", size: 14) diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index 0e5f46aeda..017360e30c 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat let simplexTeamURL = URL(string: "simplex:/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D")! diff --git a/apps/ios/Shared/Views/UserSettings/UserProfile.swift b/apps/ios/Shared/Views/UserSettings/UserProfile.swift index 13238971bf..52137f476c 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfile.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfile.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SimpleXChat struct UserProfile: View { @EnvironmentObject var chatModel: ChatModel diff --git a/apps/ios/Shared/dummy.m b/apps/ios/Shared/dummy.m deleted file mode 100644 index 301c29909a..0000000000 --- a/apps/ios/Shared/dummy.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// dummy.m -// SimpleX -// -// Created by Evgeny Poberezkin on 22/01/2022. -// - -#import - -#if defined(__x86_64__) && TARGET_IPHONE_SIMULATOR - -#import - -int readdir_r$INODE64(DIR *restrict dirp, struct dirent *restrict entry, - struct dirent **restrict result) { - return readdir_r(dirp, entry, result); -} - -DIR *opendir$INODE64(const char *name) { - return opendir(name); -} - -#endif diff --git a/apps/ios/SimpleX NSE/NotificationService.swift b/apps/ios/SimpleX NSE/NotificationService.swift index a615ac5b71..c0a06a1232 100644 --- a/apps/ios/SimpleX NSE/NotificationService.swift +++ b/apps/ios/SimpleX NSE/NotificationService.swift @@ -8,6 +8,7 @@ import UserNotifications import OSLog +import SimpleXChat let logger = Logger() @@ -59,7 +60,7 @@ func startChat() -> User? { try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path) return user } catch { - logger.error("NotificationService startChat error: \(responseError(error))") + logger.error("NotificationService startChat error: \(responseError(error), privacy: .public)") } } else { logger.debug("no active user") @@ -120,8 +121,11 @@ func apiGetActiveUser() -> User? { func apiStartChat() throws { let r = sendSimpleXCmd(.startChat) - if case .chatStarted = r { return } - throw r + switch r { + case .chatStarted: return + case .chatRunning: return + default: throw r + } } func apiSetFilesFolder(filesFolder: String) throws { diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 1ec19cdf6f..636ab1fec7 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -38,23 +38,17 @@ 5C55A92E283D0FDE00C4E99E /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 5C55A92D283D0FDE00C4E99E /* sounds */; }; 5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C577F7C27C83AA10006112D /* MarkdownHelp.swift */; }; 5C5E5D3B2824468B00B0488A /* ActiveCallView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3A2824468B00B0488A /* ActiveCallView.swift */; }; - 5C5E5D3D282447AB00B0488A /* CallTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3C282447AB00B0488A /* CallTypes.swift */; }; - 5C5E5D3E282447BF00B0488A /* CallTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3C282447AB00B0488A /* CallTypes.swift */; }; 5C5F2B6D27EBC3FE006A9D5F /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6C27EBC3FE006A9D5F /* ImagePicker.swift */; }; 5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5F2B6F27EBC704006A9D5F /* ProfileImage.swift */; }; 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 */; }; 5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; }; - 5C764E80279C7276000C6508 /* dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E7F279C7276000C6508 /* dummy.m */; }; - 5C764E82279C748B000C6508 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C764E7B279C71D4000C6508 /* libiconv.tbd */; }; - 5C764E83279C748B000C6508 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C764E7C279C71DB000C6508 /* libz.tbd */; }; 5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C764E88279CBCB3000C6508 /* ChatModel.swift */; }; 5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; productRef = 5C8F01CC27A6F0D8007D2C8D /* CodeScanner */; }; 5C971E1D27AEBEF600C8A3CE /* ChatInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C971E1C27AEBEF600C8A3CE /* ChatInfoView.swift */; }; 5C971E2127AEBF8300C8A3CE /* ChatInfoImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C971E2027AEBF8300C8A3CE /* ChatInfoImage.swift */; }; 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D13A2282187BB00AB8B43 /* WebRTC.swift */; }; - 5C9FD96B27A56D4D0075386C /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96A27A56D4D0075386C /* JSON.swift */; }; 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */; }; 5CA059DC279559F40002BEB4 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DB279559F40002BEB4 /* Tests_iOS.swift */; }; 5CA059DE279559F40002BEB4 /* Tests_iOSLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA059DD279559F40002BEB4 /* Tests_iOSLaunchTests.swift */; }; @@ -81,21 +75,29 @@ 5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; }; 5CCD403A27A5F9BE00368C90 /* CreateGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403927A5F9BE00368C90 /* CreateGroupView.swift */; }; 5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; }; - 5CDCAD5328186F9500503DA2 /* GroupDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */; }; - 5CDCAD5428186F9700503DA2 /* GroupDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */; }; - 5CDCAD5828187C7500503DA2 /* dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5728187C7500503DA2 /* dummy.m */; }; - 5CDCAD5F28187D6900503DA2 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD5E28187D4A00503DA2 /* libiconv.tbd */; }; - 5CDCAD6128187D8000503DA2 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD6028187D7900503DA2 /* libz.tbd */; }; - 5CDCAD682818876500503DA2 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96A27A56D4D0075386C /* JSON.swift */; }; - 5CDCAD7628188D3600503DA2 /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7428188D2900503DA2 /* APITypes.swift */; }; - 5CDCAD7728188D3800503DA2 /* ChatTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */; }; - 5CDCAD7828188FD300503DA2 /* ChatTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */; }; - 5CDCAD7928188FD600503DA2 /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7428188D2900503DA2 /* APITypes.swift */; }; - 5CDCAD7C2818924D00503DA2 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; }; - 5CDCAD7E2818941F00503DA2 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7D2818941F00503DA2 /* API.swift */; }; - 5CDCAD7F281894FB00503DA2 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7D2818941F00503DA2 /* API.swift */; }; - 5CDCAD81281A7E2700503DA2 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD80281A7E2700503DA2 /* Notifications.swift */; }; - 5CDCAD82281A7E2700503DA2 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD80281A7E2700503DA2 /* Notifications.swift */; }; + 5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; }; + 5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */; }; + 5CE2BA79284530CC00EC33A6 /* SimpleXChat.docc in Sources */ = {isa = PBXBuildFile; fileRef = 5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */; }; + 5CE2BA85284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; + 5CE2BA86284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; + 5CE2BA87284532AD00EC33A6 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; }; + 5CE2BA88284532AD00EC33A6 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; }; + 5CE2BA89284532AD00EC33A6 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; }; + 5CE2BA8B284533A300EC33A6 /* ChatTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */; }; + 5CE2BA8C284533A300EC33A6 /* GroupDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */; }; + 5CE2BA8D284533A300EC33A6 /* CallTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5E5D3C282447AB00B0488A /* CallTypes.swift */; }; + 5CE2BA8E284533A300EC33A6 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7D2818941F00503DA2 /* API.swift */; }; + 5CE2BA8F284533A300EC33A6 /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD7428188D2900503DA2 /* APITypes.swift */; }; + 5CE2BA90284533A300EC33A6 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FD96A27A56D4D0075386C /* JSON.swift */; }; + 5CE2BA91284533A300EC33A6 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD80281A7E2700503DA2 /* Notifications.swift */; }; + 5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; }; + 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD5E28187D4A00503DA2 /* libiconv.tbd */; }; + 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CDCAD6028187D7900503DA2 /* libz.tbd */; }; + 5CE2BA952845354B00EC33A6 /* SimpleX.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE2BA8A2845332200EC33A6 /* SimpleX.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5CE2BA97284537A800EC33A6 /* dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CE2BA96284537A800EC33A6 /* dummy.m */; }; + 5CE2BA9D284555F500EC33A6 /* SimpleX NSE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5CDCAD452818589900503DA2 /* SimpleX NSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 5CE2BAA62845617C00EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; platformFilter = ios; }; 5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407127ADB1D0007B033A /* Emoji.swift */; }; 5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407827ADB701007B033A /* EmojiItemView.swift */; }; 5CEACCE327DE9246000BD591 /* ComposeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEACCE227DE9246000BD591 /* ComposeView.swift */; }; @@ -109,19 +111,8 @@ 648010AB281ADD15009009B9 /* CIFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648010AA281ADD15009009B9 /* CIFileView.swift */; }; 649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; }; 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; }; - 64A6908128376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; - 64A6908228376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; - 64A6908328376BBA0076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; }; - 64A6908428376BBA0076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; }; - 64A6908528376BBA0076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; }; - 64A6908628376BBA0076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; }; - 64A6908728376BBA0076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; }; - 64A6908828376BBA0076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; }; - 64A6908928376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; - 64A6908A28376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; 64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; }; 64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; }; - 64DAE1512809D9F5000DA960 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -132,8 +123,54 @@ remoteGlobalIDString = 5CA059C9279559F40002BEB4; remoteInfo = "SimpleX (iOS)"; }; + 5CE2BA6E2845308900EC33A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5CA059BE279559F40002BEB4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5CE2BA672845308900EC33A6; + remoteInfo = SimpleXChat; + }; + 5CE2BA9E284555F500EC33A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5CA059BE279559F40002BEB4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5CDCAD442818589900503DA2; + remoteInfo = "SimpleX NSE"; + }; + 5CE2BAA82845617C00EC33A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5CA059BE279559F40002BEB4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5CE2BA672845308900EC33A6; + remoteInfo = SimpleXChat; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 5CE2BA722845308900EC33A6 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 5CE2BAA0284555F500EC33A6 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 5CE2BA9D284555F500EC33A6 /* SimpleX NSE.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 3C714776281C081000CB4D4B /* WebRTCView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTCView.swift; sourceTree = ""; }; 3C714779281C0F6800CB4D4B /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../android/app/src/main/assets/www; sourceTree = ""; }; @@ -177,8 +214,6 @@ 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoToolbar.swift; sourceTree = ""; }; 5C764E7B279C71D4000C6508 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/lib/libiconv.tbd; sourceTree = DEVELOPER_DIR; }; 5C764E7C279C71DB000C6508 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; - 5C764E7D279C7275000C6508 /* SimpleX (iOS)-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimpleX (iOS)-Bridging-Header.h"; sourceTree = ""; }; - 5C764E7F279C7276000C6508 /* dummy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dummy.m; sourceTree = ""; }; 5C764E88279CBCB3000C6508 /* ChatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatModel.swift; sourceTree = ""; }; 5C971E1C27AEBEF600C8A3CE /* ChatInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoView.swift; sourceTree = ""; }; 5C971E2027AEBF8300C8A3CE /* ChatInfoImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoImage.swift; sourceTree = ""; }; @@ -216,14 +251,17 @@ 5CDCAD492818589900503DA2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5CDCAD5128186DE400503DA2 /* SimpleX NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "SimpleX NSE.entitlements"; sourceTree = ""; }; 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupDefaults.swift; sourceTree = ""; }; - 5CDCAD5628187C7500503DA2 /* SimpleX NSE-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SimpleX NSE-Bridging-Header.h"; sourceTree = ""; }; - 5CDCAD5728187C7500503DA2 /* dummy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dummy.m; sourceTree = ""; }; 5CDCAD5E28187D4A00503DA2 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk/usr/lib/libiconv.tbd; sourceTree = DEVELOPER_DIR; }; 5CDCAD6028187D7900503DA2 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.4.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTypes.swift; sourceTree = ""; }; 5CDCAD7428188D2900503DA2 /* APITypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APITypes.swift; sourceTree = ""; }; 5CDCAD7D2818941F00503DA2 /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; 5CDCAD80281A7E2700503DA2 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; + 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SimpleXChat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleXChat.h; sourceTree = ""; }; + 5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SimpleXChat.docc; sourceTree = ""; }; + 5CE2BA8A2845332200EC33A6 /* SimpleX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleX.h; sourceTree = ""; }; + 5CE2BA96284537A800EC33A6 /* dummy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dummy.m; sourceTree = ""; }; 5CE4407127ADB1D0007B033A /* Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Emoji.swift; sourceTree = ""; }; 5CE4407827ADB701007B033A /* EmojiItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiItemView.swift; sourceTree = ""; }; 5CEACCE227DE9246000BD591 /* ComposeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeView.swift; sourceTree = ""; }; @@ -252,15 +290,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 64A6908928376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, + 5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */, 646BB38C283BEEB9001CE359 /* LocalAuthentication.framework in Frameworks */, - 64A6908528376BBA0076573F /* libgmpxx.a in Frameworks */, - 64A6908728376BBA0076573F /* libgmp.a in Frameworks */, 5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */, - 5C764E83279C748B000C6508 /* libz.tbd in Frameworks */, - 5C764E82279C748B000C6508 /* libiconv.tbd in Frameworks */, - 64A6908328376BBA0076573F /* libffi.a in Frameworks */, - 64A6908128376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -275,13 +307,21 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5CDCAD5F28187D6900503DA2 /* libiconv.tbd in Frameworks */, - 64A6908628376BBA0076573F /* libgmpxx.a in Frameworks */, - 64A6908A28376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, - 5CDCAD6128187D8000503DA2 /* libz.tbd in Frameworks */, - 64A6908228376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, - 64A6908828376BBA0076573F /* libgmp.a in Frameworks */, - 64A6908428376BBA0076573F /* libffi.a in Frameworks */, + 5CE2BAA62845617C00EC33A6 /* SimpleXChat.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5CE2BA652845308900EC33A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, + 5CE2BA85284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, + 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, + 5CE2BA89284532AD00EC33A6 /* libgmpxx.a in Frameworks */, + 5CE2BA87284532AD00EC33A6 /* libffi.a in Frameworks */, + 5CE2BA88284532AD00EC33A6 /* libgmp.a in Frameworks */, + 5CE2BA86284532AD00EC33A6 /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -394,6 +434,7 @@ 5CA059C2279559F40002BEB4 /* Shared */, 5CDCAD462818589900503DA2 /* SimpleX NSE */, 5CA059DA279559F40002BEB4 /* Tests iOS */, + 5CE2BA692845308900EC33A6 /* SimpleXChat */, 5CA059CB279559F40002BEB4 /* Products */, 5C764E7A279C71D4000C6508 /* Frameworks */, ); @@ -405,12 +446,9 @@ 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */, 5C36027227F47AD5009F19D9 /* AppDelegate.swift */, 5CA059C4279559F40002BEB4 /* ContentView.swift */, - 64DAE1502809D9F5000DA960 /* FileUtils.swift */, 5C764E87279CBC8E000C6508 /* Model */, 5C2E260D27A30E2400F70299 /* Views */, 5CA059C5279559F40002BEB4 /* Assets.xcassets */, - 5C764E7D279C7275000C6508 /* SimpleX (iOS)-Bridging-Header.h */, - 5C764E7F279C7276000C6508 /* dummy.m */, 5C13730C2815740A00F43030 /* DebugJSON.playground */, ); path = Shared; @@ -422,6 +460,7 @@ 5CA059CA279559F40002BEB4 /* SimpleX.app */, 5CA059D7279559F40002BEB4 /* Tests iOS.xctest */, 5CDCAD452818589900503DA2 /* SimpleX NSE.appex */, + 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */, ); name = Products; sourceTree = ""; @@ -497,13 +536,18 @@ 5CDCAD492818589900503DA2 /* Info.plist */, 5CB0BA892826CB3A00B3292C /* Localizable.strings */, 5CB0BA862826CB3A00B3292C /* InfoPlist.strings */, - 5CDCAD5728187C7500503DA2 /* dummy.m */, - 5CDCAD5628187C7500503DA2 /* SimpleX NSE-Bridging-Header.h */, ); path = "SimpleX NSE"; sourceTree = ""; }; 5CDCAD7128188CEB00503DA2 /* Shared */ = { + isa = PBXGroup; + children = ( + ); + path = Shared; + sourceTree = ""; + }; + 5CE2BA692845308900EC33A6 /* SimpleXChat */ = { isa = PBXGroup; children = ( 5CDCAD5228186F9500503DA2 /* GroupDefaults.swift */, @@ -513,8 +557,13 @@ 5C9FD96A27A56D4D0075386C /* JSON.swift */, 5CDCAD7D2818941F00503DA2 /* API.swift */, 5CDCAD80281A7E2700503DA2 /* Notifications.swift */, + 64DAE1502809D9F5000DA960 /* FileUtils.swift */, + 5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */, + 5CE2BA8A2845332200EC33A6 /* SimpleX.h */, + 5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */, + 5CE2BA96284537A800EC33A6 /* dummy.m */, ); - path = Shared; + path = SimpleXChat; sourceTree = ""; }; 5CE4407427ADB657007B033A /* ChatItem */ = { @@ -549,6 +598,18 @@ }; /* End PBXGroup section */ +/* Begin PBXHeadersBuildPhase section */ + 5CE2BA632845308900EC33A6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */, + 5CE2BA952845354B00EC33A6 /* SimpleX.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + /* Begin PBXNativeTarget section */ 5CA059C9279559F40002BEB4 /* SimpleX (iOS) */ = { isa = PBXNativeTarget; @@ -557,10 +618,14 @@ 5CA059C6279559F40002BEB4 /* Sources */, 5CA059C7279559F40002BEB4 /* Frameworks */, 5CA059C8279559F40002BEB4 /* Resources */, + 5CE2BA722845308900EC33A6 /* Embed Frameworks */, + 5CE2BAA0284555F500EC33A6 /* Embed App Extensions */, ); buildRules = ( ); dependencies = ( + 5CE2BA6F2845308900EC33A6 /* PBXTargetDependency */, + 5CE2BA9F284555F500EC33A6 /* PBXTargetDependency */, ); name = "SimpleX (iOS)"; packageProductDependencies = ( @@ -599,12 +664,31 @@ buildRules = ( ); dependencies = ( + 5CE2BAA92845617C00EC33A6 /* PBXTargetDependency */, ); name = "SimpleX NSE"; productName = "SimpleX NSE"; productReference = 5CDCAD452818589900503DA2 /* SimpleX NSE.appex */; productType = "com.apple.product-type.app-extension"; }; + 5CE2BA672845308900EC33A6 /* SimpleXChat */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5CE2BA752845308900EC33A6 /* Build configuration list for PBXNativeTarget "SimpleXChat" */; + buildPhases = ( + 5CE2BA632845308900EC33A6 /* Headers */, + 5CE2BA642845308900EC33A6 /* Sources */, + 5CE2BA652845308900EC33A6 /* Frameworks */, + 5CE2BA662845308900EC33A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SimpleXChat; + productName = SimpleXChat; + productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -628,6 +712,10 @@ CreatedOnToolsVersion = 13.3; LastSwiftMigration = 1330; }; + 5CE2BA672845308900EC33A6 = { + CreatedOnToolsVersion = 13.3; + LastSwiftMigration = 1330; + }; }; }; buildConfigurationList = 5CA059C1279559F40002BEB4 /* Build configuration list for PBXProject "SimpleX" */; @@ -649,6 +737,7 @@ 5CA059C9279559F40002BEB4 /* SimpleX (iOS) */, 5CA059D6279559F40002BEB4 /* Tests iOS */, 5CDCAD442818589900503DA2 /* SimpleX NSE */, + 5CE2BA672845308900EC33A6 /* SimpleXChat */, ); }; /* End PBXProject section */ @@ -682,6 +771,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5CE2BA662845308900EC33A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -691,16 +787,12 @@ files = ( 5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */, 5C3F1D58284363C400EC8A82 /* PrivacySettings.swift in Sources */, - 5CDCAD7F281894FB00503DA2 /* API.swift in Sources */, 5C55A923283CEDE600C4E99E /* SoundPlayer.swift in Sources */, - 5CDCAD81281A7E2700503DA2 /* Notifications.swift in Sources */, 5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */, 5CEACCE327DE9246000BD591 /* ComposeView.swift in Sources */, - 5CDCAD7728188D3800503DA2 /* ChatTypes.swift in Sources */, 5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */, 5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */, 5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */, - 5CDCAD5328186F9500503DA2 /* GroupDefaults.swift in Sources */, 5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */, 5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */, 5C3F1D562842B68D00EC8A82 /* IntegrityErrorItemView.swift in Sources */, @@ -709,7 +801,6 @@ 648010AB281ADD15009009B9 /* CIFileView.swift in Sources */, 3CDBCF4227FAE51000354CDD /* ComposeLinkView.swift in Sources */, 3CDBCF4827FF621E00354CDD /* CILinkView.swift in Sources */, - 5C764E80279C7276000C6508 /* dummy.m in Sources */, 5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */, 5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */, 5CB924E427A8683A00ACCCDD /* UserAddress.swift in Sources */, @@ -721,8 +812,6 @@ 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */, 5CB0BA8E2827126500B3292C /* OnboardingView.swift in Sources */, 5C2E261227A30FEA00F70299 /* TerminalView.swift in Sources */, - 5CDCAD7628188D3600503DA2 /* APITypes.swift in Sources */, - 5C9FD96B27A56D4D0075386C /* JSON.swift in Sources */, 5C9FD96E27A5D6ED0075386C /* SendMessageView.swift in Sources */, 5CC1C99227A6C7F5000D9FF6 /* QRCode.swift in Sources */, 5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */, @@ -751,7 +840,6 @@ 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */, 5CCD403A27A5F9BE00368C90 /* CreateGroupView.swift in Sources */, 5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */, - 64DAE1512809D9F5000DA960 /* FileUtils.swift in Sources */, 5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */, 5C971E1D27AEBEF600C8A3CE /* ChatInfoView.swift in Sources */, 5CC1C99527A6CF7F000D9FF6 /* ShareSheet.swift in Sources */, @@ -761,7 +849,6 @@ 3C714777281C081000CB4D4B /* WebRTCView.swift in Sources */, 5CB0BA92282713FD00B3292C /* CreateProfile.swift in Sources */, 5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */, - 5C5E5D3D282447AB00B0488A /* CallTypes.swift in Sources */, 64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */, 5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */, 5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */, @@ -784,17 +871,25 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5CDCAD7928188FD600503DA2 /* APITypes.swift in Sources */, - 5C5E5D3E282447BF00B0488A /* CallTypes.swift in Sources */, - 5CDCAD5828187C7500503DA2 /* dummy.m in Sources */, 5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */, - 5CDCAD82281A7E2700503DA2 /* Notifications.swift in Sources */, - 5CDCAD7C2818924D00503DA2 /* FileUtils.swift in Sources */, - 5CDCAD682818876500503DA2 /* JSON.swift in Sources */, 5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */, - 5CDCAD7828188FD300503DA2 /* ChatTypes.swift in Sources */, - 5CDCAD7E2818941F00503DA2 /* API.swift in Sources */, - 5CDCAD5428186F9700503DA2 /* GroupDefaults.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5CE2BA642845308900EC33A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5CE2BA97284537A800EC33A6 /* dummy.m in Sources */, + 5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */, + 5CE2BA91284533A300EC33A6 /* Notifications.swift in Sources */, + 5CE2BA79284530CC00EC33A6 /* SimpleXChat.docc in Sources */, + 5CE2BA90284533A300EC33A6 /* JSON.swift in Sources */, + 5CE2BA8B284533A300EC33A6 /* ChatTypes.swift in Sources */, + 5CE2BA8F284533A300EC33A6 /* APITypes.swift in Sources */, + 5CE2BA8C284533A300EC33A6 /* GroupDefaults.swift in Sources */, + 5CE2BA8D284533A300EC33A6 /* CallTypes.swift in Sources */, + 5CE2BA8E284533A300EC33A6 /* API.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -806,6 +901,22 @@ target = 5CA059C9279559F40002BEB4 /* SimpleX (iOS) */; targetProxy = 5CA059D8279559F40002BEB4 /* PBXContainerItemProxy */; }; + 5CE2BA6F2845308900EC33A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5CE2BA672845308900EC33A6 /* SimpleXChat */; + targetProxy = 5CE2BA6E2845308900EC33A6 /* PBXContainerItemProxy */; + }; + 5CE2BA9F284555F500EC33A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5CDCAD442818589900503DA2 /* SimpleX NSE */; + targetProxy = 5CE2BA9E284555F500EC33A6 /* PBXContainerItemProxy */; + }; + 5CE2BAA92845617C00EC33A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilter = ios; + target = 5CE2BA672845308900EC33A6 /* SimpleXChat */; + targetProxy = 5CE2BAA82845617C00EC33A6 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -961,6 +1072,7 @@ 5CA059F4279559F40002BEB4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_MODULES = YES; @@ -994,7 +1106,6 @@ PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "Shared/SimpleX (iOS)-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; @@ -1004,6 +1115,7 @@ 5CA059F5279559F40002BEB4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ENABLE_MODULES = YES; @@ -1037,7 +1149,6 @@ PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "Shared/SimpleX (iOS)-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; VALIDATE_PRODUCT = YES; @@ -1118,7 +1229,6 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "SimpleX NSE/SimpleX NSE-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; @@ -1158,13 +1268,106 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "SimpleX NSE/SimpleX NSE-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; VALIDATE_PRODUCT = YES; }; name = Release; }; + 5CE2BA732845308900EC33A6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 5NN7GUYB6T; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_BITCODE = NO; + GENERATE_INFOPLIST_FILE = YES; + 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", + ); + "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Libraries/ios", + ); + "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Libraries/sim", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INCLUDE_PATHS = ""; + SWIFT_OBJC_BRIDGING_HEADER = ./SimpleXChat/SimpleX.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 5CE2BA742845308900EC33A6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 5NN7GUYB6T; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_BITCODE = NO; + GENERATE_INFOPLIST_FILE = YES; + 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", + ); + "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Libraries/ios", + ); + "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Libraries/sim", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INCLUDE_PATHS = ""; + SWIFT_OBJC_BRIDGING_HEADER = ./SimpleXChat/SimpleX.h; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1204,6 +1407,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5CE2BA752845308900EC33A6 /* Build configuration list for PBXNativeTarget "SimpleXChat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5CE2BA732845308900EC33A6 /* Debug */, + 5CE2BA742845308900EC33A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ diff --git a/apps/ios/Shared/Model/Shared/API.swift b/apps/ios/SimpleXChat/API.swift similarity index 88% rename from apps/ios/Shared/Model/Shared/API.swift rename to apps/ios/SimpleXChat/API.swift index 7208c45d99..091a5a7190 100644 --- a/apps/ios/Shared/Model/Shared/API.swift +++ b/apps/ios/SimpleXChat/API.swift @@ -10,7 +10,7 @@ import Foundation private var chatController: chat_ctrl? -func getChatCtrl() -> chat_ctrl { +public func getChatCtrl() -> chat_ctrl { if let controller = chatController { return controller } let dataDir = getDocumentsDirectory().path + "/mobile_v1" logger.debug("documents directory \(dataDir)") @@ -20,12 +20,12 @@ func getChatCtrl() -> chat_ctrl { return chatController! } -func sendSimpleXCmd(_ cmd: ChatCommand) -> ChatResponse { +public func sendSimpleXCmd(_ cmd: ChatCommand) -> ChatResponse { var c = cmd.cmdString.cString(using: .utf8)! return chatResponse(chat_send_cmd(getChatCtrl(), &c)) } -func chatResponse(_ cjson: UnsafeMutablePointer) -> ChatResponse { +public func chatResponse(_ cjson: UnsafeMutablePointer) -> ChatResponse { let s = String.init(cString: cjson) let d = s.data(using: .utf8)! // TODO is there a way to do it without copying the data? e.g: @@ -57,7 +57,7 @@ func prettyJSON(_ obj: NSDictionary) -> String? { return nil } -func responseError(_ err: Error) -> String { +public func responseError(_ err: Error) -> String { if let r = err as? ChatResponse { return String(describing: r) } else { diff --git a/apps/ios/Shared/Model/Shared/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift similarity index 96% rename from apps/ios/Shared/Model/Shared/APITypes.swift rename to apps/ios/SimpleXChat/APITypes.swift index c4e5f5eabe..d45ceef19e 100644 --- a/apps/ios/Shared/Model/Shared/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -11,7 +11,7 @@ import Foundation let jsonDecoder = getJSONDecoder() let jsonEncoder = getJSONEncoder() -enum ChatCommand { +public enum ChatCommand { case showActiveUser case createActiveUser(profile: Profile) case startChat @@ -50,7 +50,7 @@ enum ChatCommand { case receiveFile(fileId: Int64) case string(String) - var cmdString: String { + public var cmdString: String { get { switch self { case .showActiveUser: return "/u" @@ -95,7 +95,7 @@ enum ChatCommand { } } - var cmdType: String { + public var cmdType: String { get { switch self { case .showActiveUser: return "showActiveUser" @@ -151,7 +151,7 @@ struct APIResponse: Decodable { var resp: ChatResponse } -enum ChatResponse: Decodable, Error { +public enum ChatResponse: Decodable, Error { case response(type: String, json: String) case activeUser(user: User) case chatStarted @@ -211,7 +211,7 @@ enum ChatResponse: Decodable, Error { case chatCmdError(chatError: ChatError) case chatError(chatError: ChatError) - var responseType: String { + public var responseType: String { get { switch self { case let .response(type, _): return "* \(type)" @@ -274,7 +274,7 @@ enum ChatResponse: Decodable, Error { } } - var details: String { + public var details: String { get { switch self { case let .response(_, json): return json @@ -346,7 +346,7 @@ struct ComposedMessage: Encodable { var msgContent: MsgContent } -func decodeJSON(_ json: String) -> T? { +public func decodeJSON(_ json: String) -> T? { if let data = json.data(using: .utf8) { return try? jsonDecoder.decode(T.self, from: data) } @@ -366,7 +366,7 @@ private func getJSONObject(_ cjson: UnsafePointer) -> NSDictionary? { return try? JSONSerialization.jsonObject(with: d) as? NSDictionary } -func encodeJSON(_ value: T) -> String { +public func encodeJSON(_ value: T) -> String { let data = try! jsonEncoder.encode(value) return String(decoding: data, as: UTF8.self) } @@ -375,13 +375,13 @@ private func encodeCJSON(_ value: T) -> [CChar] { encodeJSON(value).cString(using: .utf8)! } -enum ChatError: Decodable { +public enum ChatError: Decodable { case error(errorType: ChatErrorType) case errorAgent(agentError: AgentErrorType) case errorStore(storeError: StoreError) } -enum ChatErrorType: Decodable { +public enum ChatErrorType: Decodable { case noActiveUser case activeUserExists case chatNotStarted @@ -415,7 +415,7 @@ enum ChatErrorType: Decodable { case commandError(message: String) } -enum StoreError: Decodable { +public enum StoreError: Decodable { case duplicateName case contactNotFound(contactId: Int64) case contactNotFoundByName(contactName: ContactName) @@ -448,7 +448,7 @@ enum StoreError: Decodable { case chatItemNotFoundByFileId(fileId: Int64) } -enum AgentErrorType: Decodable { +public enum AgentErrorType: Decodable { case CMD(cmdErr: CommandErrorType) case CONN(connErr: ConnectionErrorType) case SMP(smpErr: ProtocolErrorType) @@ -458,7 +458,7 @@ enum AgentErrorType: Decodable { case INTERNAL(internalErr: String) } -enum CommandErrorType: Decodable { +public enum CommandErrorType: Decodable { case PROHIBITED case SYNTAX case NO_CONN @@ -466,7 +466,7 @@ enum CommandErrorType: Decodable { case LARGE } -enum ConnectionErrorType: Decodable { +public enum ConnectionErrorType: Decodable { case NOT_FOUND case DUPLICATE case SIMPLEX @@ -474,7 +474,7 @@ enum ConnectionErrorType: Decodable { case NOT_AVAILABLE } -enum BrokerErrorType: Decodable { +public enum BrokerErrorType: Decodable { case RESPONSE(smpErr: ProtocolErrorType) case UNEXPECTED case NETWORK @@ -482,7 +482,7 @@ enum BrokerErrorType: Decodable { case TIMEOUT } -enum ProtocolErrorType: Decodable { +public enum ProtocolErrorType: Decodable { case BLOCK case SESSION case CMD(cmdErr: ProtocolCommandError) @@ -493,7 +493,7 @@ enum ProtocolErrorType: Decodable { case INTERNAL } -enum ProtocolCommandError: Decodable { +public enum ProtocolCommandError: Decodable { case UNKNOWN case SYNTAX case NO_AUTH @@ -501,20 +501,20 @@ enum ProtocolCommandError: Decodable { case NO_ENTITY } -enum ProtocolTransportError: Decodable { +public enum ProtocolTransportError: Decodable { case badBlock case largeMsg case badSession case handshake(handshakeErr: SMPHandshakeError) } -enum SMPHandshakeError: Decodable { +public enum SMPHandshakeError: Decodable { case PARSE case VERSION case IDENTITY } -enum SMPAgentError: Decodable { +public enum SMPAgentError: Decodable { case A_MESSAGE case A_PROHIBITED case A_VERSION diff --git a/apps/ios/SimpleXChat/CallTypes.swift b/apps/ios/SimpleXChat/CallTypes.swift new file mode 100644 index 0000000000..01f05ac4fd --- /dev/null +++ b/apps/ios/SimpleXChat/CallTypes.swift @@ -0,0 +1,99 @@ +// +// CallTypes.swift +// SimpleX (iOS) +// +// Created by Evgeny on 05/05/2022. +// Copyright © 2022 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI + +public struct WebRTCCallOffer: Encodable { + public init(callType: CallType, rtcSession: WebRTCSession) { + self.callType = callType + self.rtcSession = rtcSession + } + + public var callType: CallType + public var rtcSession: WebRTCSession +} + +public struct WebRTCSession: Codable { + public init(rtcSession: String, rtcIceCandidates: String) { + self.rtcSession = rtcSession + self.rtcIceCandidates = rtcIceCandidates + } + + public var rtcSession: String + public var rtcIceCandidates: String +} + +public struct WebRTCExtraInfo: Codable { + public init(rtcIceCandidates: String) { + self.rtcIceCandidates = rtcIceCandidates + } + + public var rtcIceCandidates: String +} + +public struct CallInvitation { + public init(contact: Contact, callkitUUID: UUID? = nil, peerMedia: CallMediaType, sharedKey: String? = nil, callTs: Date) { + self.contact = contact + self.callkitUUID = callkitUUID + self.peerMedia = peerMedia + self.sharedKey = sharedKey + self.callTs = callTs + } + + public var contact: Contact + public var callkitUUID: UUID? + public var peerMedia: CallMediaType + public var sharedKey: String? + public var callTs: Date + public var callTypeText: LocalizedStringKey { + get { + switch peerMedia { + case .video: return sharedKey == nil ? "video call (not e2e encrypted)" : "**e2e encrypted** video call" + case .audio: return sharedKey == nil ? "audio call (not e2e encrypted)" : "**e2e encrypted** audio call" + } + } + } + + public static let sampleData = CallInvitation( + contact: Contact.sampleData, + peerMedia: .audio, + callTs: .now + ) +} + +public struct CallType: Codable { + public init(media: CallMediaType, capabilities: CallCapabilities) { + self.media = media + self.capabilities = capabilities + } + + public var media: CallMediaType + public var capabilities: CallCapabilities +} + +public enum CallMediaType: String, Codable, Equatable { + case video = "video" + case audio = "audio" +} + +public enum VideoCamera: String, Codable, Equatable { + case user = "user" + case environment = "environment" +} + +public struct CallCapabilities: Codable, Equatable { + public var encryption: Bool +} + +public enum WebRTCCallStatus: String, Encodable { + case connected = "connected" + case connecting = "connecting" + case disconnected = "disconnected" + case failed = "failed" +} diff --git a/apps/ios/Shared/Model/Shared/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift similarity index 71% rename from apps/ios/Shared/Model/Shared/ChatTypes.swift rename to apps/ios/SimpleXChat/ChatTypes.swift index 69966d8a59..fd631a0cc4 100644 --- a/apps/ios/Shared/Model/Shared/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -9,18 +9,18 @@ import Foundation import SwiftUI -struct User: Decodable, NamedChat { +public struct User: Decodable, NamedChat { var userId: Int64 var userContactId: Int64 var localDisplayName: ContactName - var profile: Profile + public var profile: Profile var activeUser: Bool - var displayName: String { get { profile.displayName } } - var fullName: String { get { profile.fullName } } - var image: String? { get { profile.image } } + public var displayName: String { get { profile.displayName } } + public var fullName: String { get { profile.fullName } } + public var image: String? { get { profile.image } } - static let sampleData = User( + public static let sampleData = User( userId: 1, userContactId: 1, localDisplayName: "alice", @@ -29,14 +29,20 @@ struct User: Decodable, NamedChat { ) } -typealias ContactName = String +public typealias ContactName = String -typealias GroupName = String +public typealias GroupName = String -struct Profile: Codable, NamedChat { - var displayName: String - var fullName: String - var image: String? +public struct Profile: Codable, NamedChat { + public init(displayName: String, fullName: String, image: String? = nil) { + self.displayName = displayName + self.fullName = fullName + self.image = image + } + + public var displayName: String + public var fullName: String + public var image: String? static let sampleData = Profile( displayName: "alice", @@ -44,34 +50,34 @@ struct Profile: Codable, NamedChat { ) } -enum ChatType: String { +public enum ChatType: String { case direct = "@" case group = "#" case contactRequest = "<@" case contactConnection = ":" } -protocol NamedChat { +public protocol NamedChat { var displayName: String { get } var fullName: String { get } var image: String? { get } } extension NamedChat { - var chatViewName: String { + public var chatViewName: String { get { displayName + (fullName == "" || fullName == displayName ? "" : " / \(fullName)") } } } -typealias ChatId = String +public typealias ChatId = String -enum ChatInfo: Identifiable, Decodable, NamedChat { +public enum ChatInfo: Identifiable, Decodable, NamedChat { case direct(contact: Contact) case group(groupInfo: GroupInfo) case contactRequest(contactRequest: UserContactRequest) case contactConnection(contactConnection: PendingContactConnection) - var localDisplayName: String { + public var localDisplayName: String { get { switch self { case let .direct(contact): return contact.localDisplayName @@ -82,7 +88,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var displayName: String { + public var displayName: String { get { switch self { case let .direct(contact): return contact.displayName @@ -93,7 +99,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var fullName: String { + public var fullName: String { get { switch self { case let .direct(contact): return contact.fullName @@ -104,7 +110,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var image: String? { + public var image: String? { get { switch self { case let .direct(contact): return contact.image @@ -115,7 +121,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var id: ChatId { + public var id: ChatId { get { switch self { case let .direct(contact): return contact.id @@ -126,7 +132,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var chatType: ChatType { + public var chatType: ChatType { get { switch self { case .direct: return .direct @@ -137,7 +143,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var apiId: Int64 { + public var apiId: Int64 { get { switch self { case let .direct(contact): return contact.apiId @@ -148,7 +154,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var ready: Bool { + public var ready: Bool { get { switch self { case let .direct(contact): return contact.ready @@ -168,7 +174,7 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - var updatedAt: Date { + public var updatedAt: Date { switch self { case let .direct(contact): return contact.updatedAt case let .group(groupInfo): return groupInfo.updatedAt @@ -177,49 +183,54 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } - struct SampleData { - var direct: ChatInfo - var group: ChatInfo - var contactRequest: ChatInfo + public struct SampleData { + public var direct: ChatInfo + public var group: ChatInfo + public var contactRequest: ChatInfo } - static var sampleData: ChatInfo.SampleData = SampleData( + public static var sampleData: ChatInfo.SampleData = SampleData( direct: ChatInfo.direct(contact: Contact.sampleData), group: ChatInfo.group(groupInfo: GroupInfo.sampleData), contactRequest: ChatInfo.contactRequest(contactRequest: UserContactRequest.sampleData) ) } -struct ChatData: Decodable, Identifiable { - var chatInfo: ChatInfo - var chatItems: [ChatItem] - var chatStats: ChatStats +public struct ChatData: Decodable, Identifiable { + public var chatInfo: ChatInfo + public var chatItems: [ChatItem] + public var chatStats: ChatStats - var id: ChatId { get { chatInfo.id } } + public var id: ChatId { get { chatInfo.id } } } -struct ChatStats: Decodable { - var unreadCount: Int = 0 - var minUnreadItemId: Int64 = 0 +public struct ChatStats: Decodable { + public init(unreadCount: Int = 0, minUnreadItemId: Int64 = 0) { + self.unreadCount = unreadCount + self.minUnreadItemId = minUnreadItemId + } + + public var unreadCount: Int = 0 + public var minUnreadItemId: Int64 = 0 } -struct Contact: Identifiable, Decodable, NamedChat { +public struct Contact: Identifiable, Decodable, NamedChat { var contactId: Int64 var localDisplayName: ContactName - var profile: Profile - var activeConn: Connection + public var profile: Profile + public var activeConn: Connection var viaGroup: Int64? var createdAt: Date var updatedAt: Date - var id: ChatId { get { "@\(contactId)" } } - var apiId: Int64 { get { contactId } } - var ready: Bool { get { activeConn.connStatus == .ready } } - var displayName: String { get { profile.displayName } } - var fullName: String { get { profile.fullName } } - var image: String? { get { profile.image } } + public var id: ChatId { get { "@\(contactId)" } } + public var apiId: Int64 { get { contactId } } + public var ready: Bool { get { activeConn.connStatus == .ready } } + public var displayName: String { get { profile.displayName } } + public var fullName: String { get { profile.fullName } } + public var image: String? { get { profile.image } } - static let sampleData = Contact( + public static let sampleData = Contact( contactId: 1, localDisplayName: "alice", profile: Profile.sampleData, @@ -229,23 +240,23 @@ struct Contact: Identifiable, Decodable, NamedChat { ) } -struct ContactRef: Decodable, Equatable { +public struct ContactRef: Decodable, Equatable { var contactId: Int64 var localDisplayName: ContactName - var id: ChatId { get { "@\(contactId)" } } + public var id: ChatId { get { "@\(contactId)" } } } -struct ContactSubStatus: Decodable { - var contact: Contact - var contactError: ChatError? +public struct ContactSubStatus: Decodable { + public var contact: Contact + public var contactError: ChatError? } -struct Connection: Decodable { +public struct Connection: Decodable { var connId: Int64 var connStatus: ConnStatus - var id: ChatId { get { ":\(connId)" } } + public var id: ChatId { get { ":\(connId)" } } static let sampleData = Connection( connId: 1, @@ -253,21 +264,21 @@ struct Connection: Decodable { ) } -struct UserContactRequest: Decodable, NamedChat { +public struct UserContactRequest: Decodable, NamedChat { var contactRequestId: Int64 var localDisplayName: ContactName var profile: Profile var createdAt: Date - var updatedAt: Date + public var updatedAt: Date - var id: ChatId { get { "<@\(contactRequestId)" } } - var apiId: Int64 { get { contactRequestId } } + public var id: ChatId { get { "<@\(contactRequestId)" } } + public var apiId: Int64 { get { contactRequestId } } var ready: Bool { get { true } } - var displayName: String { get { profile.displayName } } - var fullName: String { get { profile.fullName } } - var image: String? { get { profile.image } } + public var displayName: String { get { profile.displayName } } + public var fullName: String { get { profile.fullName } } + public var image: String? { get { profile.image } } - static let sampleData = UserContactRequest( + public static let sampleData = UserContactRequest( contactRequestId: 1, localDisplayName: "alice", profile: Profile.sampleData, @@ -276,21 +287,21 @@ struct UserContactRequest: Decodable, NamedChat { ) } -struct PendingContactConnection: Decodable, NamedChat { +public struct PendingContactConnection: Decodable, NamedChat { var pccConnId: Int64 var pccAgentConnId: String var pccConnStatus: ConnStatus - var viaContactUri: Bool + public var viaContactUri: Bool var createdAt: Date - var updatedAt: Date + public var updatedAt: Date - var id: ChatId { get { ":\(pccConnId)" } } - var apiId: Int64 { get { pccConnId } } + public var id: ChatId { get { ":\(pccConnId)" } } + public var apiId: Int64 { get { pccConnId } } var ready: Bool { get { false } } var localDisplayName: String { get { String.localizedStringWithFormat(NSLocalizedString("connection:%@", comment: "connection information"), pccConnId) } } - var displayName: String { + public var displayName: String { get { if let initiated = pccConnStatus.initiated { return initiated && !viaContactUri @@ -302,11 +313,11 @@ struct PendingContactConnection: Decodable, NamedChat { } } } - var fullName: String { get { "" } } - var image: String? { get { nil } } - var initiated: Bool { get { (pccConnStatus.initiated ?? false) && !viaContactUri } } + public var fullName: String { get { "" } } + public var image: String? { get { nil } } + public var initiated: Bool { get { (pccConnStatus.initiated ?? false) && !viaContactUri } } - var description: String { + public var description: String { get { if let initiated = pccConnStatus.initiated { return initiated && !viaContactUri @@ -320,7 +331,7 @@ struct PendingContactConnection: Decodable, NamedChat { } } - static func getSampleData(_ status: ConnStatus = .new, viaContactUri: Bool = false) -> PendingContactConnection { + public static func getSampleData(_ status: ConnStatus = .new, viaContactUri: Bool = false) -> PendingContactConnection { PendingContactConnection( pccConnId: 1, pccAgentConnId: "abcd", @@ -332,7 +343,7 @@ struct PendingContactConnection: Decodable, NamedChat { } } -enum ConnStatus: String, Decodable { +public enum ConnStatus: String, Decodable { case new = "new" case joined = "joined" case requested = "requested" @@ -356,19 +367,19 @@ enum ConnStatus: String, Decodable { } } -struct GroupInfo: Identifiable, Decodable, NamedChat { +public struct GroupInfo: Identifiable, Decodable, NamedChat { var groupId: Int64 var localDisplayName: GroupName var groupProfile: GroupProfile var createdAt: Date var updatedAt: Date - var id: ChatId { get { "#\(groupId)" } } + public var id: ChatId { get { "#\(groupId)" } } var apiId: Int64 { get { groupId } } - var ready: Bool { get { true } } - var displayName: String { get { groupProfile.displayName } } - var fullName: String { get { groupProfile.fullName } } - var image: String? { get { groupProfile.image } } + public var ready: Bool { get { true } } + public var displayName: String { get { groupProfile.displayName } } + public var fullName: String { get { groupProfile.fullName } } + public var image: String? { get { groupProfile.image } } static let sampleData = GroupInfo( groupId: 1, @@ -379,10 +390,10 @@ struct GroupInfo: Identifiable, Decodable, NamedChat { ) } -struct GroupProfile: Codable, NamedChat { - var displayName: String - var fullName: String - var image: String? +public struct GroupProfile: Codable, NamedChat { + public var displayName: String + public var fullName: String + public var image: String? static let sampleData = GroupProfile( displayName: "team", @@ -390,15 +401,15 @@ struct GroupProfile: Codable, NamedChat { ) } -struct GroupMember: Decodable { - var groupMemberId: Int64 +public struct GroupMember: Decodable { + public var groupMemberId: Int64 var memberId: String // var memberRole: GroupMemberRole // var memberCategory: GroupMemberCategory // var memberStatus: GroupMemberStatus // var invitedBy: InvitedBy var localDisplayName: ContactName - var memberProfile: Profile + public var memberProfile: Profile var memberContactId: Int64? // var activeConn: Connection? @@ -412,7 +423,7 @@ struct GroupMember: Decodable { } } - static let sampleData = GroupMember( + public static let sampleData = GroupMember( groupMemberId: 1, memberId: "abcd", localDisplayName: "alice", @@ -421,29 +432,38 @@ struct GroupMember: Decodable { ) } -struct MemberSubError: Decodable { +public struct MemberSubError: Decodable { var member: GroupMember var memberError: ChatError } -struct AChatItem: Decodable { - var chatInfo: ChatInfo - var chatItem: ChatItem +public struct AChatItem: Decodable { + public var chatInfo: ChatInfo + public var chatItem: ChatItem } -struct ChatItem: Identifiable, Decodable { - var chatDir: CIDirection - var meta: CIMeta - var content: CIContent - var formattedText: [FormattedText]? - var quotedItem: CIQuote? - var file: CIFile? +public struct ChatItem: Identifiable, Decodable { + public init(chatDir: CIDirection, meta: CIMeta, content: CIContent, formattedText: [FormattedText]? = nil, quotedItem: CIQuote? = nil, file: CIFile? = nil) { + self.chatDir = chatDir + self.meta = meta + self.content = content + self.formattedText = formattedText + self.quotedItem = quotedItem + self.file = file + } + + public var chatDir: CIDirection + public var meta: CIMeta + public var content: CIContent + public var formattedText: [FormattedText]? + public var quotedItem: CIQuote? + public var file: CIFile? - var id: Int64 { get { meta.itemId } } + public var id: Int64 { get { meta.itemId } } - var timestampText: Text { get { meta.timestampText } } + public var timestampText: Text { get { meta.timestampText } } - var text: String { + public var text: String { get { switch (content.text, file) { case let ("", .some(file)): return file.fileName @@ -452,12 +472,12 @@ struct ChatItem: Identifiable, Decodable { } } - func isRcvNew() -> Bool { + public func isRcvNew() -> Bool { if case .rcvNew = meta.itemStatus { return true } return false } - func isMsgContent() -> Bool { + public func isMsgContent() -> Bool { switch content { case .sndMsgContent: return true case .rcvMsgContent: return true @@ -465,7 +485,7 @@ struct ChatItem: Identifiable, Decodable { } } - func isDeletedContent() -> Bool { + public func isDeletedContent() -> Bool { switch content { case .sndDeleted: return true case .rcvDeleted: return true @@ -473,7 +493,7 @@ struct ChatItem: Identifiable, Decodable { } } - func isCall() -> Bool { + public func isCall() -> Bool { switch content { case .sndCall: return true case .rcvCall: return true @@ -481,7 +501,7 @@ struct ChatItem: Identifiable, Decodable { } } - var memberDisplayName: String? { + public var memberDisplayName: String? { get { if case let .groupRcv(groupMember) = chatDir { return groupMember.memberProfile.displayName @@ -491,7 +511,7 @@ struct ChatItem: Identifiable, Decodable { } } - static func getSample (_ id: Int64, _ dir: CIDirection, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, quotedItem: CIQuote? = nil, file: CIFile? = nil, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> ChatItem { + public static func getSample (_ id: Int64, _ dir: CIDirection, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, quotedItem: CIQuote? = nil, file: CIFile? = nil, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> ChatItem { ChatItem( chatDir: dir, meta: CIMeta.getSample(id, ts, text, status, itemDeleted, itemEdited, editable), @@ -501,7 +521,7 @@ struct ChatItem: Identifiable, Decodable { ) } - static func getFileMsgContentSample (id: Int64 = 1, text: String = "", fileName: String = "test.txt", fileSize: Int64 = 100, fileStatus: CIFileStatus = .rcvComplete) -> ChatItem { + public static func getFileMsgContentSample (id: Int64 = 1, text: String = "", fileName: String = "test.txt", fileSize: Int64 = 100, fileStatus: CIFileStatus = .rcvComplete) -> ChatItem { ChatItem( chatDir: .directRcv, meta: CIMeta.getSample(id, .now, text, .rcvRead, false, false, false), @@ -511,7 +531,7 @@ struct ChatItem: Identifiable, Decodable { ) } - static func getDeletedContentSample (_ id: Int64 = 1, dir: CIDirection = .directRcv, _ ts: Date = .now, _ text: String = "this item is deleted", _ status: CIStatus = .rcvRead) -> ChatItem { + public static func getDeletedContentSample (_ id: Int64 = 1, dir: CIDirection = .directRcv, _ ts: Date = .now, _ text: String = "this item is deleted", _ status: CIStatus = .rcvRead) -> ChatItem { ChatItem( chatDir: dir, meta: CIMeta.getSample(id, ts, text, status, false, false, false), @@ -521,7 +541,7 @@ struct ChatItem: Identifiable, Decodable { ) } - static func getIntegrityErrorSample (_ status: CIStatus = .rcvRead, fromMsgId: Int64 = 1, toMsgId: Int64 = 2) -> ChatItem { + public static func getIntegrityErrorSample (_ status: CIStatus = .rcvRead, fromMsgId: Int64 = 1, toMsgId: Int64 = 2) -> ChatItem { ChatItem( chatDir: .directRcv, meta: CIMeta.getSample(1, .now, "1 skipped message", status, false, false, false), @@ -532,13 +552,13 @@ struct ChatItem: Identifiable, Decodable { } } -enum CIDirection: Decodable { +public enum CIDirection: Decodable { case directSnd case directRcv case groupSnd case groupRcv(groupMember: GroupMember) - var sent: Bool { + public var sent: Bool { get { switch self { case .directSnd: return true @@ -550,19 +570,19 @@ enum CIDirection: Decodable { } } -struct CIMeta: Decodable { +public struct CIMeta: Decodable { var itemId: Int64 var itemTs: Date var itemText: String - var itemStatus: CIStatus + public var itemStatus: CIStatus var createdAt: Date - var itemDeleted: Bool - var itemEdited: Bool - var editable: Bool + public var itemDeleted: Bool + public var itemEdited: Bool + public var editable: Bool var timestampText: Text { get { formatTimestampText(itemTs) } } - static func getSample(_ id: Int64, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> CIMeta { + public static func getSample(_ id: Int64, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, _ itemDeleted: Bool = false, _ itemEdited: Bool = false, _ editable: Bool = true) -> CIMeta { CIMeta( itemId: id, itemTs: ts, @@ -579,14 +599,14 @@ struct CIMeta: Decodable { let msgTimeFormat = Date.FormatStyle.dateTime.hour().minute() let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits) -func formatTimestampText(_ date: Date) -> Text { +public func formatTimestampText(_ date: Date) -> Text { let now = Calendar.current.dateComponents([.day, .hour], from: .now) let dc = Calendar.current.dateComponents([.day, .hour], from: date) let recent = now.day == dc.day || ((now.day ?? 0) - (dc.day ?? 0) == 1 && (dc.hour ?? 0) >= 18 && (now.hour ?? 0) < 12) return Text(date, format: recent ? msgTimeFormat : msgDateFormat) } -enum CIStatus: Decodable { +public enum CIStatus: Decodable { case sndNew case sndSent case sndErrorAuth @@ -595,7 +615,7 @@ enum CIStatus: Decodable { case rcvRead } -enum CIDeleteMode: String, Decodable { +public enum CIDeleteMode: String, Decodable { case cidmBroadcast = "broadcast" case cidmInternal = "internal" } @@ -604,7 +624,7 @@ protocol ItemContent { var text: String { get } } -enum CIContent: Decodable, ItemContent { +public enum CIContent: Decodable, ItemContent { case sndMsgContent(msgContent: MsgContent) case rcvMsgContent(msgContent: MsgContent) case sndDeleted(deleteMode: CIDeleteMode) @@ -613,7 +633,7 @@ enum CIContent: Decodable, ItemContent { case rcvCall(status: CICallStatus, duration: Int) case rcvIntegrityError(msgError: MsgErrorType) - var text: String { + public var text: String { get { switch self { case let .sndMsgContent(mc): return mc.text @@ -627,7 +647,7 @@ enum CIContent: Decodable, ItemContent { } } - var msgContent: MsgContent? { + public var msgContent: MsgContent? { get { switch self { case let .sndMsgContent(mc): return mc @@ -638,17 +658,17 @@ enum CIContent: Decodable, ItemContent { } } -struct CIQuote: Decodable, ItemContent { +public struct CIQuote: Decodable, ItemContent { var chatDir: CIDirection? var itemId: Int64? var sharedMsgId: String? = nil var sentAt: Date - var content: MsgContent - var formattedText: [FormattedText]? + public var content: MsgContent + public var formattedText: [FormattedText]? - var text: String { get { content.text } } + public var text: String { get { content.text } } - func getSender(_ currentUser: User?) -> String? { + public func getSender(_ currentUser: User?) -> String? { switch (chatDir) { case .directSnd: return "you" case .directRcv: return nil @@ -658,7 +678,7 @@ struct CIQuote: Decodable, ItemContent { } } - static func getSample(_ itemId: Int64?, _ sentAt: Date, _ text: String, chatDir: CIDirection?, image: String? = nil) -> CIQuote { + public static func getSample(_ itemId: Int64?, _ sentAt: Date, _ text: String, chatDir: CIDirection?, image: String? = nil) -> CIQuote { let mc: MsgContent if let image = image { mc = .image(text: text, image: image) @@ -669,14 +689,14 @@ struct CIQuote: Decodable, ItemContent { } } -struct CIFile: Decodable { - var fileId: Int64 - var fileName: String - var fileSize: Int64 - var filePath: String? - var fileStatus: CIFileStatus +public struct CIFile: Decodable { + public var fileId: Int64 + public var fileName: String + public var fileSize: Int64 + public var filePath: String? + public var fileStatus: CIFileStatus - static func getSample(fileId: Int64 = 1, fileName: String = "test.txt", fileSize: Int64 = 100, filePath: String? = "test.txt", fileStatus: CIFileStatus = .rcvComplete) -> CIFile { + public static func getSample(fileId: Int64 = 1, fileName: String = "test.txt", fileSize: Int64 = 100, filePath: String? = "test.txt", fileStatus: CIFileStatus = .rcvComplete) -> CIFile { CIFile(fileId: fileId, fileName: fileName, fileSize: fileSize, filePath: filePath, fileStatus: fileStatus) } @@ -697,7 +717,7 @@ struct CIFile: Decodable { } } -enum CIFileStatus: String, Decodable { +public enum CIFileStatus: String, Decodable { case sndStored = "snd_stored" case sndTransfer = "snd_transfer" case sndComplete = "snd_complete" @@ -709,7 +729,7 @@ enum CIFileStatus: String, Decodable { case rcvCancelled = "rcv_cancelled" } -enum MsgContent { +public enum MsgContent { case text(String) case link(text: String, preview: LinkPreview) case image(text: String, image: String) @@ -738,7 +758,7 @@ enum MsgContent { } } - func isFile() -> Bool { + public func isFile() -> Bool { switch self { case .file: return true default: return false @@ -754,7 +774,7 @@ enum MsgContent { } extension MsgContent: Decodable { - init(from decoder: Decoder) throws { + public init(from decoder: Decoder) throws { do { let container = try decoder.container(keyedBy: CodingKeys.self) let type = try container.decode(String.self, forKey: CodingKeys.type) @@ -784,7 +804,7 @@ extension MsgContent: Decodable { } extension MsgContent: Encodable { - func encode(to encoder: Encoder) throws { + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) switch self { case let .text(text): @@ -809,12 +829,12 @@ extension MsgContent: Encodable { } } -struct FormattedText: Decodable { - var text: String - var format: Format? +public struct FormattedText: Decodable { + public var text: String + public var format: Format? } -enum Format: Decodable, Equatable { +public enum Format: Decodable, Equatable { case bold case italic case strikeThrough @@ -826,7 +846,7 @@ enum Format: Decodable, Equatable { case phone } -enum FormatColor: String, Decodable { +public enum FormatColor: String, Decodable { case red = "red" case green = "green" case blue = "blue" @@ -836,7 +856,7 @@ enum FormatColor: String, Decodable { case black = "black" case white = "white" - var uiColor: Color { + public var uiColor: Color { get { switch (self) { case .red: return .red @@ -853,15 +873,22 @@ enum FormatColor: String, Decodable { } // Struct to use with simplex API -struct LinkPreview: Codable { - var uri: URL - var title: String +public struct LinkPreview: Codable { + public init(uri: URL, title: String, description: String = "", image: String) { + self.uri = uri + self.title = title + self.description = description + self.image = image + } + + public var uri: URL + public var title: String // TODO remove once optional in haskell - var description: String = "" - var image: String + public var description: String = "" + public var image: String } -enum NtfTknStatus: String, Decodable { +public enum NtfTknStatus: String, Decodable { case new = "NEW" case registered = "REGISTERED" case invalid = "INVALID" @@ -870,15 +897,15 @@ enum NtfTknStatus: String, Decodable { case expired = "EXPIRED" } -struct SndFileTransfer: Decodable { +public struct SndFileTransfer: Decodable { } -struct FileTransferMeta: Decodable { +public struct FileTransferMeta: Decodable { } -enum CICallStatus: String, Decodable { +public enum CICallStatus: String, Decodable { case pending case missed case rejected @@ -901,12 +928,12 @@ enum CICallStatus: String, Decodable { } } - static func durationText(_ sec: Int) -> String { + public static func durationText(_ sec: Int) -> String { String(format: "%02d:%02d", sec / 60, sec % 60) } } -enum MsgErrorType: Decodable { +public enum MsgErrorType: Decodable { case msgSkipped(fromMsgId: Int64, toMsgId: Int64) case msgBadId(msgId: Int64) case msgBadHash diff --git a/apps/ios/Shared/FileUtils.swift b/apps/ios/SimpleXChat/FileUtils.swift similarity index 87% rename from apps/ios/Shared/FileUtils.swift rename to apps/ios/SimpleXChat/FileUtils.swift index abb1509653..6cf037a5c5 100644 --- a/apps/ios/Shared/FileUtils.swift +++ b/apps/ios/SimpleXChat/FileUtils.swift @@ -8,17 +8,21 @@ import Foundation import SwiftUI +import OSLog + +let logger = Logger() // maximum image file size to be auto-accepted -let maxImageSize: Int64 = 236700 +public let maxImageSize: Int64 = 236700 -let maxFileSize: Int64 = 8000000 +public let maxFileSize: Int64 = 8000000 func getDocumentsDirectory() -> URL { - FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! +// FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.chat.simplex.app")! } -func getAppFilesDirectory() -> URL { +public func getAppFilesDirectory() -> URL { getDocumentsDirectory().appendingPathComponent("app_files", isDirectory: true) } @@ -26,7 +30,7 @@ func getAppFilePath(_ fileName: String) -> URL { getAppFilesDirectory().appendingPathComponent(fileName) } -func getLoadedFilePath(_ file: CIFile?) -> String? { +public func getLoadedFilePath(_ file: CIFile?) -> String? { if let file = file, file.loaded, let savedFile = file.filePath { @@ -35,14 +39,14 @@ func getLoadedFilePath(_ file: CIFile?) -> String? { return nil } -func getLoadedImage(_ file: CIFile?) -> UIImage? { +public func getLoadedImage(_ file: CIFile?) -> UIImage? { if let filePath = getLoadedFilePath(file) { return UIImage(contentsOfFile: filePath) } return nil } -func saveFileFromURL(_ url: URL) -> String? { +public func saveFileFromURL(_ url: URL) -> String? { let savedFile: String? if url.startAccessingSecurityScopedResource() { do { @@ -61,7 +65,7 @@ func saveFileFromURL(_ url: URL) -> String? { return savedFile } -func saveImage(_ uiImage: UIImage) -> String? { +public func saveImage(_ uiImage: UIImage) -> String? { if let imageDataResized = resizeImageToDataSize(uiImage, maxDataSize: maxImageSize) { let timestamp = Date().getFormattedDate("yyyyMMdd_HHmmss") let fileName = uniqueCombine("IMG_\(timestamp).jpg") @@ -113,7 +117,7 @@ private extension String { } } -func removeFile(_ fileName: String) { +public func removeFile(_ fileName: String) { do { try FileManager.default.removeItem(atPath: getAppFilePath(fileName).path) } catch { @@ -123,7 +127,7 @@ func removeFile(_ fileName: String) { // image utils -func dropImagePrefix(_ s: String) -> String { +public func dropImagePrefix(_ s: String) -> String { dropPrefix(dropPrefix(s, "data:image/png;base64,"), "data:image/jpg;base64,") } @@ -131,7 +135,7 @@ private func dropPrefix(_ s: String, _ prefix: String) -> String { s.hasPrefix(prefix) ? String(s.dropFirst(prefix.count)) : s } -func cropToSquare(_ image: UIImage) -> UIImage { +public func cropToSquare(_ image: UIImage) -> UIImage { let size = image.size let side = min(size.width, size.height) let newSize = CGSize(width: side, height: side) @@ -159,7 +163,7 @@ func resizeImageToDataSize(_ image: UIImage, maxDataSize: Int64) -> Data? { return data } -func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? { +public func resizeImageToStrSize(_ image: UIImage, maxDataSize: Int64) -> String? { var img = image var str = compressImageStr(img) var dataSize = str?.count ?? 0 diff --git a/apps/ios/Shared/Model/Shared/GroupDefaults.swift b/apps/ios/SimpleXChat/GroupDefaults.swift similarity index 54% rename from apps/ios/Shared/Model/Shared/GroupDefaults.swift rename to apps/ios/SimpleXChat/GroupDefaults.swift index ca5aaef410..f7fc3fa26f 100644 --- a/apps/ios/Shared/Model/Shared/GroupDefaults.swift +++ b/apps/ios/SimpleXChat/GroupDefaults.swift @@ -9,20 +9,22 @@ import Foundation import SwiftUI +let GROUP_DEFAULT_APP_IN_BACKGROUND = "appInBackground" + func getGroupDefaults() -> UserDefaults? { - UserDefaults(suiteName: "5NN7GUYB6T.group.chat.simplex.app") + UserDefaults(suiteName: "group.chat.simplex.app") } -func setAppState(_ phase: ScenePhase) { +public func setAppState(_ phase: ScenePhase) { if let defaults = getGroupDefaults() { - defaults.set(phase == .background, forKey: "appInBackground") + defaults.set(phase == .background, forKey: GROUP_DEFAULT_APP_IN_BACKGROUND) defaults.synchronize() } } -func getAppState() -> ScenePhase { +public func getAppState() -> ScenePhase { if let defaults = getGroupDefaults() { - if defaults.bool(forKey: "appInBackground") { + if defaults.bool(forKey: GROUP_DEFAULT_APP_IN_BACKGROUND) { return .background } } diff --git a/apps/ios/Shared/Model/Shared/JSON.swift b/apps/ios/SimpleXChat/JSON.swift similarity index 92% rename from apps/ios/Shared/Model/Shared/JSON.swift rename to apps/ios/SimpleXChat/JSON.swift index 2123c54811..e9dfdef44e 100644 --- a/apps/ios/Shared/Model/Shared/JSON.swift +++ b/apps/ios/SimpleXChat/JSON.swift @@ -8,7 +8,7 @@ import Foundation -func getJSONDecoder() -> JSONDecoder { +public func getJSONDecoder() -> JSONDecoder { let jd = JSONDecoder() let fracSeconds = getDateFormatter("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ") let noFracSeconds = getDateFormatter("yyyy-MM-dd'T'HH:mm:ssZZZZZ") @@ -23,7 +23,7 @@ func getJSONDecoder() -> JSONDecoder { return jd } -func getJSONEncoder() -> JSONEncoder { +public func getJSONEncoder() -> JSONEncoder { let je = JSONEncoder() je.dateEncodingStrategy = .iso8601 return je diff --git a/apps/ios/Shared/Model/Shared/Notifications.swift b/apps/ios/SimpleXChat/Notifications.swift similarity index 76% rename from apps/ios/Shared/Model/Shared/Notifications.swift rename to apps/ios/SimpleXChat/Notifications.swift index 84bb1b5bad..9413e6381b 100644 --- a/apps/ios/Shared/Model/Shared/Notifications.swift +++ b/apps/ios/SimpleXChat/Notifications.swift @@ -10,17 +10,17 @@ import Foundation import UserNotifications import SwiftUI -let ntfCategoryContactRequest = "NTF_CAT_CONTACT_REQUEST" -let ntfCategoryContactConnected = "NTF_CAT_CONTACT_CONNECTED" -let ntfCategoryMessageReceived = "NTF_CAT_MESSAGE_RECEIVED" -let ntfCategoryCallInvitation = "NTF_CAT_CALL_INVITATION" -let ntfCategoryCheckMessage = "NTF_CAT_CHECK_MESSAGE" +public let ntfCategoryContactRequest = "NTF_CAT_CONTACT_REQUEST" +public let ntfCategoryContactConnected = "NTF_CAT_CONTACT_CONNECTED" +public let ntfCategoryMessageReceived = "NTF_CAT_MESSAGE_RECEIVED" +public let ntfCategoryCallInvitation = "NTF_CAT_CALL_INVITATION" +public let ntfCategoryCheckMessage = "NTF_CAT_CHECK_MESSAGE" // TODO remove -let ntfCategoryCheckingMessages = "NTF_CAT_CHECKING_MESSAGES" +public let ntfCategoryCheckingMessages = "NTF_CAT_CHECKING_MESSAGES" -let appNotificationId = "chat.simplex.app.notification" +public let appNotificationId = "chat.simplex.app.notification" -func createContactRequestNtf(_ contactRequest: UserContactRequest) -> UNMutableNotificationContent { +public func createContactRequestNtf(_ contactRequest: UserContactRequest) -> UNMutableNotificationContent { createNotification( categoryIdentifier: ntfCategoryContactRequest, title: String.localizedStringWithFormat(NSLocalizedString("%@ wants to connect!", comment: "notification title"), contactRequest.displayName), @@ -30,7 +30,7 @@ func createContactRequestNtf(_ contactRequest: UserContactRequest) -> UNMutableN ) } -func createContactConnectedNtf(_ contact: Contact) -> UNMutableNotificationContent { +public func createContactConnectedNtf(_ contact: Contact) -> UNMutableNotificationContent { createNotification( categoryIdentifier: ntfCategoryContactConnected, title: String.localizedStringWithFormat(NSLocalizedString("%@ is connected!", comment: "notification title"), contact.displayName), @@ -40,7 +40,7 @@ func createContactConnectedNtf(_ contact: Contact) -> UNMutableNotificationConte ) } -func createMessageReceivedNtf(_ cInfo: ChatInfo, _ cItem: ChatItem) -> UNMutableNotificationContent { +public func createMessageReceivedNtf(_ cInfo: ChatInfo, _ cItem: ChatItem) -> UNMutableNotificationContent { createNotification( categoryIdentifier: ntfCategoryMessageReceived, title: "\(cInfo.chatViewName):", @@ -50,7 +50,7 @@ func createMessageReceivedNtf(_ cInfo: ChatInfo, _ cItem: ChatItem) -> UNMutable ) } -func createCallInvitationNtf(_ invitation: CallInvitation) -> UNMutableNotificationContent { +public func createCallInvitationNtf(_ invitation: CallInvitation) -> UNMutableNotificationContent { let text = invitation.peerMedia == .video ? NSLocalizedString("Incoming video call", comment: "notification") : NSLocalizedString("Incoming audio call", comment: "notification") @@ -63,7 +63,7 @@ func createCallInvitationNtf(_ invitation: CallInvitation) -> UNMutableNotificat ) } -func createNotification(categoryIdentifier: String, title: String, subtitle: String? = nil, body: String? = nil, +public func createNotification(categoryIdentifier: String, title: String, subtitle: String? = nil, body: String? = nil, targetContentIdentifier: String? = nil, userInfo: [AnyHashable : Any] = [:]) -> UNMutableNotificationContent { let content = UNMutableNotificationContent() content.categoryIdentifier = categoryIdentifier diff --git a/apps/ios/SimpleX NSE/SimpleX NSE-Bridging-Header.h b/apps/ios/SimpleXChat/SimpleX.h similarity index 54% rename from apps/ios/SimpleX NSE/SimpleX NSE-Bridging-Header.h rename to apps/ios/SimpleXChat/SimpleX.h index bc28b42d38..dab7fa3eb6 100644 --- a/apps/ios/SimpleX NSE/SimpleX NSE-Bridging-Header.h +++ b/apps/ios/SimpleXChat/SimpleX.h @@ -1,6 +1,15 @@ // -// Use this file to import your target's public headers that you would like to expose to Swift. +// SimpleX.h +// SimpleX // +// Created by Evgeny on 30/05/2022. +// Copyright © 2022 SimpleX Chat. All rights reserved. +// + +#ifndef SimpleX_h +#define SimpleX_h + +#endif /* SimpleX_h */ extern void hs_init(int argc, char **argv[]); diff --git a/apps/ios/SimpleXChat/SimpleXChat.docc/SimpleXChat.md b/apps/ios/SimpleXChat/SimpleXChat.docc/SimpleXChat.md new file mode 100755 index 0000000000..2ab4ef5f06 --- /dev/null +++ b/apps/ios/SimpleXChat/SimpleXChat.docc/SimpleXChat.md @@ -0,0 +1,13 @@ +# ``SimpleXChat`` + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` \ No newline at end of file diff --git a/apps/ios/SimpleXChat/SimpleXChat.h b/apps/ios/SimpleXChat/SimpleXChat.h new file mode 100644 index 0000000000..c109fc9412 --- /dev/null +++ b/apps/ios/SimpleXChat/SimpleXChat.h @@ -0,0 +1,17 @@ +// +// SimpleXChat.h +// SimpleXChat +// +// Created by Evgeny on 30/05/2022. +// Copyright © 2022 SimpleX Chat. All rights reserved. +// + +#import + +//! Project version number for SimpleXChat. +FOUNDATION_EXPORT double SimpleXChatVersionNumber; + +//! Project version string for SimpleXChat. +FOUNDATION_EXPORT const unsigned char SimpleXChatVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import diff --git a/apps/ios/SimpleX NSE/dummy.m b/apps/ios/SimpleXChat/dummy.m similarity index 89% rename from apps/ios/SimpleX NSE/dummy.m rename to apps/ios/SimpleXChat/dummy.m index adef540363..64fbc32dd3 100644 --- a/apps/ios/SimpleX NSE/dummy.m +++ b/apps/ios/SimpleXChat/dummy.m @@ -1,8 +1,8 @@ // // dummy.m -// SimpleX NSE +// SimpleXChat // -// Created by Evgeny on 26/04/2022. +// Created by Evgeny on 30/05/2022. // Copyright © 2022 SimpleX Chat. All rights reserved. //