瀏覽代碼

remove mailboxPointer, move native method calls to Wrapper

cyberta 5 年之前
父節點
當前提交
29082e4b59

+ 41 - 75
deltachat-ios/AppDelegate.swift

@@ -5,7 +5,6 @@ import SwiftyBeaver
 import UIKit
 import UserNotifications
 
-var mailboxPointer: OpaquePointer!
 let logger = SwiftyBeaver.self
 
 enum ApplicationState {
@@ -31,19 +30,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
     var state = ApplicationState.stopped
 
-    private func getCoreInfo() -> [[String]] {
-        if let cString = dc_get_info(mailboxPointer) {
-            let info = String(cString: cString)
-            dc_str_unref(cString)
-            logger.info(info)
-            return info.components(separatedBy: "\n").map { val in
-                val.components(separatedBy: "=")
-            }
-        }
-
-        return []
-    }
-
     func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
         // gets here when app returns from oAuth2-Setup process - the url contains the provided token
         if let params = url.queryParameters, let token = params["code"] {
@@ -148,64 +134,52 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
     func open() {
         logger.info("open: \(dbfile())")
-
-        if mailboxPointer == nil {
-            mailboxPointer = dcContext.contextPointer
-            guard mailboxPointer != nil else {
-                fatalError("Error: dc_context_new returned nil")
-            }
-        }
-        _ = dc_open(mailboxPointer, dbfile(), nil)
+        dcContext.openDatabase(dbFile: dbfile())
     }
 
     func setStockTranslations() {
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_NOMESSAGES), String.localized("chat_no_messages"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_SELF), String.localized("self"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_DRAFT), String.localized("draft"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_VOICEMESSAGE), String.localized("voice_message"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_DEADDROP), String.localized("chat_contact_request"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_IMAGE), String.localized("image"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_VIDEO), String.localized("video"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_AUDIO), String.localized("audio"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_FILE), String.localized("file"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_STATUSLINE), String.localized("pref_default_status_text"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_NEWGROUPDRAFT), String.localized("group_hello_draft"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGGRPNAME), String.localized("systemmsg_group_name_changed"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGGRPIMGCHANGED), String.localized("systemmsg_group_image_changed"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGADDMEMBER), String.localized("systemmsg_member_added"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGDELMEMBER), String.localized("systemmsg_member_removed"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGGROUPLEFT), String.localized("systemmsg_group_left"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_GIF), String.localized("gif"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_CANTDECRYPT_MSG_BODY), String.localized("systemmsg_cannot_decrypt"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_READRCPT), String.localized("systemmsg_read_receipt_subject"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_READRCPT_MAILBODY), String.localized("systemmsg_read_receipt_body"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGGRPIMGDELETED), String.localized("systemmsg_group_image_deleted"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_CONTACT_VERIFIED), String.localized("contact_verified"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_CONTACT_NOT_VERIFIED), String.localized("contact_not_verified"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_CONTACT_SETUP_CHANGED), String.localized("contact_setup_changed"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_ARCHIVEDCHATS), String.localized("chat_archived_chats_title"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_AC_SETUP_MSG_SUBJECT), String.localized("autocrypt_asm_subject"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_AC_SETUP_MSG_BODY), String.localized("autocrypt_asm_general_body"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_CANNOT_LOGIN), String.localized("login_error_cannot_login"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_SERVER_RESPONSE), String.localized("login_error_server_response"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGACTIONBYUSER), String.localized("systemmsg_action_by_user"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_MSGACTIONBYME), String.localized("systemmsg_action_by_me"))
-        dc_set_stock_translation(mailboxPointer, UInt32(DC_STR_DEVICE_MESSAGES), String.localized("device_talk"))
+        dcContext.setStockTranslation(id: DC_STR_NOMESSAGES, localizationKey: "chat_no_messages")
+        dcContext.setStockTranslation(id: DC_STR_SELF, localizationKey: "self")
+        dcContext.setStockTranslation(id: DC_STR_DRAFT, localizationKey: "draft")
+        dcContext.setStockTranslation(id: DC_STR_VOICEMESSAGE, localizationKey: "voice_message")
+        dcContext.setStockTranslation(id: DC_STR_DEADDROP, localizationKey: "chat_contact_request")
+        dcContext.setStockTranslation(id: DC_STR_IMAGE, localizationKey: "image")
+        dcContext.setStockTranslation(id: DC_STR_VIDEO, localizationKey: "video")
+        dcContext.setStockTranslation(id: DC_STR_AUDIO, localizationKey: "audio")
+        dcContext.setStockTranslation(id: DC_STR_FILE, localizationKey: "file")
+        dcContext.setStockTranslation(id: DC_STR_STATUSLINE, localizationKey: "pref_default_status_text")
+        dcContext.setStockTranslation(id: DC_STR_NEWGROUPDRAFT, localizationKey: "group_hello_draft")
+        dcContext.setStockTranslation(id: DC_STR_MSGGRPNAME, localizationKey: "systemmsg_group_name_changed")
+        dcContext.setStockTranslation(id: DC_STR_MSGGRPIMGCHANGED, localizationKey: "systemmsg_group_image_changed")
+        dcContext.setStockTranslation(id: DC_STR_MSGADDMEMBER, localizationKey: "systemmsg_member_added")
+        dcContext.setStockTranslation(id: DC_STR_MSGDELMEMBER, localizationKey: "systemmsg_member_removed")
+        dcContext.setStockTranslation(id: DC_STR_MSGGROUPLEFT, localizationKey: "systemmsg_group_left")
+        dcContext.setStockTranslation(id: DC_STR_GIF, localizationKey: "gif")
+        dcContext.setStockTranslation(id: DC_STR_CANTDECRYPT_MSG_BODY, localizationKey: "systemmsg_cannot_decrypt")
+        dcContext.setStockTranslation(id: DC_STR_READRCPT, localizationKey: "systemmsg_read_receipt_subject")
+        dcContext.setStockTranslation(id: DC_STR_READRCPT_MAILBODY, localizationKey: "systemmsg_read_receipt_body")
+        dcContext.setStockTranslation(id: DC_STR_MSGGRPIMGDELETED, localizationKey: "systemmsg_group_image_deleted")
+        dcContext.setStockTranslation(id: DC_STR_CONTACT_VERIFIED, localizationKey: "contact_verified")
+        dcContext.setStockTranslation(id: DC_STR_CONTACT_NOT_VERIFIED, localizationKey: "contact_not_verified")
+        dcContext.setStockTranslation(id: DC_STR_CONTACT_SETUP_CHANGED, localizationKey: "contact_setup_changed")
+        dcContext.setStockTranslation(id: DC_STR_ARCHIVEDCHATS, localizationKey: "chat_archived_chats_title")
+        dcContext.setStockTranslation(id: DC_STR_AC_SETUP_MSG_SUBJECT, localizationKey: "autocrypt_asm_subject")
+        dcContext.setStockTranslation(id: DC_STR_AC_SETUP_MSG_BODY, localizationKey: "autocrypt_asm_general_body")
+        dcContext.setStockTranslation(id: DC_STR_CANNOT_LOGIN, localizationKey: "login_error_cannot_login")
+        dcContext.setStockTranslation(id: DC_STR_SERVER_RESPONSE, localizationKey: "login_error_server_response")
+        dcContext.setStockTranslation(id: DC_STR_MSGACTIONBYUSER, localizationKey: "systemmsg_action_by_user")
+        dcContext.setStockTranslation(id: DC_STR_MSGACTIONBYME, localizationKey: "systemmsg_action_by_me")
+        dcContext.setStockTranslation(id: DC_STR_DEVICE_MESSAGES, localizationKey: "device_talk")
     }
 
     func stop() {
         state = .background
-
-        dc_interrupt_imap_idle(mailboxPointer)
-        dc_interrupt_smtp_idle(mailboxPointer)
-        dc_interrupt_mvbox_idle(mailboxPointer)
-        dc_interrupt_sentbox_idle(mailboxPointer)
+        dcContext.interruptIdle()
     }
 
     func close() {
         state = .stopped
-        dc_close(mailboxPointer)
-        mailboxPointer = nil
+        dcContext.closeDatabase()
     }
 
     func start(_ completion: (() -> Void)? = nil) {
@@ -214,15 +188,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         if state == .running {
             return
         }
-
         state = .running
 
         DispatchQueue.global(qos: .background).async {
             self.registerBackgroundTask()
             while self.state == .running {
-                dc_perform_imap_jobs(mailboxPointer)
-                dc_perform_imap_fetch(mailboxPointer)
-                dc_perform_imap_idle(mailboxPointer)
+                self.dcContext.performImap()
             }
             if self.backgroundTask != .invalid {
                 completion?()
@@ -233,8 +204,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         DispatchQueue.global(qos: .utility).async {
             self.registerBackgroundTask()
             while self.state == .running {
-                dc_perform_smtp_jobs(mailboxPointer)
-                dc_perform_smtp_idle(mailboxPointer)
+                self.dcContext.performSmtp()
             }
             if self.backgroundTask != .invalid {
                 self.endBackgroundTask()
@@ -243,17 +213,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
         DispatchQueue.global(qos: .background).async {
             while self.state == .running {
-                dc_perform_sentbox_jobs(mailboxPointer)
-                dc_perform_sentbox_fetch(mailboxPointer)
-                dc_perform_sentbox_idle(mailboxPointer)
+                self.dcContext.performSentbox()
             }
         }
 
         DispatchQueue.global(qos: .background).async {
             while self.state == .running {
-                dc_perform_mvbox_jobs(mailboxPointer)
-                dc_perform_mvbox_fetch(mailboxPointer)
-                dc_perform_mvbox_idle(mailboxPointer)
+                self.dcContext.performMoveBox()
             }
         }
 
@@ -265,7 +231,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
             logger.info("could not start reachability notifier")
         }
 
-        let info: [DBCustomVariable] = getCoreInfo().map { kv in
+        let info: [DBCustomVariable] = dcContext.getInfo().map { kv in
             let value = kv.count > 1 ? kv[1] : ""
             return DBCustomVariable(name: kv[0], value: value)
         }
@@ -288,7 +254,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
             // however, in fact, it may halt things for some seconds.
             // this pr is a workaround that make things usable for now.
             DispatchQueue.global(qos: .background).async {
-                dc_maybe_network(mailboxPointer)
+                self.dcContext.maybeNetwork()
             }
         case .none:
             logger.info("network: not reachable")

+ 4 - 6
deltachat-ios/Controller/AccountSetupController.swift

@@ -358,7 +358,7 @@ class AccountSetupController: UITableViewController {
             style: .done,
             target: self,
             action: #selector(loginButtonPressed))
-        button.isEnabled = dc_is_configured(mailboxPointer) == 0
+        button.isEnabled = !dcContext.isConfigured()
         return button
     }()
 
@@ -611,7 +611,7 @@ class AccountSetupController: UITableViewController {
         }
 
         print("oAuth-Flag when loggin in: \(dcContext.getAuthFlags())")
-        dc_configure(mailboxPointer)
+        dcContext.configure()
         showProgressHud(title: String.localized("login_header"))
     }
 
@@ -755,12 +755,10 @@ class AccountSetupController: UITableViewController {
         if !documents.isEmpty {
             logger.info("looking for backup in: \(documents[0])")
 
-            if let cString = dc_imex_has_backup(mailboxPointer, documents[0]) {
-                let file = String(cString: cString)
-                dc_str_unref(cString)
+            if let file = dcContext.imexHasBackup(filePath: documents[0]) {
                 logger.info("restoring backup: \(file)")
                 showProgressHud(title: String.localized("import_backup_title"))
-                dc_imex(mailboxPointer, DC_IMEX_IMPORT_BACKUP, file, nil)
+                dcContext.imex(what: DC_IMEX_IMPORT_BACKUP, directory: file)
             }
             else {
                 let alert = UIAlertController(

+ 7 - 22
deltachat-ios/Controller/ChatViewController.swift

@@ -205,7 +205,7 @@ class ChatViewController: MessagesViewController {
         // things that do not affect the chatview
         // and are delayed after the view is displayed
         dcContext.marknoticedChat(chatId: chatId)
-        let array = DcArray(arrayPointer: dc_get_fresh_msgs(mailboxPointer))
+        let array = dcContext.getFreshMessages()
         UIApplication.shared.applicationIconBadgeNumber = array.count
         startTimer()
     }
@@ -350,21 +350,11 @@ class ChatViewController: MessagesViewController {
     }
 
     private var textDraft: String? {
-        if let draft = dc_get_draft(mailboxPointer, UInt32(chatId)) {
-            if let cString = dc_msg_get_text(draft) {
-                let swiftString = String(cString: cString)
-                dc_str_unref(cString)
-                dc_msg_unref(draft)
-                return swiftString
-            }
-            dc_msg_unref(draft)
-            return nil
-        }
-        return nil
+        return dcContext.getDraft(chatId: chatId)
     }
 
     private func getMessageIds(_ count: Int, from: Int? = nil) -> [DcMsg] {
-        let cMessageIds = dc_get_chat_msgs(mailboxPointer, UInt32(chatId), 0, 0)
+        let cMessageIds = dcContext.getChatMessages(chatId: chatId)
 
         let ids: [Int]
         if let from = from {
@@ -374,7 +364,7 @@ class ChatViewController: MessagesViewController {
         }
 
         let markIds: [UInt32] = ids.map { UInt32($0) }
-        dc_markseen_msgs(mailboxPointer, UnsafePointer(markIds), Int32(ids.count))
+        dcContext.markSeenMessages(messageIds: markIds, count: ids.count)
 
         return ids.map {
             DcMsg(id: $0)
@@ -383,12 +373,7 @@ class ChatViewController: MessagesViewController {
 
     @objc private func setTextDraft() {
         if let text = self.messageInputBar.inputTextView.text {
-            let draft = dc_msg_new(mailboxPointer, DC_MSG_TEXT)
-            dc_msg_set_text(draft, text.cString(using: .utf8))
-            dc_set_draft(mailboxPointer, UInt32(chatId), draft)
-
-            // cleanup
-            dc_msg_unref(draft)
+            dcContext.setDraft(chatId: chatId, draftText: text)
         }
     }
 
@@ -889,7 +874,7 @@ extension ChatViewController: MessagesDataSource {
 
     func updateMessage(_ messageId: Int) {
         if let index = messageList.firstIndex(where: { $0.id == messageId }) {
-            dc_markseen_msgs(mailboxPointer, UnsafePointer([UInt32(messageId)]), 1)
+            dcContext.markSeenMessages(messageIds: [UInt32(messageId)])
 
             messageList[index] = DcMsg(id: messageId)
             // Reload section to update header/footer labels
@@ -915,7 +900,7 @@ extension ChatViewController: MessagesDataSource {
     }
 
     func insertMessage(_ message: DcMsg) {
-        dc_markseen_msgs(mailboxPointer, UnsafePointer([UInt32(message.id)]), 1)
+        dcContext.markSeenMessages(messageIds: [UInt32(message.id)])
         messageList.append(message)
         emptyStateView.isHidden = true
         // Reload last section to update header/footer labels and insert a new one

+ 1 - 1
deltachat-ios/Controller/EditContactController.swift

@@ -28,7 +28,7 @@ class EditContactController: NewContactController {
     }
 
     @objc override func saveContactButtonPressed() {
-        dc_create_contact(mailboxPointer, model.name, model.email)
+        dcContext.createContact(name: model.name, email: model.email)
         coordinator?.navigateBack()
     }
 

+ 1 - 1
deltachat-ios/Controller/EditGroupViewController.swift

@@ -77,7 +77,7 @@ class EditGroupViewController: UITableViewController, MediaPickerDelegate {
         if let groupImage = groupImage, let dcContext = coordinator?.dcContext {
             AvatarHelper.saveChatAvatar(dcContext: dcContext, image: groupImage, for: Int(chat.id))
         }
-        dc_set_chat_name(mailboxPointer, UInt32(chat.id), newName)
+        DcContext.getInstance().setChatName(chatId: chat.id, name: newName ?? "")
         coordinator?.navigateBack()
     }
 

+ 1 - 1
deltachat-ios/Controller/EditSettingsController.swift

@@ -70,7 +70,7 @@ class EditSettingsController: UITableViewController, MediaPickerDelegate {
     override func viewWillDisappear(_ animated: Bool) {
         dcContext.selfstatus = statusCell.getText()
         dcContext.displayname = nameCell.getText()
-        dc_configure(mailboxPointer)
+        dcContext.configure()
     }
 
     // MARK: - Table view data source

+ 3 - 3
deltachat-ios/Controller/GroupChatDetailViewController.swift

@@ -346,8 +346,8 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
                 let title = String.localizedStringWithFormat(String.localized("ask_remove_members"), contact.nameNAddr)
                 let alert = UIAlertController(title: title, message: nil, preferredStyle: .safeActionSheet)
                 alert.addAction(UIAlertAction(title: String.localized("remove_desktop"), style: .destructive, handler: { _ in
-                    let success = dc_remove_contact_from_chat(mailboxPointer, UInt32(self.chat.id), UInt32(contact.id))
-                    if success == 1 {
+                    let success = self.context.removeContactFromChat(chatId: self.chat.id, contactId: contact.id)
+                    if success {
                         self.removeGroupMemberFromTableAt(indexPath)
                     }
                 }))
@@ -391,7 +391,7 @@ extension GroupChatDetailViewController {
         if let userId = currentUser?.id {
             let alert = UIAlertController(title: String.localized("ask_leave_group"), message: nil, preferredStyle: .safeActionSheet)
             alert.addAction(UIAlertAction(title: String.localized("menu_leave_group"), style: .destructive, handler: { _ in
-                dc_remove_contact_from_chat(mailboxPointer, UInt32(self.chat.id), UInt32(userId))
+                let _ = self.context.removeContactFromChat(chatId: self.chat.id, contactId: userId)
                 self.editBarButtonItem.isEnabled = false
                 self.updateGroupMembers()
             }))

+ 7 - 7
deltachat-ios/Controller/GroupMembersViewController.swift

@@ -2,7 +2,6 @@ import UIKit
 
 class NewGroupAddMembersViewController: GroupMembersViewController {
     weak var coordinator: NewGroupAddMembersCoordinator?
-    let dcContext: DcContext
 
     var onMembersSelected: ((Set<Int>) -> Void)?
     let isVerifiedGroup: Bool
@@ -17,8 +16,7 @@ class NewGroupAddMembersViewController: GroupMembersViewController {
        return button
    }()
 
-    init(dcContext: DcContext, preselected: Set<Int>, isVerified: Bool) {
-        self.dcContext = dcContext
+    init(preselected: Set<Int>, isVerified: Bool) {
         isVerifiedGroup = isVerified
         super.init()
         selectedContactIds = preselected
@@ -192,7 +190,7 @@ class AddGroupMembersViewController: GroupMembersViewController {
     }
 
     func loadMemberCandidates() -> [Int] {
-        var contactIds = Utils.getContactIds()
+        var contactIds = dcContext.getContacts(flags: 0)
         let memberSet = Set(chatMemberIds)
         contactIds.removeAll(where: { memberSet.contains($0)})
         return Array(contactIds)
@@ -207,7 +205,7 @@ class AddGroupMembersViewController: GroupMembersViewController {
             return
         }
         for contactId in selectedContactIds {
-            dc_add_contact_to_chat(mailboxPointer, UInt32(chatId), UInt32(contactId))
+           _ = dcContext.addContactToChat(chatId: chatId, contactId: contactId)
         }
         navigationController?.popViewController(animated: true)
     }
@@ -241,7 +239,7 @@ class BlockedContactsViewController: GroupMembersViewController, GroupMemberSele
     override func viewDidLoad() {
         super.viewDidLoad()
         title = String.localized("pref_blocked_contacts")
-        contactIds = Utils.getBlockedContactIds()
+        contactIds = dcContext.getBlockedContacts()
         selectedContactIds = Set(contactIds)
         navigationItem.searchController = nil
         groupMemberSelectionDelegate = self
@@ -259,7 +257,7 @@ class BlockedContactsViewController: GroupMembersViewController, GroupMemberSele
             alert.addAction(UIAlertAction(title: String.localized("menu_unblock_contact"), style: .default, handler: { _ in
                 let contact = DcContact(id: contactId)
                 contact.unblock()
-                self.contactIds = Utils.getBlockedContactIds()
+                self.contactIds = self.dcContext.getBlockedContacts()
                 self.selectedContactIds = Set(self.contactIds)
                 self.tableView.reloadData()
             }))
@@ -281,6 +279,7 @@ class GroupMembersViewController: UITableViewController, UISearchResultsUpdating
     weak var groupMemberSelectionDelegate: GroupMemberSelectionDelegate?
     var enableCheckmarks = true
     var numberOfSections = 1
+    let dcContext: DcContext
 
     var contactIds: [Int] = [] {
         didSet {
@@ -325,6 +324,7 @@ class GroupMembersViewController: UITableViewController, UISearchResultsUpdating
     var selectedContactIds: Set<Int> = []
 
     init() {
+        self.dcContext = DcContext.getInstance()
         super.init(style: .grouped)
         hidesBottomBarWhenPushed = true
     }

+ 1 - 1
deltachat-ios/Controller/NewContactController.swift

@@ -2,7 +2,7 @@ import UIKit
 
 class NewContactController: UITableViewController {
 
-    private let dcContext: DcContext
+    let dcContext: DcContext
     weak var coordinator: EditContactCoordinatorProtocol?
     var openChatOnSave = true
 

+ 2 - 2
deltachat-ios/Controller/SettingsController.swift

@@ -321,13 +321,13 @@ internal final class SettingsViewController: UITableViewController {
     private func handleReceiptConfirmationToggle() {
         receiptConfirmationSwitch.isOn = !receiptConfirmationSwitch.isOn
         dcContext.mdnsEnabled = receiptConfirmationSwitch.isOn
-        dc_configure(mailboxPointer)
+        dcContext.configure()
     }
 
     private func handleAutocryptPreferencesToggle() {
         autocryptSwitch.isOn = !autocryptSwitch.isOn
         dcContext.e2eeEnabled = autocryptSwitch.isOn
-        dc_configure(mailboxPointer)
+        dcContext.configure()
     }
 
     private func sendAutocryptSetupMessage() {

+ 2 - 3
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -203,7 +203,7 @@ class ChatListCoordinator: Coordinator {
     }
 
     func showNewChat(contactId: Int) {
-        let chatId = dc_create_chat_by_contact_id(mailboxPointer, UInt32(contactId))
+        let chatId = dcContext.createChatByContactId(contactId: contactId)
         showChat(chatId: Int(chatId))
     }
 }
@@ -623,8 +623,7 @@ class NewGroupCoordinator: Coordinator {
     }
 
     func showAddMembers(preselectedMembers: Set<Int>, isVerified: Bool) {
-        let newGroupController = NewGroupAddMembersViewController(dcContext: dcContext,
-                                                                  preselected: preselectedMembers,
+        let newGroupController = NewGroupAddMembersViewController(preselected: preselectedMembers,
                                                                   isVerified: isVerified)
         let coordinator = NewGroupAddMembersCoordinator(dcContext: dcContext, navigationController: navigationController)
         childCoordinators.append(coordinator)

+ 113 - 0
deltachat-ios/DC/Wrapper.swift

@@ -36,6 +36,11 @@ class DcContext {
         return Utils.copyAndFreeArray(inputArray: cContacts)
     }
 
+    func getBlockedContacts() -> [Int] {
+        let cBlockedContacts = dc_get_blocked_contacts(contextPointer)
+        return Utils.copyAndFreeArray(inputArray: cBlockedContacts)
+    }
+
     func addContacts(contactString: String) {
         dc_add_address_book(contextPointer, contactString)
     }
@@ -135,6 +140,96 @@ class DcContext {
         dc_stop_ongoing_process(contextPointer)
     }
 
+    func getInfo() -> [[String]] {
+        if let cString = dc_get_info(contextPointer) {
+            let info = String(cString: cString)
+            dc_str_unref(cString)
+            logger.info(info)
+            return info.components(separatedBy: "\n").map { val in
+                val.components(separatedBy: "=")
+            }
+        }
+        return []
+    }
+
+    func interruptIdle() {
+        dc_interrupt_imap_idle(contextPointer)
+        dc_interrupt_smtp_idle((contextPointer))
+        dc_interrupt_mvbox_idle((contextPointer))
+        dc_interrupt_sentbox_idle((contextPointer))
+    }
+
+    func openDatabase(dbFile: String) {
+        _ = dc_open(contextPointer, dbFile, nil)
+    }
+
+    func closeDatabase() {
+        dc_close(contextPointer)
+    }
+
+    func performImap() {
+        dc_perform_imap_jobs(contextPointer)
+        dc_perform_imap_fetch(contextPointer)
+        dc_perform_imap_idle(contextPointer)
+    }
+
+    func performMoveBox() {
+        dc_perform_mvbox_jobs(contextPointer)
+        dc_perform_mvbox_fetch(contextPointer)
+        dc_perform_mvbox_idle(contextPointer)
+    }
+
+    func performSmtp() {
+        dc_perform_smtp_jobs(contextPointer)
+        dc_perform_smtp_idle(contextPointer)
+    }
+
+    func performSentbox() {
+        dc_perform_sentbox_jobs(contextPointer)
+        dc_perform_sentbox_fetch(contextPointer)
+        dc_perform_sentbox_idle(contextPointer)
+    }
+
+    func setStockTranslation(id: Int32, localizationKey: String) {
+        dc_set_stock_translation(contextPointer, UInt32(id), String.localized(localizationKey))
+    }
+
+    func getDraft(chatId: Int) -> String? {
+        if let draft = dc_get_draft(contextPointer, UInt32(chatId)) {
+            if let cString = dc_msg_get_text(draft) {
+                let swiftString = String(cString: cString)
+                dc_str_unref(cString)
+                dc_msg_unref(draft)
+                return swiftString
+            }
+            dc_msg_unref(draft)
+            return nil
+        }
+        return nil
+    }
+
+    func setDraft(chatId: Int, draftText: String) {
+        let draft = dc_msg_new(contextPointer, DC_MSG_TEXT)
+        dc_msg_set_text(draft, draftText.cString(using: .utf8))
+        dc_set_draft(contextPointer, UInt32(chatId), draft)
+
+        // cleanup
+        dc_msg_unref(draft)
+    }
+
+    func getFreshMessages() -> DcArray {
+        return DcArray(arrayPointer: dc_get_fresh_msgs(contextPointer))
+    }
+
+    func markSeenMessages(messageIds: [UInt32], count: Int = 1) {
+        let ptr = UnsafePointer(messageIds)
+        dc_markseen_msgs(contextPointer, ptr, Int32(count))
+    }
+
+    func getChatMessages(chatId: Int) -> OpaquePointer {
+        return dc_get_chat_msgs(contextPointer, UInt32(chatId), 0, 0)
+    }
+    
     func getMsgInfo(msgId: Int) -> String {
         if let cString = dc_get_msg_info(self.contextPointer, UInt32(msgId)) {
             let swiftString = String(cString: cString)
@@ -169,6 +264,10 @@ class DcContext {
         return dc_continue_key_transfer(self.contextPointer, UInt32(msgId), setupCode) != 0
     }
 
+    func configure() {
+        dc_configure(contextPointer)
+    }
+
     func getConfig(_ key: String) -> String? {
         guard let cString = dc_get_config(self.contextPointer, key) else { return nil }
         let value = String(cString: cString)
@@ -261,6 +360,15 @@ class DcContext {
         dc_imex(contextPointer, what, directory, nil)
     }
 
+    func imexHasBackup(filePath: String) -> String? {
+        var file: String? = nil
+        if let cString = dc_imex_has_backup(contextPointer, filePath) {
+            file = String(cString: cString)
+            dc_str_unref(cString)
+        }
+        return file
+    }
+
     func isSendingLocationsToChat(chatId: Int) -> Bool {
         return dc_is_sending_locations_to_chat(contextPointer, UInt32(chatId)) == 1
     }
@@ -281,6 +389,11 @@ class DcContext {
         return messageIds
     }
 
+    // call dc_maybe_network() from a worker thread.
+    func maybeNetwork() {
+        dc_maybe_network(contextPointer)
+    }
+
     // also, there is no much worth in adding a separate function or so
     // for each config option - esp. if they are just forwarded to the core
     // and set/get only at one line of code each.

+ 1 - 1
deltachat-ios/DC/events.swift

@@ -131,7 +131,7 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
                 logger.info("notifications: added \(content)")
             }
 
-            let array = DcArray(arrayPointer: dc_get_fresh_msgs(mailboxPointer))
+            let array = DcContext.getInstance().getFreshMessages()
             UIApplication.shared.applicationIconBadgeNumber = array.count
         }
 

+ 0 - 11
deltachat-ios/Helper/Utils.swift

@@ -4,17 +4,6 @@ import AVFoundation
 
 struct Utils {
 
-    // do not use, use DcContext::getContacts() instead
-    static func getContactIds() -> [Int] {
-        let cContacts = dc_get_contacts(mailboxPointer, 0, nil)
-        return Utils.copyAndFreeArray(inputArray: cContacts)
-    }
-
-    static func getBlockedContactIds() -> [Int] {
-        let cBlockedContacts = dc_get_blocked_contacts(mailboxPointer)
-        return Utils.copyAndFreeArray(inputArray: cBlockedContacts)
-    }
-
     static func getInitials(inputName: String) -> String {
         if let firstLetter = inputName.first {
             return firstLetter.uppercased()