Quellcode durchsuchen

Merge pull request #623 from deltachat/shared_framework

DcCore framework
nayooti vor 5 Jahren
Ursprung
Commit
e06c398ae8
61 geänderte Dateien mit 2326 neuen und 279 gelöschten Zeilen
  1. 585 0
      DcCore/DcCore.xcodeproj/project.pbxproj
  2. 7 0
      DcCore/DcCore.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  3. 8 0
      DcCore/DcCore.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  4. 8 0
      DcCore/DcCore/DC/Logger.swift
  5. 1180 0
      DcCore/DcCore/DC/Wrapper.swift
  6. 28 28
      DcCore/DcCore/DC/events.swift
  7. 0 0
      DcCore/DcCore/DC/wrapper.c
  8. 0 0
      DcCore/DcCore/DC/wrapper.h
  9. 13 0
      DcCore/DcCore/DcCore.h
  10. 23 0
      DcCore/DcCore/Extensions/String+Extensions.swift
  11. 64 0
      DcCore/DcCore/Extensions/UIColor+Extensions.swift
  12. 11 0
      DcCore/DcCore/Helper/Constants.swift
  13. 78 0
      DcCore/DcCore/Helper/DateUtils.swift
  14. 54 0
      DcCore/DcCore/Helper/DcUtils.swift
  15. 22 0
      DcCore/DcCore/Info.plist
  16. 26 0
      DcCore/DcCoreTests/DcCoreTests.swift
  17. 22 0
      DcCore/DcCoreTests/Info.plist
  18. 35 31
      deltachat-ios.xcodeproj/project.pbxproj
  19. 3 0
      deltachat-ios.xcworkspace/contents.xcworkspacedata
  20. 2 0
      deltachat-ios/AppDelegate.swift
  21. 1 0
      deltachat-ios/Controller/AccountSetup/CertificateCheckController.swift
  22. 1 0
      deltachat-ios/Controller/AccountSetup/SecuritySettingsController.swift
  23. 1 0
      deltachat-ios/Controller/AccountSetupController.swift
  24. 1 0
      deltachat-ios/Controller/ChatListController.swift
  25. 2 9
      deltachat-ios/Controller/ChatViewController.swift
  26. 1 0
      deltachat-ios/Controller/EditContactController.swift
  27. 1 0
      deltachat-ios/Controller/EditGroupViewController.swift
  28. 1 0
      deltachat-ios/Controller/EditSettingsController.swift
  29. 1 0
      deltachat-ios/Controller/GroupChatDetailViewController.swift
  30. 1 0
      deltachat-ios/Controller/GroupMembersViewController.swift
  31. 1 0
      deltachat-ios/Controller/MailboxViewController.swift
  32. 1 0
      deltachat-ios/Controller/MessageInfoViewController.swift
  33. 1 0
      deltachat-ios/Controller/NewChatViewController.swift
  34. 1 0
      deltachat-ios/Controller/NewContactController.swift
  35. 1 0
      deltachat-ios/Controller/NewGroupController.swift
  36. 1 0
      deltachat-ios/Controller/QrInviteViewController.swift
  37. 1 0
      deltachat-ios/Controller/QrViewController.swift
  38. 1 0
      deltachat-ios/Controller/SettingsAutodelOverviewController.swift
  39. 1 0
      deltachat-ios/Controller/SettingsAutodelSetController.swift
  40. 1 1
      deltachat-ios/Controller/SettingsClassicViewController.swift
  41. 1 0
      deltachat-ios/Controller/SettingsController.swift
  42. 1 0
      deltachat-ios/Controller/WelcomeViewController.swift
  43. 1 0
      deltachat-ios/Coordinator/AppCoordinator.swift
  44. 26 0
      deltachat-ios/DC/DcLogger.swift
  45. 93 0
      deltachat-ios/DC/DcMsg+Extension.swift
  46. 1 0
      deltachat-ios/Extensions/DcContact+Extension.swift
  47. 0 19
      deltachat-ios/Extensions/String+Extension.swift
  48. 1 59
      deltachat-ios/Extensions/UIColor+Extensions.swift
  49. 1 0
      deltachat-ios/Handler/DeviceContactsHandler.swift
  50. 1 0
      deltachat-ios/Handler/ProgressAlertHandler.swift
  51. 1 0
      deltachat-ios/Helper/AvatarHelper.swift
  52. 1 0
      deltachat-ios/Helper/LocationManager.swift
  53. 1 0
      deltachat-ios/Helper/RelayHelper.swift
  54. 1 125
      deltachat-ios/Helper/Utils.swift
  55. 1 0
      deltachat-ios/View/AvatarSelectionCell.swift
  56. 1 0
      deltachat-ios/View/Cell/ProfileCell.swift
  57. 1 0
      deltachat-ios/View/ContactCell.swift
  58. 1 0
      deltachat-ios/ViewModel/ChatListViewModel.swift
  59. 1 0
      deltachat-ios/ViewModel/ContactCellViewModel.swift
  60. 1 0
      deltachat-ios/ViewModel/ContactDetailViewModel.swift
  61. 0 7
      deltachat-ios/deltachat-ios-Bridging-Header.h

+ 585 - 0
DcCore/DcCore.xcodeproj/project.pbxproj

@@ -0,0 +1,585 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 52;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		3042193B243DE0F200516852 /* DcCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30421931243DE0F200516852 /* DcCore.framework */; };
+		30421940243DE0F200516852 /* DcCoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3042193F243DE0F200516852 /* DcCoreTests.swift */; };
+		30421942243DE0F200516852 /* DcCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 30421934243DE0F200516852 /* DcCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		30421950243DE15D00516852 /* wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3042194C243DE15D00516852 /* wrapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		30421951243DE15D00516852 /* Wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3042194D243DE15D00516852 /* Wrapper.swift */; };
+		30421952243DE15D00516852 /* wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 3042194E243DE15D00516852 /* wrapper.c */; };
+		30421959243DE6AD00516852 /* libdeltachat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30421958243DE61400516852 /* libdeltachat.a */; platformFilter = ios; };
+		3042195B243DF1C500516852 /* deltachat.h in Headers */ = {isa = PBXBuildFile; fileRef = 3042195A243DF1C500516852 /* deltachat.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		3042195D243E23F100516852 /* DcUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3042195C243E23F100516852 /* DcUtils.swift */; };
+		30421960243E257100516852 /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3042195F243E257100516852 /* UIColor+Extensions.swift */; };
+		30421962243E26C800516852 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30421961243E26C800516852 /* Logger.swift */; };
+		30421964243F0B8400516852 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30421963243F0B8400516852 /* String+Extensions.swift */; };
+		30421986243F209E00516852 /* events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30421985243F209E00516852 /* events.swift */; };
+		30421988243F23E500516852 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30421987243F23E500516852 /* Constants.swift */; };
+		306C324824460CDE001D89F3 /* DateUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306C324724460CDE001D89F3 /* DateUtils.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		3042193C243DE0F200516852 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30421928243DE0F100516852 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 30421930243DE0F200516852;
+			remoteInfo = DcCore;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		30421931243DE0F200516852 /* DcCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DcCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		30421934243DE0F200516852 /* DcCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DcCore.h; sourceTree = "<group>"; };
+		30421935243DE0F200516852 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		3042193A243DE0F200516852 /* DcCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DcCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		3042193F243DE0F200516852 /* DcCoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcCoreTests.swift; sourceTree = "<group>"; };
+		30421941243DE0F200516852 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		3042194C243DE15D00516852 /* wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wrapper.h; path = ../../DcCore/DcCore/DC/wrapper.h; sourceTree = "<group>"; };
+		3042194D243DE15D00516852 /* Wrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Wrapper.swift; path = ../../DcCore/DcCore/DC/Wrapper.swift; sourceTree = "<group>"; };
+		3042194E243DE15D00516852 /* wrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wrapper.c; path = ../../DcCore/DcCore/DC/wrapper.c; sourceTree = "<group>"; };
+		30421958243DE61400516852 /* libdeltachat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdeltachat.a; path = "../deltachat-ios/libraries/deltachat-core-rust/target/universal/release/libdeltachat.a"; sourceTree = "<group>"; };
+		3042195A243DF1C500516852 /* deltachat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = deltachat.h; path = "../deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi/deltachat.h"; sourceTree = "<group>"; };
+		3042195C243E23F100516852 /* DcUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DcUtils.swift; sourceTree = "<group>"; };
+		3042195F243E257100516852 /* UIColor+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extensions.swift"; sourceTree = "<group>"; };
+		30421961243E26C800516852 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Logger.swift; path = ../../DcCore/DcCore/DC/Logger.swift; sourceTree = "<group>"; };
+		30421963243F0B8400516852 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
+		30421985243F209E00516852 /* events.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = events.swift; path = ../../DcCore/DcCore/DC/events.swift; sourceTree = "<group>"; };
+		30421987243F23E500516852 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
+		306C324724460CDE001D89F3 /* DateUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateUtils.swift; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		3042192E243DE0F200516852 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				30421959243DE6AD00516852 /* libdeltachat.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		30421937243DE0F200516852 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3042193B243DE0F200516852 /* DcCore.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		30421927243DE0F100516852 = {
+			isa = PBXGroup;
+			children = (
+				3042195A243DF1C500516852 /* deltachat.h */,
+				30421933243DE0F200516852 /* DcCore */,
+				3042193E243DE0F200516852 /* DcCoreTests */,
+				30421932243DE0F200516852 /* Products */,
+				30421957243DE61400516852 /* Frameworks */,
+			);
+			sourceTree = "<group>";
+		};
+		30421932243DE0F200516852 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				30421931243DE0F200516852 /* DcCore.framework */,
+				3042193A243DE0F200516852 /* DcCoreTests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		30421933243DE0F200516852 /* DcCore */ = {
+			isa = PBXGroup;
+			children = (
+				30421977243F1AF400516852 /* Helper */,
+				3042195E243E255000516852 /* Extensions */,
+				3042194B243DE15D00516852 /* DC */,
+				30421934243DE0F200516852 /* DcCore.h */,
+				30421935243DE0F200516852 /* Info.plist */,
+			);
+			path = DcCore;
+			sourceTree = "<group>";
+		};
+		3042193E243DE0F200516852 /* DcCoreTests */ = {
+			isa = PBXGroup;
+			children = (
+				3042193F243DE0F200516852 /* DcCoreTests.swift */,
+				30421941243DE0F200516852 /* Info.plist */,
+			);
+			path = DcCoreTests;
+			sourceTree = "<group>";
+		};
+		3042194B243DE15D00516852 /* DC */ = {
+			isa = PBXGroup;
+			children = (
+				30421985243F209E00516852 /* events.swift */,
+				30421961243E26C800516852 /* Logger.swift */,
+				3042194E243DE15D00516852 /* wrapper.c */,
+				3042194C243DE15D00516852 /* wrapper.h */,
+				3042194D243DE15D00516852 /* Wrapper.swift */,
+			);
+			name = DC;
+			path = "../../deltachat-ios/DC";
+			sourceTree = "<group>";
+		};
+		30421957243DE61400516852 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				30421958243DE61400516852 /* libdeltachat.a */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		3042195E243E255000516852 /* Extensions */ = {
+			isa = PBXGroup;
+			children = (
+				3042195F243E257100516852 /* UIColor+Extensions.swift */,
+				30421963243F0B8400516852 /* String+Extensions.swift */,
+			);
+			path = Extensions;
+			sourceTree = "<group>";
+		};
+		30421977243F1AF400516852 /* Helper */ = {
+			isa = PBXGroup;
+			children = (
+				30421987243F23E500516852 /* Constants.swift */,
+				3042195C243E23F100516852 /* DcUtils.swift */,
+				306C324724460CDE001D89F3 /* DateUtils.swift */,
+			);
+			path = Helper;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		3042192C243DE0F200516852 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				30421950243DE15D00516852 /* wrapper.h in Headers */,
+				30421942243DE0F200516852 /* DcCore.h in Headers */,
+				3042195B243DF1C500516852 /* deltachat.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		30421930243DE0F200516852 /* DcCore */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 30421945243DE0F200516852 /* Build configuration list for PBXNativeTarget "DcCore" */;
+			buildPhases = (
+				30421954243DE38E00516852 /* ShellScript */,
+				3042192C243DE0F200516852 /* Headers */,
+				3042192D243DE0F200516852 /* Sources */,
+				3042192E243DE0F200516852 /* Frameworks */,
+				3042192F243DE0F200516852 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = DcCore;
+			productName = DcCore;
+			productReference = 30421931243DE0F200516852 /* DcCore.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		30421939243DE0F200516852 /* DcCoreTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 30421948243DE0F200516852 /* Build configuration list for PBXNativeTarget "DcCoreTests" */;
+			buildPhases = (
+				30421936243DE0F200516852 /* Sources */,
+				30421937243DE0F200516852 /* Frameworks */,
+				30421938243DE0F200516852 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				3042193D243DE0F200516852 /* PBXTargetDependency */,
+			);
+			name = DcCoreTests;
+			productName = DcCoreTests;
+			productReference = 3042193A243DE0F200516852 /* DcCoreTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		30421928243DE0F100516852 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastSwiftUpdateCheck = 1140;
+				LastUpgradeCheck = 1140;
+				ORGANIZATIONNAME = "merlinux GmbH";
+				TargetAttributes = {
+					30421930243DE0F200516852 = {
+						CreatedOnToolsVersion = 11.4;
+					};
+					30421939243DE0F200516852 = {
+						CreatedOnToolsVersion = 11.4;
+					};
+				};
+			};
+			buildConfigurationList = 3042192B243DE0F100516852 /* Build configuration list for PBXProject "DcCore" */;
+			compatibilityVersion = "Xcode 9.3";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 30421927243DE0F100516852;
+			productRefGroup = 30421932243DE0F200516852 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				30421930243DE0F200516852 /* DcCore */,
+				30421939243DE0F200516852 /* DcCoreTests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		3042192F243DE0F200516852 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		30421938243DE0F200516852 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		30421954243DE38E00516852 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "# The $PATH used by XCode likely won't contain Cargo, fix that.\n# This assumes a default `rustup` setup.\nexport PATH=\"$HOME/.cargo/bin:$PATH\"\n\nexport CFLAGS_x86_64_apple_darwin=\"-I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include\"\n\n# ensure all targets are installed\nrustup target add aarch64-apple-ios x86_64-apple-ios --toolchain `cat ../deltachat-ios/libraries/deltachat-core-rust/rust-toolchain`\n\n# --xcode-integ determines --release and --targets from XCode's env vars.\n# Depending your setup, specify the rustup toolchain explicitly.\ncargo +`cat ../deltachat-ios/libraries/deltachat-core-rust/rust-toolchain` lipo --release --manifest-path ../deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi/Cargo.toml --no-default-features --features nightly\n";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		3042192D243DE0F200516852 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				30421988243F23E500516852 /* Constants.swift in Sources */,
+				30421962243E26C800516852 /* Logger.swift in Sources */,
+				30421986243F209E00516852 /* events.swift in Sources */,
+				30421951243DE15D00516852 /* Wrapper.swift in Sources */,
+				306C324824460CDE001D89F3 /* DateUtils.swift in Sources */,
+				30421952243DE15D00516852 /* wrapper.c in Sources */,
+				3042195D243E23F100516852 /* DcUtils.swift in Sources */,
+				30421964243F0B8400516852 /* String+Extensions.swift in Sources */,
+				30421960243E257100516852 /* UIColor+Extensions.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		30421936243DE0F200516852 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				30421940243DE0F200516852 /* DcCoreTests.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		3042193D243DE0F200516852 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 30421930243DE0F200516852 /* DcCore */;
+			targetProxy = 3042193C243DE0F200516852 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		30421943243DE0F200516852 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 13.4;
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Debug;
+		};
+		30421944243DE0F200516852 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 13.4;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				MTL_FAST_MATH = YES;
+				SDKROOT = iphoneos;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+				VALIDATE_PRODUCT = YES;
+				VERSIONING_SYSTEM = "apple-generic";
+				VERSION_INFO_PREFIX = "";
+			};
+			name = Release;
+		};
+		30421946243DE0F200516852 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DEVELOPMENT_TEAM = 8Y86453UA8;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				ENABLE_BITCODE = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/../deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi",
+				);
+				INFOPLIST_FILE = DcCore/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/../deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi",
+					"$(PROJECT_DIR)/../deltachat-ios/libraries/deltachat-core-rust/target/universal/release",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = chat.delta.DcCore;
+				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+				SKIP_INSTALL = YES;
+				SWIFT_OBJC_BRIDGING_HEADER = "";
+				SWIFT_VERSION = 4.2;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		30421947243DE0F200516852 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Automatic;
+				DEFINES_MODULE = YES;
+				DEVELOPMENT_TEAM = 8Y86453UA8;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				ENABLE_BITCODE = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/../deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi",
+				);
+				INFOPLIST_FILE = DcCore/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/../deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi",
+					"$(PROJECT_DIR)/../deltachat-ios/libraries/deltachat-core-rust/target/universal/release",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = chat.delta.DcCore;
+				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+				SKIP_INSTALL = YES;
+				SWIFT_OBJC_BRIDGING_HEADER = "";
+				SWIFT_VERSION = 4.2;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Release;
+		};
+		30421949243DE0F200516852 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+				CODE_SIGN_STYLE = Automatic;
+				DEVELOPMENT_TEAM = 8Y86453UA8;
+				INFOPLIST_FILE = DcCoreTests/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = chat.delta.DcCoreTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		3042194A243DE0F200516852 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+				CODE_SIGN_STYLE = Automatic;
+				DEVELOPMENT_TEAM = 8Y86453UA8;
+				INFOPLIST_FILE = DcCoreTests/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+					"@loader_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = chat.delta.DcCoreTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		3042192B243DE0F100516852 /* Build configuration list for PBXProject "DcCore" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				30421943243DE0F200516852 /* Debug */,
+				30421944243DE0F200516852 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		30421945243DE0F200516852 /* Build configuration list for PBXNativeTarget "DcCore" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				30421946243DE0F200516852 /* Debug */,
+				30421947243DE0F200516852 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		30421948243DE0F200516852 /* Build configuration list for PBXNativeTarget "DcCoreTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				30421949243DE0F200516852 /* Debug */,
+				3042194A243DE0F200516852 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 30421928243DE0F100516852 /* Project object */;
+}

+ 7 - 0
DcCore/DcCore.xcodeproj/project.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:DcCore.xcodeproj">
+   </FileRef>
+</Workspace>

+ 8 - 0
DcCore/DcCore.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 8 - 0
DcCore/DcCore/DC/Logger.swift

@@ -0,0 +1,8 @@
+import Foundation
+public protocol Logger {
+    func verbose(_ message: String)
+    func debug(_ message: String)
+    func info(_ message: String)
+    func warning(_ message: String)
+    func error(_ message: String)
+}

+ 1180 - 0
DcCore/DcCore/DC/Wrapper.swift

@@ -0,0 +1,1180 @@
+import Foundation
+import UIKit
+import AVFoundation
+
+public class DcContext {
+
+    /// TODO: THIS global instance should be replaced in the future, for example for a multi-account scenario,
+    /// where we want to have more than one DcContext.
+    static let dcContext: DcContext = DcContext()
+    public var logger: Logger?
+    let contextPointer: OpaquePointer
+    public var lastErrorString: String?
+
+    private init() {
+        var version = ""
+        if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
+            version += " " + appVersion
+        }
+
+        contextPointer = dc_context_new(callback_ios, nil, "iOS" + version)
+    }
+
+    deinit {
+        dc_context_unref(contextPointer)
+    }
+
+    /// Injection of DcContext is preferred over the usage of the shared variable
+    public static var shared: DcContext {
+        return .dcContext
+    }
+
+    public func getMessageIds(chatId: Int, count: Int, from: Int?) -> [Int] {
+		let cMessageIds = getChatMessages(chatId: chatId)
+
+        let ids: [Int]
+        if let from = from {
+            ids = DcUtils.copyAndFreeArrayWithOffset(inputArray: cMessageIds, len: count, skipEnd: from)
+        } else {
+            ids = DcUtils.copyAndFreeArrayWithLen(inputArray: cMessageIds, len: count)
+        }
+        return ids
+    }
+
+    public func createContact(name: String, email: String) -> Int {
+        return Int(dc_create_contact(contextPointer, name, email))
+    }
+
+    public func deleteContact(contactId: Int) -> Bool {
+        return dc_delete_contact(self.contextPointer, UInt32(contactId)) == 1
+    }
+
+    public func getContacts(flags: Int32, queryString: String? = nil) -> [Int] {
+        let cContacts = dc_get_contacts(contextPointer, UInt32(flags), queryString)
+        return DcUtils.copyAndFreeArray(inputArray: cContacts)
+    }
+
+    public func getBlockedContacts() -> [Int] {
+        let cBlockedContacts = dc_get_blocked_contacts(contextPointer)
+        return DcUtils.copyAndFreeArray(inputArray: cBlockedContacts)
+    }
+
+    public func addContacts(contactString: String) {
+        dc_add_address_book(contextPointer, contactString)
+    }
+
+    public func getChat(chatId: Int) -> DcChat {
+        return DcChat(id: chatId)
+    }
+
+    public func getChatIdByContactId(_ contactId: Int) -> Int? {
+        let chatId = dc_get_chat_id_by_contact_id(contextPointer, UInt32(contactId))
+        if chatId == 0 {
+            return nil
+        } else {
+            return Int(chatId)
+        }
+    }
+
+    public func createChatByMessageId(_ messageId: Int) -> DcChat {
+        let chatId = dc_create_chat_by_msg_id(contextPointer, UInt32(messageId))
+        return DcChat(id: Int(chatId))
+    }
+
+    public func getChatlist(flags: Int32, queryString: String?, queryId: Int) -> DcChatlist {
+        let chatlistPointer = dc_get_chatlist(contextPointer, flags, queryString, UInt32(queryId))
+        let chatlist = DcChatlist(chatListPointer: chatlistPointer)
+        return chatlist
+    }
+
+    public func getChatMedia(chatId: Int, messageType: Int32, messageType2: Int32, messageType3: Int32) -> [Int] {
+        guard let messagesPointer = dc_get_chat_media(contextPointer, UInt32(chatId), messageType, messageType2, messageType3) else {
+            return []
+        }
+
+        let messageIds: [Int] =  DcUtils.copyAndFreeArray(inputArray: messagesPointer)
+        return messageIds
+    }
+
+    @discardableResult
+    public func createChatByContactId(contactId: Int) -> Int {
+        return Int(dc_create_chat_by_contact_id(contextPointer, UInt32(contactId)))
+    }
+
+    public func getChatIdByContactId(contactId: Int) -> Int {
+        return Int(dc_get_chat_id_by_contact_id(contextPointer, UInt32(contactId)))
+    }
+
+    public func createGroupChat(verified: Bool, name: String) -> Int {
+        return Int(dc_create_group_chat(contextPointer, verified ? 1 : 0, name))
+    }
+
+    public func addContactToChat(chatId: Int, contactId: Int) -> Bool {
+        return dc_add_contact_to_chat(contextPointer, UInt32(chatId), UInt32(contactId)) == 1
+    }
+
+    public func removeContactFromChat(chatId: Int, contactId: Int) -> Bool {
+        return dc_remove_contact_from_chat(contextPointer, UInt32(chatId), UInt32(contactId)) == 1
+    }
+
+    public func setChatName(chatId: Int, name: String) -> Bool {
+        return dc_set_chat_name(contextPointer, UInt32(chatId), name) == 1
+    }
+
+    public func deleteChat(chatId: Int) {
+        dc_delete_chat(contextPointer, UInt32(chatId))
+    }
+
+    public func archiveChat(chatId: Int, archive: Bool) {
+        dc_set_chat_visibility(contextPointer, UInt32(chatId), Int32(archive ? DC_CHAT_VISIBILITY_ARCHIVED : DC_CHAT_VISIBILITY_NORMAL))
+    }
+
+    public func setChatVisibility(chatId: Int, visibility: Int32) {
+        dc_set_chat_visibility(contextPointer, UInt32(chatId), visibility)
+    }
+
+    public func marknoticedChat(chatId: Int) {
+        dc_marknoticed_chat(self.contextPointer, UInt32(chatId))
+    }
+
+    public func getSecurejoinQr (chatId: Int) -> String? {
+        if let cString = dc_get_securejoin_qr(self.contextPointer, UInt32(chatId)) {
+            let swiftString = String(cString: cString)
+            dc_str_unref(cString)
+            return swiftString
+        }
+        return nil
+    }
+
+    public func joinSecurejoin (qrCode: String) -> Int {
+        return Int(dc_join_securejoin(contextPointer, qrCode))
+    }
+
+    public func checkQR(qrCode: String) -> DcLot {
+        return DcLot(dc_check_qr(contextPointer, qrCode))
+    }
+
+    public func configureAccountFromQR(qrCode: String) -> Bool {
+        let state = checkQR(qrCode: qrCode).state
+        if state != DC_QR_ACCOUNT {
+            return false
+        }
+        let success = dc_set_config_from_qr(contextPointer, qrCode)
+        return success == 1
+    }
+
+    public func stopOngoingProcess() {
+        dc_stop_ongoing_process(contextPointer)
+    }
+
+    public 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 []
+    }
+
+    public func interruptIdle() {
+        dc_interrupt_imap_idle(contextPointer)
+        dc_interrupt_smtp_idle((contextPointer))
+        dc_interrupt_mvbox_idle((contextPointer))
+        dc_interrupt_sentbox_idle((contextPointer))
+    }
+
+    public func openDatabase(dbFile: String) {
+        _ = dc_open(contextPointer, dbFile, nil)
+    }
+
+    public func closeDatabase() {
+        dc_close(contextPointer)
+    }
+
+    public func performImap() {
+        dc_perform_imap_jobs(contextPointer)
+        dc_perform_imap_fetch(contextPointer)
+        dc_perform_imap_idle(contextPointer)
+    }
+
+    public func performMoveBox() {
+        dc_perform_mvbox_jobs(contextPointer)
+        dc_perform_mvbox_fetch(contextPointer)
+        dc_perform_mvbox_idle(contextPointer)
+    }
+
+    public func performSmtp() {
+        dc_perform_smtp_jobs(contextPointer)
+        dc_perform_smtp_idle(contextPointer)
+    }
+
+    public func performSentbox() {
+        dc_perform_sentbox_jobs(contextPointer)
+        dc_perform_sentbox_fetch(contextPointer)
+        dc_perform_sentbox_idle(contextPointer)
+    }
+
+    public func setStockTranslation(id: Int32, localizationKey: String) {
+        dc_set_stock_translation(contextPointer, UInt32(id), String.localized(localizationKey))
+    }
+
+    public 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
+    }
+
+    public 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)
+    }
+
+    public func getFreshMessages() -> DcArray {
+        return DcArray(arrayPointer: dc_get_fresh_msgs(contextPointer))
+    }
+
+    public func markSeenMessages(messageIds: [UInt32], count: Int = 1) {
+        let ptr = UnsafePointer(messageIds)
+        dc_markseen_msgs(contextPointer, ptr, Int32(count))
+    }
+
+    public func getChatMessages(chatId: Int) -> OpaquePointer {
+        return dc_get_chat_msgs(contextPointer, UInt32(chatId), 0, 0)
+    }
+    
+    public func getMsgInfo(msgId: Int) -> String {
+        if let cString = dc_get_msg_info(self.contextPointer, UInt32(msgId)) {
+            let swiftString = String(cString: cString)
+            dc_str_unref(cString)
+            return swiftString
+        }
+        return "ErrGetMsgInfo"
+    }
+
+    public func deleteMessage(msgId: Int) {
+        dc_delete_msgs(contextPointer, [UInt32(msgId)], 1)
+    }
+
+    public func forwardMessage(with msgId: Int, to chat: Int) {
+        dc_forward_msgs(contextPointer, [UInt32(msgId)], 1, UInt32(chat))
+    }
+
+    public func sendTextInChat(id: Int, message: String) {
+        dc_send_text_msg(contextPointer, UInt32(id), message)
+    }
+
+    public func initiateKeyTransfer() -> String? {
+        if let cString = dc_initiate_key_transfer(self.contextPointer) {
+            let swiftString = String(cString: cString)
+            dc_str_unref(cString)
+            return swiftString
+        }
+        return nil
+    }
+
+    public func continueKeyTransfer(msgId: Int, setupCode: String) -> Bool {
+        return dc_continue_key_transfer(self.contextPointer, UInt32(msgId), setupCode) != 0
+    }
+
+    public func configure() {
+        dc_configure(contextPointer)
+    }
+
+    public func getConfig(_ key: String) -> String? {
+        guard let cString = dc_get_config(self.contextPointer, key) else { return nil }
+        let value = String(cString: cString)
+        dc_str_unref(cString)
+        if value.isEmpty {
+            return nil
+        }
+        return value
+    }
+
+    public func setConfig(_ key: String, _ value: String?) {
+        if let v = value {
+            dc_set_config(self.contextPointer, key, v)
+        } else {
+            dc_set_config(self.contextPointer, key, nil)
+        }
+    }
+
+    public func getConfigBool(_ key: String) -> Bool {
+        return strToBool(getConfig(key))
+    }
+
+    public func setConfigBool(_ key: String, _ value: Bool) {
+        let vStr = value ? "1" : "0"
+        setConfig(key, vStr)
+    }
+
+    public func getConfigInt(_ key: String) -> Int {
+        if let str = getConfig(key) {
+            return Int(str) ?? 0
+        }
+        return 0
+    }
+
+    public func setConfigInt(_ key: String, _ value: Int) {
+        setConfig(key, String(value))
+    }
+
+    public func getUnreadMessages(chatId: Int) -> Int {
+        return Int(dc_get_fresh_msg_cnt(contextPointer, UInt32(chatId)))
+    }
+
+    public func estimateDeletionCnt(fromServer: Bool, timeout: Int) -> Int {
+        return Int(dc_estimate_deletion_cnt(contextPointer, fromServer ? 1 : 0, Int64(timeout)))
+    }
+
+    public func emptyServer(flags: Int) {
+        dc_empty_server(contextPointer, UInt32(flags))
+    }
+
+    public func isConfigured() -> Bool {
+        return dc_is_configured(contextPointer) != 0
+    }
+
+    public func getSelfAvatarImage() -> UIImage? {
+       guard let fileName = selfavatar else { return nil }
+       let path: URL = URL(fileURLWithPath: fileName, isDirectory: false)
+       if path.isFileURL {
+           do {
+               let data = try Data(contentsOf: path)
+               return UIImage(data: data)
+           } catch {
+               logger?.warning("failed to load image: \(fileName), \(error)")
+               return nil
+           }
+       }
+       return nil
+    }
+
+    public func saveChatAvatarImage(chatId: Int, path: String) {
+        dc_set_chat_profile_image(contextPointer, UInt32(chatId), path)
+    }
+
+    @discardableResult
+    public func addDeviceMessage(label: String, msg: DcMsg) -> Int {
+        return Int(dc_add_device_msg(contextPointer, label.cString(using: .utf8), msg.cptr))
+    }
+
+    public func updateDeviceChats() {
+        dc_update_device_chats(contextPointer)
+    }
+
+    public func getProviderFromEmail(addr: String) -> DcProvider? {
+        guard let dcProviderPointer = dc_provider_new_from_email(contextPointer, addr) else { return nil }
+        return DcProvider(dcProviderPointer)
+    }
+
+    public func imex(what: Int32, directory: String) {
+        dc_imex(contextPointer, what, directory, nil)
+    }
+
+    public func imexHasBackup(filePath: String) -> String? {
+        var file: String?
+        if let cString = dc_imex_has_backup(contextPointer, filePath) {
+            file = String(cString: cString)
+            dc_str_unref(cString)
+        }
+        return file
+    }
+
+    public func isSendingLocationsToChat(chatId: Int) -> Bool {
+        return dc_is_sending_locations_to_chat(contextPointer, UInt32(chatId)) == 1
+    }
+
+    public func sendLocationsToChat(chatId: Int, seconds: Int) {
+        dc_send_locations_to_chat(contextPointer, UInt32(chatId), Int32(seconds))
+    }
+
+    public func setLocation(latitude: Double, longitude: Double, accuracy: Double) {
+        dc_set_location(contextPointer, latitude, longitude, accuracy)
+    }
+
+    public func searchMessages(chatId: Int = 0, searchText: String) -> [Int] {
+        guard let arrayPointer = dc_search_msgs(contextPointer, UInt32(chatId), searchText) else {
+            return []
+        }
+        let messageIds = DcUtils.copyAndFreeArray(inputArray: arrayPointer)
+        return messageIds
+    }
+
+    // call dc_maybe_network() from a worker thread.
+    public 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.
+    // this adds a complexity that can be avoided -
+    // and makes grep harder as these names are typically named following different guidelines.
+
+    public var displayname: String? {
+        set { setConfig("displayname", newValue) }
+        get { return getConfig("displayname") }
+    }
+
+    public var selfstatus: String? {
+        set { setConfig("selfstatus", newValue) }
+        get { return getConfig("selfstatus") }
+    }
+
+    public var selfavatar: String? {
+        set { setConfig("selfavatar", newValue) }
+        get { return getConfig("selfavatar") }
+    }
+
+    public var addr: String? {
+        set { setConfig("addr", newValue) }
+        get { return getConfig("addr") }
+    }
+
+    public var mailServer: String? {
+        set { setConfig("mail_server", newValue) }
+        get { return getConfig("mail_server") }
+    }
+
+    public var mailUser: String? {
+        set { setConfig("mail_user", newValue) }
+        get { return getConfig("mail_user") }
+    }
+
+    public var mailPw: String? {
+        set { setConfig("mail_pw", newValue) }
+        get { return getConfig("mail_pw") }
+    }
+
+    public var mailPort: String? {
+        set { setConfig("mail_port", newValue) }
+        get { return getConfig("mail_port") }
+    }
+
+    public var sendServer: String? {
+        set { setConfig("send_server", newValue) }
+        get { return getConfig("send_server") }
+    }
+
+    public var sendUser: String? {
+        set { setConfig("send_user", newValue) }
+        get { return getConfig("send_user") }
+    }
+
+    public var sendPw: String? {
+        set { setConfig("send_pw", newValue) }
+        get { return getConfig("send_pw") }
+    }
+
+    public var sendPort: String? {
+        set { setConfig("send_port", newValue) }
+        get { return getConfig("send_port") }
+    }
+
+    public var certificateChecks: Int {
+        set {
+            setConfig("smtp_certificate_checks", "\(newValue)")
+            setConfig("imap_certificate_checks", "\(newValue)")
+        }
+        get {
+            if let str = getConfig("imap_certificate_checks") {
+                return Int(str) ?? 0
+            } else {
+                return 0
+            }
+        }
+    }
+
+    private var serverFlags: Int {
+        // IMAP-/SMTP-flags as a combination of DC_LP flags
+        set {
+            setConfig("server_flags", "\(newValue)")
+        }
+        get {
+            if let str = getConfig("server_flags") {
+                return Int(str) ?? 0
+            } else {
+                return 0
+            }
+        }
+    }
+
+    public func setImapSecurity(imapFlags flags: Int) {
+        var sf = serverFlags
+        sf = sf & ~0x700 // DC_LP_IMAP_SOCKET_FLAGS
+        sf = sf | flags
+        serverFlags = sf
+    }
+
+    public func setSmtpSecurity(smptpFlags flags: Int) {
+        var sf = serverFlags
+        sf = sf & ~0x70000 // DC_LP_SMTP_SOCKET_FLAGS
+        sf = sf | flags
+        serverFlags = sf
+    }
+
+    public func setAuthFlags(flags: Int) {
+        var sf = serverFlags
+        sf = sf & ~0x6 // DC_LP_AUTH_FLAGS
+        sf = sf | flags
+        serverFlags = sf
+    }
+
+    public func getImapSecurity() -> Int {
+        var sf = serverFlags
+        sf = sf & 0x700 // DC_LP_IMAP_SOCKET_FLAGS
+        return sf
+    }
+
+    public func getSmtpSecurity() -> Int {
+        var sf = serverFlags
+        sf = sf & 0x70000  // DC_LP_SMTP_SOCKET_FLAGS
+        return sf
+    }
+
+    public func getAuthFlags() -> Int {
+        var sf = serverFlags
+        sf = sf & 0x6 // DC_LP_AUTH_FLAGS
+        return sf
+    }
+
+    public var e2eeEnabled: Bool {
+        set { setConfigBool("e2ee_enabled", newValue) }
+        get { return getConfigBool("e2ee_enabled") }
+    }
+
+    public var mdnsEnabled: Bool {
+        set { setConfigBool("mdns_enabled", newValue) }
+        get { return getConfigBool("mdns_enabled") }
+    }
+
+    public var showEmails: Int {
+        // one of DC_SHOW_EMAILS_*
+        set { setConfigInt("show_emails", newValue) }
+        get { return getConfigInt("show_emails") }
+    }
+
+    // do not use. use DcContext::isConfigured() instead
+    public var configured: Bool {
+        return getConfigBool("configured")
+    }
+}
+
+public class DcChatlist {
+    private var chatListPointer: OpaquePointer?
+
+    // takes ownership of specified pointer
+    public init(chatListPointer: OpaquePointer?) {
+        self.chatListPointer = chatListPointer
+    }
+
+    deinit {
+        dc_chatlist_unref(chatListPointer)
+    }
+
+    public var length: Int {
+        return dc_chatlist_get_cnt(chatListPointer)
+    }
+
+    public func getChatId(index: Int) -> Int {
+        return Int(dc_chatlist_get_chat_id(chatListPointer, index))
+    }
+
+    public func getMsgId(index: Int) -> Int {
+        return Int(dc_chatlist_get_msg_id(chatListPointer, index))
+    }
+
+    public func getSummary(index: Int) -> DcLot {
+        guard let lotPointer = dc_chatlist_get_summary(self.chatListPointer, index, nil) else {
+            fatalError("lot-pointer was nil")
+        }
+        return DcLot(lotPointer)
+    }
+}
+
+public class DcChat {
+    var chatPointer: OpaquePointer?
+
+    // use DcContext.getChat() instead of calling the constructor directly
+    public init(id: Int) {
+        if let p = dc_get_chat(DcContext.shared.contextPointer, UInt32(id)) {
+            chatPointer = p
+        } else {
+            fatalError("Invalid chatID opened \(id)")
+        }
+    }
+
+    deinit {
+        dc_chat_unref(chatPointer)
+    }
+
+    public var id: Int {
+        return Int(dc_chat_get_id(chatPointer))
+    }
+
+    public var name: String {
+        guard let cString = dc_chat_get_name(chatPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var type: Int {
+        return Int(dc_chat_get_type(chatPointer))
+    }
+
+    public var chatType: ChatType {
+        return ChatType(rawValue: type) ?? ChatType.GROUP // group as fallback - shouldn't get here
+    }
+
+    public var color: UIColor {
+        return UIColor(netHex: Int(dc_chat_get_color(chatPointer)))
+    }
+
+    public var isArchived: Bool {
+        return Int(dc_chat_get_visibility(chatPointer)) == DC_CHAT_VISIBILITY_ARCHIVED
+    }
+
+    public var visibility: Int32 {
+        return dc_chat_get_visibility(chatPointer)
+    }
+
+    public var isUnpromoted: Bool {
+        return Int(dc_chat_is_unpromoted(chatPointer)) != 0
+    }
+
+    public var isGroup: Bool {
+        let type = Int(dc_chat_get_type(chatPointer))
+        return type == DC_CHAT_TYPE_GROUP || type == DC_CHAT_TYPE_VERIFIED_GROUP
+    }
+
+    public var isSelfTalk: Bool {
+        return Int(dc_chat_is_self_talk(chatPointer)) != 0
+    }
+
+    public var isDeviceTalk: Bool {
+        return Int(dc_chat_is_device_talk(chatPointer)) != 0
+    }
+
+    public var canSend: Bool {
+        return Int(dc_chat_can_send(chatPointer)) != 0
+    }
+
+    public var isVerified: Bool {
+        return dc_chat_is_verified(chatPointer) > 0
+    }
+
+    public var contactIds: [Int] {
+        return DcUtils.copyAndFreeArray(inputArray: dc_get_chat_contacts(DcContext.shared.contextPointer, UInt32(id)))
+    }
+
+    public lazy var profileImage: UIImage? = { [unowned self] in
+        guard let cString = dc_chat_get_profile_image(chatPointer) else { return nil }
+        let filename = String(cString: cString)
+        dc_str_unref(cString)
+        let path: URL = URL(fileURLWithPath: filename, isDirectory: false)
+        if path.isFileURL {
+            do {
+                let data = try Data(contentsOf: path)
+                let image = UIImage(data: data)
+                return image
+            } catch {
+                DcContext.shared.logger?.warning("failed to load image: \(filename), \(error)")
+                return nil
+            }
+        }
+        return nil
+        }()
+
+    public var isSendingLocations: Bool {
+        return dc_chat_is_sending_locations(chatPointer) == 1
+    }
+}
+
+public class DcArray {
+    private var dcArrayPointer: OpaquePointer?
+
+    public init(arrayPointer: OpaquePointer) {
+        dcArrayPointer = arrayPointer
+    }
+
+    deinit {
+        dc_array_unref(dcArrayPointer)
+    }
+
+    public var count: Int {
+       return Int(dc_array_get_cnt(dcArrayPointer))
+    }
+
+    ///TODO: add missing methods here
+}
+
+public class DcMsg {
+    private var messagePointer: OpaquePointer?
+
+    /**
+        viewType: one of
+            DC_MSG_TEXT,
+            DC_MSG_IMAGE,
+            DC_MSG_GIF,
+            DC_MSG_STICKER,
+            DC_MSG_AUDIO,
+            DC_MSG_VOICE,
+            DC_MSG_VIDEO,
+            DC_MSG_FILE
+     */
+    public init(viewType: Int32) {
+        messagePointer = dc_msg_new(DcContext.shared.contextPointer, viewType)
+    }
+
+    public init(id: Int) {
+        messagePointer = dc_get_msg(DcContext.shared.contextPointer, UInt32(id))
+    }
+
+    public init(type: Int32) {
+        messagePointer = dc_msg_new(DcContext.shared.contextPointer, type)
+    }
+
+    deinit {
+        dc_msg_unref(messagePointer)
+    }
+
+    public var cptr: OpaquePointer? {
+        return messagePointer
+    }
+
+    public lazy var sentDate: Date = {
+        Date(timeIntervalSince1970: Double(timestamp))
+    }()
+
+    public func formattedSentDate() -> String {
+        return DateUtils.getExtendedRelativeTimeSpanString(timeStamp: Double(timestamp))
+    }
+
+    public var isForwarded: Bool {
+        return dc_msg_is_forwarded(messagePointer) != 0
+    }
+
+    public var messageId: String {
+        return "\(id)"
+    }
+
+    public var id: Int {
+        return Int(dc_msg_get_id(messagePointer))
+    }
+
+    public var fromContactId: Int {
+        return Int(dc_msg_get_from_id(messagePointer))
+    }
+
+    public lazy var fromContact: DcContact = {
+        DcContact(id: fromContactId)
+    }()
+
+    public var chatId: Int {
+        return Int(dc_msg_get_chat_id(messagePointer))
+    }
+
+    public var text: String? {
+        set {
+            if let newValue = newValue {
+                dc_msg_set_text(messagePointer, newValue.cString(using: .utf8))
+            } else {
+                dc_msg_set_text(messagePointer, nil)
+            }
+        }
+        get {
+            guard let cString = dc_msg_get_text(messagePointer) else { return nil }
+            let swiftString = String(cString: cString)
+            dc_str_unref(cString)
+            return swiftString
+        }
+    }
+
+    public var viewtype: MessageViewType? {
+        switch dc_msg_get_viewtype(messagePointer) {
+        case 0:
+            return nil
+        case DC_MSG_AUDIO:
+            return .audio
+        case DC_MSG_FILE:
+            return .file
+        case DC_MSG_GIF:
+            return .gif
+        case DC_MSG_TEXT:
+            return .text
+        case DC_MSG_IMAGE:
+            return .image
+        case DC_MSG_STICKER:
+            return .image
+        case DC_MSG_VIDEO:
+            return .video
+        case DC_MSG_VOICE:
+            return .voice
+        default:
+            return nil
+        }
+    }
+
+    public var fileURL: URL? {
+        if let file = self.file {
+            return URL(fileURLWithPath: file, isDirectory: false)
+        }
+        return nil
+    }
+
+    public lazy var image: UIImage? = { [unowned self] in
+        let filetype = dc_msg_get_viewtype(messagePointer)
+        if let path = fileURL, filetype == DC_MSG_IMAGE {
+            if path.isFileURL {
+                do {
+                    let data = try Data(contentsOf: path)
+                    let image = UIImage(data: data)
+                    return image
+                } catch {
+                    DcContext.shared.logger?.warning("failed to load image: \(path), \(error)")
+                    return nil
+                }
+            }
+            return nil
+        } else {
+            return nil
+        }
+        }()
+
+    public var file: String? {
+        if let cString = dc_msg_get_file(messagePointer) {
+            let str = String(cString: cString)
+            dc_str_unref(cString)
+            return str.isEmpty ? nil : str
+        }
+
+        return nil
+    }
+
+    public var filemime: String? {
+        if let cString = dc_msg_get_filemime(messagePointer) {
+            let str = String(cString: cString)
+            dc_str_unref(cString)
+            return str.isEmpty ? nil : str
+        }
+
+        return nil
+    }
+
+    public var filename: String? {
+        if let cString = dc_msg_get_filename(messagePointer) {
+            let str = String(cString: cString)
+            dc_str_unref(cString)
+            return str.isEmpty ? nil : str
+        }
+
+        return nil
+    }
+
+    public func setFile(filepath: String?, mimeType: String?) {
+        dc_msg_set_file(messagePointer, filepath, mimeType)
+    }
+
+    public func setDimension(width: CGFloat, height: CGFloat) {
+        dc_msg_set_dimension(messagePointer, Int32(width), Int32(height))
+    }
+
+    public var filesize: Int {
+        return Int(dc_msg_get_filebytes(messagePointer))
+    }
+
+    // DC_MSG_*
+    public var type: Int {
+        return Int(dc_msg_get_viewtype(messagePointer))
+    }
+
+    // DC_STATE_*
+    public var state: Int {
+        return Int(dc_msg_get_state(messagePointer))
+    }
+
+    public var timestamp: Int64 {
+        return Int64(dc_msg_get_timestamp(messagePointer))
+    }
+
+    public var isInfo: Bool {
+        return dc_msg_is_info(messagePointer) == 1
+    }
+
+    public var isSetupMessage: Bool {
+        return dc_msg_is_setupmessage(messagePointer) == 1
+    }
+
+    public var setupCodeBegin: String {
+        guard let cString = dc_msg_get_setupcodebegin(messagePointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public func summary(chars: Int) -> String? {
+        guard let cString = dc_msg_get_summarytext(messagePointer, Int32(chars)) else { return nil }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public func summary(chat: DcChat) -> DcLot {
+        guard let chatPointer = chat.chatPointer else {
+            fatalError()
+        }
+        guard let dcLotPointer = dc_msg_get_summary(messagePointer, chatPointer) else {
+            fatalError()
+        }
+        return DcLot(dcLotPointer)
+    }
+
+    public func showPadlock() -> Bool {
+        return dc_msg_get_showpadlock(messagePointer) == 1
+    }
+
+    public func sendInChat(id: Int) {
+        dc_send_msg(DcContext.shared.contextPointer, UInt32(id), messagePointer)
+    }
+
+    public func previousMediaURLs() -> [URL] {
+        var urls: [URL] = []
+        var prev: Int = Int(dc_get_next_media(DcContext.shared.contextPointer, UInt32(id), -1, Int32(type), 0, 0))
+        while prev != 0 {
+            let prevMessage = DcMsg(id: prev)
+            if let url = prevMessage.fileURL {
+                urls.insert(url, at: 0)
+            }
+            prev = Int(dc_get_next_media(DcContext.shared.contextPointer, UInt32(prevMessage.id), -1, Int32(prevMessage.type), 0, 0))
+        }
+        return urls
+    }
+
+    public func nextMediaURLs() -> [URL] {
+        var urls: [URL] = []
+        var next: Int = Int(dc_get_next_media(DcContext.shared.contextPointer, UInt32(id), 1, Int32(type), 0, 0))
+        while next != 0 {
+            let nextMessage = DcMsg(id: next)
+            if let url = nextMessage.fileURL {
+                urls.append(url)
+            }
+            next = Int(dc_get_next_media(DcContext.shared.contextPointer, UInt32(nextMessage.id), 1, Int32(nextMessage.type), 0, 0))
+        }
+        return urls
+    }
+}
+
+public class DcContact {
+    private var contactPointer: OpaquePointer?
+
+    public init(id: Int) {
+        contactPointer = dc_get_contact(DcContext.shared.contextPointer, UInt32(id))
+    }
+
+    deinit {
+        dc_contact_unref(contactPointer)
+    }
+
+    public var displayName: String {
+        guard let cString = dc_contact_get_display_name(contactPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var nameNAddr: String {
+        guard let cString = dc_contact_get_name_n_addr(contactPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var name: String {
+        guard let cString = dc_contact_get_name(contactPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var email: String {
+        guard let cString = dc_contact_get_addr(contactPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var isVerified: Bool {
+        return dc_contact_is_verified(contactPointer) > 0
+    }
+
+    public var isBlocked: Bool {
+        return dc_contact_is_blocked(contactPointer) == 1
+    }
+
+    public lazy var profileImage: UIImage? = { [unowned self] in
+        guard let cString = dc_contact_get_profile_image(contactPointer) else { return nil }
+        let filename = String(cString: cString)
+        dc_str_unref(cString)
+        let path: URL = URL(fileURLWithPath: filename, isDirectory: false)
+        if path.isFileURL {
+            do {
+                let data = try Data(contentsOf: path)
+                return UIImage(data: data)
+            } catch {
+                DcContext.shared.logger?.warning("failed to load image: \(filename), \(error)")
+                return nil
+            }
+        }
+        return nil
+    }()
+
+    public var color: UIColor {
+        return UIColor(netHex: Int(dc_contact_get_color(contactPointer)))
+    }
+
+    public var id: Int {
+        return Int(dc_contact_get_id(contactPointer))
+    }
+
+    public func block() {
+        dc_block_contact(DcContext.shared.contextPointer, UInt32(id), 1)
+    }
+
+    public func unblock() {
+        dc_block_contact(DcContext.shared.contextPointer, UInt32(id), 0)
+    }
+
+    public func marknoticed() {
+        dc_marknoticed_contact(DcContext.shared.contextPointer, UInt32(id))
+    }
+}
+
+public class DcLot {
+    private var dcLotPointer: OpaquePointer?
+
+    // takes ownership of specified pointer
+    public init(_ dcLotPointer: OpaquePointer) {
+        self.dcLotPointer = dcLotPointer
+    }
+
+    deinit {
+        dc_lot_unref(dcLotPointer)
+    }
+
+    public var text1: String? {
+        guard let cString = dc_lot_get_text1(dcLotPointer) else { return nil }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var text1Meaning: Int {
+        return Int(dc_lot_get_text1_meaning(dcLotPointer))
+    }
+
+    public var text2: String? {
+        guard let cString = dc_lot_get_text2(dcLotPointer) else { return nil }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var timestamp: Int64 {
+        return Int64(dc_lot_get_timestamp(dcLotPointer))
+    }
+
+    public var state: Int {
+        return Int(dc_lot_get_state(dcLotPointer))
+    }
+
+    public var id: Int {
+        return Int(dc_lot_get_id(dcLotPointer))
+    }
+}
+
+public class DcProvider {
+    private var dcProviderPointer: OpaquePointer?
+
+    // takes ownership of specified pointer
+    public init(_ dcProviderPointer: OpaquePointer) {
+        self.dcProviderPointer = dcProviderPointer
+    }
+
+    deinit {
+        dc_provider_unref(dcProviderPointer)
+    }
+
+    public var status: Int {
+        return Int(dc_provider_get_status(dcProviderPointer))
+    }
+
+    public var beforeLoginHint: String {
+        guard let cString = dc_provider_get_before_login_hint(dcProviderPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+
+    public var getOverviewPage: String {
+        guard let cString = dc_provider_get_overview_page(dcProviderPointer) else { return "" }
+        let swiftString = String(cString: cString)
+        dc_str_unref(cString)
+        return swiftString
+    }
+}
+
+public enum ChatType: Int {
+    case SINGLE = 100
+    case GROUP = 120
+    case VERIFIEDGROUP = 130
+}
+
+public enum MessageViewType: CustomStringConvertible {
+    case audio
+    case file
+    case gif
+    case image
+    case text
+    case video
+    case voice
+
+    public var description: String {
+        switch self {
+        // Use Internationalization, as appropriate.
+        case .audio: return "Audio"
+        case .file: return "File"
+        case .gif: return "GIF"
+        case .image: return "Image"
+        case .text: return "Text"
+        case .video: return "Video"
+        case .voice: return "Voice"
+        }
+    }
+}
+
+func strToBool(_ value: String?) -> Bool {
+    if let vStr = value {
+        if let vInt = Int(vStr) {
+            return vInt == 1
+        }
+        return false
+    }
+
+    return false
+}

+ 28 - 28
deltachat-ios/DC/events.swift → DcCore/DcCore/DC/events.swift

@@ -1,24 +1,24 @@
 import UIKit
 import UserNotifications
 
-let dcNotificationChanged = Notification.Name(rawValue: "MrEventMsgsChanged")
-let dcNotificationIncoming = Notification.Name(rawValue: "MrEventIncomingMsg")
-let dcNotificationImexProgress = Notification.Name(rawValue: "dcNotificationImexProgress")
-let dcNotificationConfigureProgress = Notification.Name(rawValue: "MrEventConfigureProgress")
-let dcNotificationSecureJoinerProgress = Notification.Name(rawValue: "MrEventSecureJoinerProgress")
-let dcNotificationSecureInviterProgress = Notification.Name(rawValue: "MrEventSecureInviterProgress")
-let dcNotificationViewChat = Notification.Name(rawValue: "MrEventViewChat")
-let dcNotificationContactChanged = Notification.Name(rawValue: "MrEventContactsChanged")
-let dcNotificationChatModified = Notification.Name(rawValue: "dcNotificationChatModified")
-let dcNotificationChatDeletedInChatDetail = Notification.Name(rawValue: "ChatDeletedInChatDetail")
+public let dcNotificationChanged = Notification.Name(rawValue: "MrEventMsgsChanged")
+public let dcNotificationIncoming = Notification.Name(rawValue: "MrEventIncomingMsg")
+public let dcNotificationImexProgress = Notification.Name(rawValue: "dcNotificationImexProgress")
+public let dcNotificationConfigureProgress = Notification.Name(rawValue: "MrEventConfigureProgress")
+public let dcNotificationSecureJoinerProgress = Notification.Name(rawValue: "MrEventSecureJoinerProgress")
+public let dcNotificationSecureInviterProgress = Notification.Name(rawValue: "MrEventSecureInviterProgress")
+public let dcNotificationViewChat = Notification.Name(rawValue: "MrEventViewChat")
+public let dcNotificationContactChanged = Notification.Name(rawValue: "MrEventContactsChanged")
+public let dcNotificationChatModified = Notification.Name(rawValue: "dcNotificationChatModified")
+public let dcNotificationChatDeletedInChatDetail = Notification.Name(rawValue: "ChatDeletedInChatDetail")
 
 @_silgen_name("callbackSwift")
 
 public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLong, data1String: UnsafePointer<Int8>, data2String: UnsafePointer<Int8>) {
     if event >= DC_EVENT_ERROR && event <= 499 {
         let s = String(cString: data2String)
-        AppDelegate.lastErrorString = s
-        logger.error("event: \(s)")
+        DcContext.shared.lastErrorString = s
+        DcContext.shared.logger?.error("event: \(s)")
         return
     }
 
@@ -26,14 +26,14 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
 
     case DC_EVENT_INFO:
         let s = String(cString: data2String)
-        logger.info("event: \(s)")
+        DcContext.shared.logger?.info("event: \(s)")
 
     case DC_EVENT_WARNING:
         let s = String(cString: data2String)
-        logger.warning("event: \(s)")
+        DcContext.shared.logger?.warning("event: \(s)")
 
     case DC_EVENT_CONFIGURE_PROGRESS:
-        logger.info("configure progress: \(Int(data1)) \(Int(data2))")
+        DcContext.shared.logger?.info("configure progress: \(Int(data1)) \(Int(data2))")
         let nc = NotificationCenter.default
         DispatchQueue.main.async {
             let done = Int(data1) == 1000
@@ -45,14 +45,14 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
                     "progress": Int(data1),
                     "error": Int(data1) == 0,
                     "done": done,
-                    "errorMessage": AppDelegate.lastErrorString as Any,
+                    "errorMessage": DcContext.shared.lastErrorString as Any,
                 ]
             )
 
             if done {
                 UserDefaults.standard.set(true, forKey: Constants.Keys.deltachatUserProvidedCredentialsKey)
                 UserDefaults.standard.synchronize()
-                AppDelegate.lastErrorString = nil
+                DcContext.shared.lastErrorString = nil
             }
         }
 
@@ -66,16 +66,16 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
                     "progress": Int(data1),
                     "error": Int(data1) == 0,
                     "done": Int(data1) == 1000,
-                    "errorMessage": AppDelegate.lastErrorString as Any,
+                    "errorMessage": DcContext.shared.lastErrorString as Any,
                 ]
             )
         }
 
     case DC_EVENT_IMAP_CONNECTED, DC_EVENT_SMTP_CONNECTED:
-        logger.warning("network: \(String(cString: data2String))")
+        DcContext.shared.logger?.warning("network: \(String(cString: data2String))")
 
     case DC_EVENT_MSGS_CHANGED, DC_EVENT_MSG_READ, DC_EVENT_MSG_DELIVERED, DC_EVENT_MSG_FAILED:
-        logger.info("change: \(event)")
+        DcContext.shared.logger?.info("change: \(event)")
 
         let nc = NotificationCenter.default
 
@@ -92,7 +92,7 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
         }
 
     case DC_EVENT_CHAT_MODIFIED:
-        logger.info("chat modified: \(event)")
+        DcContext.shared.logger?.info("chat modified: \(event)")
         let nc = NotificationCenter.default
         DispatchQueue.main.async {
             nc.post(
@@ -128,7 +128,7 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
 
                 let request = UNNotificationRequest(identifier: Constants.notificationIdentifier, content: content, trigger: trigger)
                 UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
-                logger.info("notifications: added \(content)")
+                DcContext.shared.logger?.info("notifications: added \(content)")
             }
 
             let array = DcContext.shared.getFreshMessages()
@@ -136,13 +136,13 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
         }
 
     case DC_EVENT_SMTP_MESSAGE_SENT:
-        logger.info("network: \(String(cString: data2String))")
+        DcContext.shared.logger?.info("network: \(String(cString: data2String))")
 
     case DC_EVENT_MSG_DELIVERED:
-        logger.info("message delivered: \(data1)-\(data2)")
+        DcContext.shared.logger?.info("message delivered: \(data1)-\(data2)")
 
     case DC_EVENT_SECUREJOIN_INVITER_PROGRESS:
-        logger.info("securejoin inviter progress \(data1)")
+        DcContext.shared.logger?.info("securejoin inviter progress \(data1)")
 
         let nc = NotificationCenter.default
         DispatchQueue.main.async {
@@ -158,7 +158,7 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
         }
 
     case DC_EVENT_SECUREJOIN_JOINER_PROGRESS:
-        logger.info("securejoin joiner progress \(data1)")
+        DcContext.shared.logger?.info("securejoin joiner progress \(data1)")
         let nc = NotificationCenter.default
         DispatchQueue.main.async {
             nc.post(
@@ -173,7 +173,7 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
             )
         }
     case DC_EVENT_CONTACTS_CHANGED:
-        logger.info("contact changed: \(data1)")
+        DcContext.shared.logger?.info("contact changed: \(data1)")
         let nc = NotificationCenter.default
         DispatchQueue.main.async {
             nc.post(
@@ -186,6 +186,6 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
         }
 
     default:
-        logger.warning("unknown event: \(event)")
+        DcContext.shared.logger?.warning("unknown event: \(event)")
     }
 }

+ 0 - 0
deltachat-ios/DC/wrapper.c → DcCore/DcCore/DC/wrapper.c


+ 0 - 0
deltachat-ios/DC/wrapper.h → DcCore/DcCore/DC/wrapper.h


+ 13 - 0
DcCore/DcCore/DcCore.h

@@ -0,0 +1,13 @@
+#import <Foundation/Foundation.h>
+
+//! Project version number for DcCore.
+FOUNDATION_EXPORT double DcCoreVersionNumber;
+
+//! Project version string for DcCore.
+FOUNDATION_EXPORT const unsigned char DcCoreVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import <DcCore/PublicHeader.h>
+
+
+#import <DcCore/wrapper.h>
+#include "deltachat.h"

+ 23 - 0
DcCore/DcCore/Extensions/String+Extensions.swift

@@ -0,0 +1,23 @@
+import Foundation
+public extension String {
+    
+	static func localized(_ stringID: String) -> String {
+        let value = NSLocalizedString(stringID, comment: "")
+        if value != stringID || NSLocale.preferredLanguages.first == "en" {
+            return value
+        }
+
+        guard
+            let path = Bundle.main.path(forResource: "en", ofType: "lproj"),
+            let bundle = Bundle(path: path)
+        else { return value }
+        return NSLocalizedString(stringID, bundle: bundle, comment: "")
+    }
+
+	static func localized(stringID: String, count: Int) -> String {
+        let formatString: String = localized(stringID)
+        let resultString: String = String.localizedStringWithFormat(formatString, count)
+        return resultString
+    }
+
+}

+ 64 - 0
DcCore/DcCore/Extensions/UIColor+Extensions.swift

@@ -0,0 +1,64 @@
+import UIKit
+
+public extension UIColor {
+
+    convenience init(alpha: Int, red: Int, green: Int, blue: Int) {
+        assert(red >= 0 && red <= 255, "Invalid red component")
+        assert(green >= 0 && green <= 255, "Invalid green component")
+        assert(blue >= 0 && blue <= 255, "Invalid blue component")
+
+        self.init(red: CGFloat(red) / 255, green: CGFloat(green) / 255, blue: CGFloat(blue) / 255, alpha: CGFloat(alpha) / 255)
+    }
+
+    convenience init(netHex: Int) {
+        var alpha = (netHex >> 24) & 0xFF
+        if alpha == 0 {
+            alpha = 255
+        }
+
+        self.init(alpha: alpha, red: (netHex >> 16) & 0xFF, green: (netHex >> 8) & 0xFF, blue: netHex & 0xFF)
+    }
+
+    // see: https://stackoverflow.com/a/33397427
+    convenience init(hexString: String) {
+        let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
+        var int = UInt32()
+        Scanner(string: hex).scanHexInt32(&int)
+        let a, r, g, b: UInt32
+        switch hex.count {
+        case 3: // RGB (12-bit)
+            (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
+        case 6: // RGB (24-bit)
+            (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
+        case 8: // ARGB (32-bit)
+            (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
+        default:
+            (a, r, g, b) = (255, 0, 0, 0)
+        }
+        self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
+    }
+
+	static func themeColor(light: UIColor, dark: UIColor? = nil) -> UIColor {
+        if let dark = dark {
+            if #available(iOS 13, *) {
+                return UIColor.init { (trait) -> UIColor in
+                    return trait.userInterfaceStyle == .dark ? dark : light
+                }
+            }
+        }
+        return light
+    }
+
+    static func themeColor(lightHex: String, darkHex: String? = nil) -> UIColor {
+        if let darkHex = darkHex {
+            if #available(iOS 13, *) {
+                return UIColor.init { (trait) -> UIColor in
+                    return trait.userInterfaceStyle == .dark ? UIColor(hexString: darkHex) :  UIColor(hexString: lightHex)
+                }
+            }
+        }
+        return UIColor(hexString: lightHex)
+    }
+
+
+}

+ 11 - 0
DcCore/DcCore/Helper/Constants.swift

@@ -0,0 +1,11 @@
+import UIKit
+
+public struct Constants {
+
+    public struct Keys {
+        static let deltachatUserProvidedCredentialsKey = "__DELTACHAT_USER_PROVIDED_CREDENTIALS_KEY__"
+        static let deltachatImapEmailKey = "__DELTACHAT_IMAP_EMAIL_KEY__"
+        static let deltachatImapPasswordKey = "__DELTACHAT_IMAP_PASSWORD_KEY__"
+    }
+    public static let notificationIdentifier = "deltachat-ios-local-notifications"
+}

+ 78 - 0
DcCore/DcCore/Helper/DateUtils.swift

@@ -0,0 +1,78 @@
+import Foundation
+
+public class DateUtils {
+    typealias DtU = DateUtils
+    static let minute: Double = 60
+    static let hour: Double = 3600
+    static let day: Double = 86400
+    static let year: Double = 365 * day
+
+    public static func getRelativeTimeInSeconds(timeStamp: Double) -> Double {
+        let unixTime = Double(Date().timeIntervalSince1970)
+        return unixTime - timeStamp
+    }
+
+    private static func is24hDefault() -> Bool {
+        let dateString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current) ?? ""
+        return !dateString.contains("a")
+    }
+
+    private static func getLocalDateFormatter() -> DateFormatter {
+        let formatter = DateFormatter()
+        formatter.timeZone = .current
+        formatter.locale = .current
+        return formatter
+    }
+
+    public static func getExtendedRelativeTimeSpanString(timeStamp: Double) -> String {
+        let seconds = getRelativeTimeInSeconds(timeStamp: timeStamp)
+        let date = Date(timeIntervalSince1970: timeStamp)
+        let formatter = getLocalDateFormatter()
+        let is24h = is24hDefault()
+
+        if seconds < DtU.minute {
+            return String.localized("now")
+        } else if seconds < DtU.hour {
+            let mins = seconds / DtU.minute
+            return String.localized(stringID: "n_minutes", count: Int(mins))
+        } else if seconds < DtU.day {
+            formatter.dateFormat = is24h ?  "HH:mm" : "hh:mm a"
+            return formatter.string(from: date)
+        } else if seconds < 6 * DtU.day {
+            formatter.dateFormat = is24h ?  "EEE, HH:mm" : "EEE, hh:mm a"
+            return formatter.string(from: date)
+        } else if seconds < DtU.year {
+            formatter.dateFormat = is24h ? "MMM d, HH:mm" : "MMM d, hh:mm a"
+            return formatter.string(from: date)
+        } else {
+            formatter.dateFormat = is24h ? "MMM d, yyyy, HH:mm" : "MMM d, yyyy, hh:mm a"
+            return formatter.string(from: date)
+        }
+    }
+
+    public static func getBriefRelativeTimeSpanString(timeStamp: Double) -> String {
+        let seconds = getRelativeTimeInSeconds(timeStamp: timeStamp)
+        let date = Date(timeIntervalSince1970: timeStamp)
+        let formatter = getLocalDateFormatter()
+
+        if seconds < DtU.minute {
+            return String.localized("now")    // under one minute
+        } else if seconds < DtU.hour {
+            let mins = seconds / DtU.minute
+            return String.localized(stringID: "n_minutes", count: Int(mins))
+        } else if seconds < DtU.day {
+            let hours = seconds / DtU.hour
+            return String.localized(stringID: "n_hours", count: Int(hours))
+        } else if seconds < DtU.day * 6 {
+            formatter.dateFormat = "EEE"
+            return formatter.string(from: date)
+        } else if seconds < DtU.year {
+            formatter.dateFormat = "MMM d"
+            return formatter.string(from: date)
+        } else {
+            formatter.dateFormat = "MMM d, yyyy"
+            let localDate = formatter.string(from: date)
+            return localDate
+        }
+    }
+}

+ 54 - 0
DcCore/DcCore/Helper/DcUtils.swift

@@ -0,0 +1,54 @@
+import Foundation
+import UIKit
+
+public struct DcUtils {
+
+    static func copyAndFreeArray(inputArray: OpaquePointer?) -> [Int] {
+        var acc: [Int] = []
+        let len = dc_array_get_cnt(inputArray)
+        for i in 0 ..< len {
+            let e = dc_array_get_id(inputArray, i)
+            acc.append(Int(e))
+        }
+        dc_array_unref(inputArray)
+
+        return acc
+    }
+
+    static func copyAndFreeArrayWithLen(inputArray: OpaquePointer?, len: Int = 0) -> [Int] {
+        var acc: [Int] = []
+        let arrayLen = dc_array_get_cnt(inputArray)
+        let start = max(0, arrayLen - len)
+        for i in start ..< arrayLen {
+            let e = dc_array_get_id(inputArray, i)
+            acc.append(Int(e))
+        }
+        dc_array_unref(inputArray)
+
+        return acc
+    }
+
+    static func copyAndFreeArrayWithOffset(inputArray: OpaquePointer?, len: Int = 0, from: Int = 0, skipEnd: Int = 0) -> [Int] {
+        let lenArray = dc_array_get_cnt(inputArray)
+        if lenArray <= skipEnd || lenArray == 0 {
+            dc_array_unref(inputArray)
+            return []
+        }
+
+        let start = lenArray - 1 - skipEnd
+        let end = max(0, start - len)
+        let finalLen = start - end + (len > 0 ? 0 : 1)
+        var acc: [Int] = [Int](repeating: 0, count: finalLen)
+
+        for i in stride(from: start, to: end, by: -1) {
+            let index = finalLen - (start - i) - 1
+            acc[index] = Int(dc_array_get_id(inputArray, i))
+        }
+
+        dc_array_unref(inputArray)
+        DcContext.shared.logger?.info("got: \(from) \(len) \(lenArray) - \(acc)")
+
+        return acc
+    }
+
+}

+ 22 - 0
DcCore/DcCore/Info.plist

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>$(CURRENT_PROJECT_VERSION)</string>
+</dict>
+</plist>

+ 26 - 0
DcCore/DcCoreTests/DcCoreTests.swift

@@ -0,0 +1,26 @@
+import XCTest
+@testable import DcCore
+
+class DcCoreTests: XCTestCase {
+
+    override func setUpWithError() throws {
+        // Put setup code here. This method is called before the invocation of each test method in the class.
+    }
+
+    override func tearDownWithError() throws {
+        // Put teardown code here. This method is called after the invocation of each test method in the class.
+    }
+
+    func testExample() throws {
+        // This is an example of a functional test case.
+        // Use XCTAssert and related functions to verify your tests produce the correct results.
+    }
+
+    func testPerformanceExample() throws {
+        // This is an example of a performance test case.
+        self.measure {
+            // Put the code you want to measure the time of here.
+        }
+    }
+
+}

+ 22 - 0
DcCore/DcCoreTests/Info.plist

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>

+ 35 - 31
deltachat-ios.xcodeproj/project.pbxproj

@@ -19,6 +19,8 @@
 		3040F45E234DFBC000FA34D5 /* Audio.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3040F45D234DFBC000FA34D5 /* Audio.swift */; };
 		3040F460234F419400FA34D5 /* BasicAudioController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3040F45F234F419300FA34D5 /* BasicAudioController.swift */; };
 		3040F462234F550300FA34D5 /* AudioPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3040F461234F550300FA34D5 /* AudioPlayerView.swift */; };
+		304219D3243F588500516852 /* DcCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 304219D1243F588500516852 /* DcCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304219D82440734A00516852 /* DcMsg+Extension.swift */; };
 		305961CC2346125100C80F33 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305961822346125000C80F33 /* UIView+Extensions.swift */; };
 		305961CD2346125100C80F33 /* UIEdgeInsets+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305961832346125000C80F33 /* UIEdgeInsets+Extensions.swift */; };
 		305961CF2346125100C80F33 /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305961852346125000C80F33 /* UIColor+Extensions.swift */; };
@@ -87,6 +89,7 @@
 		305FE03623A81B4C0053BE90 /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305FE03523A81B4C0053BE90 /* PaddingLabel.swift */; };
 		3060119C22DDE24000C1CE6F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3060119E22DDE24000C1CE6F /* Localizable.strings */; };
 		306011B622E5E7FB00C1CE6F /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 306011B422E5E7FB00C1CE6F /* Localizable.stringsdict */; };
+		306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306C32312445CDE9001D89F3 /* DcLogger.swift */; };
 		307D822E241669C7006D2490 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307D822D241669C7006D2490 /* LocationManager.swift */; };
 		3095A351237DD1F700AB07F7 /* MediaPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3095A350237DD1F700AB07F7 /* MediaPicker.swift */; };
 		30A4D9AE2332672700544344 /* QrInviteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A4D9AD2332672600544344 /* QrInviteViewController.swift */; };
@@ -100,7 +103,6 @@
 		70B8882E2091B8550074812E /* ContactCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70B8882D2091B8550074812E /* ContactCell.swift */; };
 		7837B64021E54DC600CDE126 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 7837B63F21E54DC600CDE126 /* .swiftlint.yml */; };
 		785BE16821E247F1003BE98C /* MessageInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 785BE16721E247F1003BE98C /* MessageInfoViewController.swift */; };
-		787D669A229F2237000A7A9D /* libdeltachat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 787D6699229F2237000A7A9D /* libdeltachat.a */; };
 		789E879621D6CB58003ED1C5 /* QrCodeReaderController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E879521D6CB58003ED1C5 /* QrCodeReaderController.swift */; };
 		789E879D21D6DF86003ED1C5 /* ProgressHud.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E879C21D6DF86003ED1C5 /* ProgressHud.swift */; };
 		78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3921D3CFBC00D4B15E /* SettingsController.swift */; };
@@ -108,12 +110,9 @@
 		78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */; };
 		78E45E4C21D404AE00D4B15E /* InfoMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4B21D404AE00D4B15E /* InfoMessageCell.swift */; };
 		78ED838321D5379000243125 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838221D5379000243125 /* TextFieldCell.swift */; };
-		78ED838D21D577D000243125 /* events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838C21D577D000243125 /* events.swift */; };
 		78ED839421D5AF8A00243125 /* QrCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED839321D5AF8A00243125 /* QrCodeView.swift */; };
 		7A0052C81FBE6CB40048C3BF /* NewContactController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0052C71FBE6CB40048C3BF /* NewContactController.swift */; };
-		7A451D941FB1B1DB00177250 /* wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 7A451D921FB1B1DB00177250 /* wrapper.c */; };
 		7A451DB01FB1F84900177250 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A451DAF1FB1F84900177250 /* AppCoordinator.swift */; };
-		7A451DBE1FB4AD0700177250 /* Wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A451DBD1FB4AD0700177250 /* Wrapper.swift */; };
 		7A9FB1441FB061E2001FEA36 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FB1431FB061E2001FEA36 /* AppDelegate.swift */; };
 		7A9FB14B1FB061E2001FEA36 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A9FB14A1FB061E2001FEA36 /* Assets.xcassets */; };
 		7A9FB14E1FB061E2001FEA36 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7A9FB14C1FB061E2001FEA36 /* LaunchScreen.storyboard */; };
@@ -176,6 +175,20 @@
 		};
 /* End PBXContainerItemProxy section */
 
+/* Begin PBXCopyFilesBuildPhase section */
+		304219D4243F588600516852 /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+				304219D3243F588500516852 /* DcCore.framework in Embed Frameworks */,
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 		21EE28844E7A690D73BF5285 /* Pods-deltachat-iosTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-deltachat-iosTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-deltachat-iosTests/Pods-deltachat-iosTests.debug.xcconfig"; sourceTree = "<group>"; };
 		2F7009234DB9408201A6CDCB /* Pods_deltachat_iosTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_deltachat_iosTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -209,6 +222,8 @@
 		3040F45D234DFBC000FA34D5 /* Audio.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Audio.swift; sourceTree = "<group>"; };
 		3040F45F234F419300FA34D5 /* BasicAudioController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicAudioController.swift; sourceTree = "<group>"; };
 		3040F461234F550300FA34D5 /* AudioPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerView.swift; sourceTree = "<group>"; };
+		304219D1243F588500516852 /* DcCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DcCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		304219D82440734A00516852 /* DcMsg+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DcMsg+Extension.swift"; sourceTree = "<group>"; };
 		305961822346125000C80F33 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
 		305961832346125000C80F33 /* UIEdgeInsets+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIEdgeInsets+Extensions.swift"; sourceTree = "<group>"; };
 		305961852346125000C80F33 /* UIColor+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Extensions.swift"; sourceTree = "<group>"; };
@@ -316,6 +331,7 @@
 		306011C722E5E82E00C1CE6F /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lt; path = lt.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
 		306011C822E5E83100C1CE6F /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
 		306011C922E5E83500C1CE6F /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
+		306C32312445CDE9001D89F3 /* DcLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcLogger.swift; sourceTree = "<group>"; };
 		307D822D241669C7006D2490 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
 		3095A350237DD1F700AB07F7 /* MediaPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPicker.swift; sourceTree = "<group>"; };
 		30A4D9AD2332672600544344 /* QrInviteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrInviteViewController.swift; sourceTree = "<group>"; };
@@ -334,25 +350,19 @@
 		789E879521D6CB58003ED1C5 /* QrCodeReaderController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeReaderController.swift; sourceTree = "<group>"; };
 		789E879C21D6DF86003ED1C5 /* ProgressHud.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressHud.swift; sourceTree = "<group>"; };
 		78C7036A21D46752005D4525 /* deltachat-ios.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "deltachat-ios.entitlements"; sourceTree = "<group>"; };
-		78E45E2121D1768900D4B15E /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; name = src; path = "deltachat-ios/libraries/deltachat-core/src"; sourceTree = "<group>"; };
 		78E45E3921D3CFBC00D4B15E /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
 		78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = "<group>"; };
 		78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = "<group>"; };
 		78E45E4B21D404AE00D4B15E /* InfoMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoMessageCell.swift; sourceTree = "<group>"; };
 		78ED838221D5379000243125 /* TextFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
-		78ED838C21D577D000243125 /* events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = events.swift; sourceTree = "<group>"; };
 		78ED839321D5AF8A00243125 /* QrCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeView.swift; sourceTree = "<group>"; };
 		7A0052C71FBE6CB40048C3BF /* NewContactController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewContactController.swift; sourceTree = "<group>"; };
-		7A451D921FB1B1DB00177250 /* wrapper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = wrapper.c; sourceTree = "<group>"; };
-		7A451D931FB1B1DB00177250 /* wrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrapper.h; sourceTree = "<group>"; };
 		7A451DAF1FB1F84900177250 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
-		7A451DBD1FB4AD0700177250 /* Wrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wrapper.swift; sourceTree = "<group>"; };
 		7A9FB1401FB061E2001FEA36 /* deltachat-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "deltachat-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		7A9FB1431FB061E2001FEA36 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		7A9FB14A1FB061E2001FEA36 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		7A9FB14D1FB061E2001FEA36 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		7A9FB14F1FB061E2001FEA36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		7A9FB1561FB06540001FEA36 /* deltachat-ios-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "deltachat-ios-Bridging-Header.h"; sourceTree = "<group>"; };
 		7AE0A5481FC42F65005ECB4B /* NewChatViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewChatViewController.swift; sourceTree = "<group>"; };
 		8DE110C607A0E4485C43B5FA /* Pods-deltachat-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-deltachat-ios.debug.xcconfig"; path = "Pods/Target Support Files/Pods-deltachat-ios/Pods-deltachat-ios.debug.xcconfig"; sourceTree = "<group>"; };
 		A8615D4600859851E53CAA9C /* Pods-deltachat-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-deltachat-ios.release.xcconfig"; path = "Pods/Target Support Files/Pods-deltachat-ios/Pods-deltachat-ios.release.xcconfig"; sourceTree = "<group>"; };
@@ -447,7 +457,6 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				787D669A229F2237000A7A9D /* libdeltachat.a in Frameworks */,
 				8B6D425BC604F7C43B65D436 /* Pods_deltachat_ios.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -463,6 +472,15 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		304219D7244072E600516852 /* DC */ = {
+			isa = PBXGroup;
+			children = (
+				304219D82440734A00516852 /* DcMsg+Extension.swift */,
+				306C32312445CDE9001D89F3 /* DcLogger.swift */,
+			);
+			path = DC;
+			sourceTree = "<group>";
+		};
 		3059617E234610A800C80F33 /* MessageKit */ = {
 			isa = PBXGroup;
 			children = (
@@ -622,7 +640,6 @@
 				3060119E22DDE24000C1CE6F /* Localizable.strings */,
 				306011B422E5E7FB00C1CE6F /* Localizable.stringsdict */,
 				7837B63F21E54DC600CDE126 /* .swiftlint.yml */,
-				78E45E2121D1768900D4B15E /* src */,
 				7A9FB1421FB061E2001FEA36 /* deltachat-ios */,
 				AE851A02227AECDE00ED86F0 /* deltachat-iosTests */,
 				7A9FB1411FB061E2001FEA36 /* Products */,
@@ -646,13 +663,13 @@
 		7A9FB1421FB061E2001FEA36 /* deltachat-ios */ = {
 			isa = PBXGroup;
 			children = (
+				304219D7244072E600516852 /* DC */,
 				AE1988AA23EB3C7600B4CD5F /* Assets */,
 				AE19887623EB2BDA00B4CD5F /* Assets */,
 				AE77838B23E32EAA0093EABD /* ViewModel */,
 				305961812346125000C80F33 /* Extensions */,
 				3059617E234610A800C80F33 /* MessageKit */,
 				7A9FB1431FB061E2001FEA36 /* AppDelegate.swift */,
-				AE851ACA227C79CF00ED86F0 /* DC */,
 				AE851AC3227C695900ED86F0 /* View */,
 				AE851AC2227C695000ED86F0 /* Helper */,
 				AE851AC1227C694300ED86F0 /* Coordinator */,
@@ -660,7 +677,6 @@
 				AE851ABA227C692600ED86F0 /* Model */,
 				AE851ACB227C7A5000ED86F0 /* Handler */,
 				7A9FB15B1FB07364001FEA36 /* libraries */,
-				7A9FB1561FB06540001FEA36 /* deltachat-ios-Bridging-Header.h */,
 				78C7036A21D46752005D4525 /* deltachat-ios.entitlements */,
 				7A9FB14A1FB061E2001FEA36 /* Assets.xcassets */,
 				7A9FB14C1FB061E2001FEA36 /* LaunchScreen.storyboard */,
@@ -680,6 +696,7 @@
 		7A9FB4F81FB084E6001FEA36 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				304219D1243F588500516852 /* DcCore.framework */,
 				787D6699229F2237000A7A9D /* libdeltachat.a */,
 				6241BE1534A653E79AD5D01D /* Pods_deltachat_ios.framework */,
 				2F7009234DB9408201A6CDCB /* Pods_deltachat_iosTests.framework */,
@@ -836,17 +853,6 @@
 			path = View;
 			sourceTree = "<group>";
 		};
-		AE851ACA227C79CF00ED86F0 /* DC */ = {
-			isa = PBXGroup;
-			children = (
-				7A451D931FB1B1DB00177250 /* wrapper.h */,
-				7A451DBD1FB4AD0700177250 /* Wrapper.swift */,
-				78ED838C21D577D000243125 /* events.swift */,
-				7A451D921FB1B1DB00177250 /* wrapper.c */,
-			);
-			path = DC;
-			sourceTree = "<group>";
-		};
 		AE851ACB227C7A5000ED86F0 /* Handler */ = {
 			isa = PBXGroup;
 			children = (
@@ -873,6 +879,7 @@
 				30C8FE37A924BE7AFF9661C1 /* [CP] Embed Pods Frameworks */,
 				7837B63821E54CB400CDE126 /* Run Script */,
 				7837B64621E5532B00CDE126 /* ShellScript */,
+				304219D4243F588600516852 /* Embed Frameworks */,
 			);
 			buildRules = (
 			);
@@ -1136,7 +1143,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "# The $PATH used by XCode likely won't contain Cargo, fix that.\n# This assumes a default `rustup` setup.\nexport PATH=\"$HOME/.cargo/bin:$PATH\"\n\nexport CFLAGS_x86_64_apple_darwin=\"-I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include\"\n\n# ensure all targets are installed\nrustup target add aarch64-apple-ios x86_64-apple-ios --toolchain `cat deltachat-ios/libraries/deltachat-core-rust/rust-toolchain`\n\n# --xcode-integ determines --release and --targets from XCode's env vars.\n# Depending your setup, specify the rustup toolchain explicitly.\ncargo +`cat deltachat-ios/libraries/deltachat-core-rust/rust-toolchain` lipo --release --manifest-path deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi/Cargo.toml --no-default-features --features nightly\n";
+			shellScript = "# The $PATH used by XCode likely won't contain Cargo, fix that.\n# This assumes a default `rustup` setup.\n export PATH=\"$HOME/.cargo/bin:$PATH\"\n\n export CFLAGS_x86_64_apple_darwin=\"-I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include\"\n\n# ensure all targets are installed\n rustup target add aarch64-apple-ios x86_64-apple-ios --toolchain `cat deltachat-ios/libraries/deltachat-core-rust/rust-toolchain`\n\n# --xcode-integ determines --release and --targets from XCode's env vars.\n# Depending your setup, specify the rustup toolchain explicitly.\n cargo +`cat deltachat-ios/libraries/deltachat-core-rust/rust-toolchain` lipo --release --manifest-path deltachat-ios/libraries/deltachat-core-rust/deltachat-ffi/Cargo.toml --no-default-features --features nightly\n";
 		};
 /* End PBXShellScriptBuildPhase section */
 
@@ -1159,6 +1166,7 @@
 				7070FB9B2101ECBB000DC258 /* NewGroupController.swift in Sources */,
 				305961EA2346125100C80F33 /* MessageStyle.swift in Sources */,
 				305961F92346125100C80F33 /* MessageLabel.swift in Sources */,
+				304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */,
 				305961FA2346125100C80F33 /* MessageReusableView.swift in Sources */,
 				3040F462234F550300FA34D5 /* AudioPlayerView.swift in Sources */,
 				AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */,
@@ -1168,7 +1176,6 @@
 				AE52EA20229EB9F000C586C9 /* EditGroupViewController.swift in Sources */,
 				70B08FCD21073B910097D3EA /* NewGroupMemberChoiceController.swift in Sources */,
 				AE18F294228C602A0007B1BE /* SecuritySettingsController.swift in Sources */,
-				78ED838D21D577D000243125 /* events.swift in Sources */,
 				305961FD2346125100C80F33 /* TypingBubble.swift in Sources */,
 				305961D72346125100C80F33 /* MessageKit+Availability.swift in Sources */,
 				3040F45E234DFBC000FA34D5 /* Audio.swift in Sources */,
@@ -1200,6 +1207,7 @@
 				AEE6EC3F2282C59C00EDC689 /* GroupMembersViewController.swift in Sources */,
 				B26B3BC7236DC3DC008ED35A /* SwitchCell.swift in Sources */,
 				AEE700252438E0E500D6992E /* ProgressAlertHandler.swift in Sources */,
+				306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */,
 				78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */,
 				AE8519EA2272FDCA00ED86F0 /* DeviceContactsHandler.swift in Sources */,
 				3059620B2346125100C80F33 /* LocationMessageSizeCalculator.swift in Sources */,
@@ -1255,7 +1263,6 @@
 				305961D22346125100C80F33 /* CGRect+Extensions.swift in Sources */,
 				305961E12346125100C80F33 /* LocationItem.swift in Sources */,
 				305961E72346125100C80F33 /* AccessoryPosition.swift in Sources */,
-				7A451DBE1FB4AD0700177250 /* Wrapper.swift in Sources */,
 				30260CA7238F02F700D8D52C /* MultilineTextFieldCell.swift in Sources */,
 				305961DE2346125100C80F33 /* MessageType.swift in Sources */,
 				AE851ACE227CA54400ED86F0 /* InitialsBadge.swift in Sources */,
@@ -1263,7 +1270,6 @@
 				305961EB2346125100C80F33 /* MessageKitError.swift in Sources */,
 				70B8882E2091B8550074812E /* ContactCell.swift in Sources */,
 				305961F82346125100C80F33 /* AudioMessageCell.swift in Sources */,
-				7A451D941FB1B1DB00177250 /* wrapper.c in Sources */,
 				305961EC2346125100C80F33 /* Avatar.swift in Sources */,
 				305961CD2346125100C80F33 /* UIEdgeInsets+Extensions.swift in Sources */,
 				305962032346125100C80F33 /* CellSizeCalculator.swift in Sources */,
@@ -1623,7 +1629,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = chat.delta;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
-				SWIFT_OBJC_BRIDGING_HEADER = "deltachat-ios/deltachat-ios-Bridging-Header.h";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 				SWIFT_VERSION = 4.2;
 				TARGETED_DEVICE_FAMILY = "1,2";
@@ -1697,7 +1702,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = chat.delta;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
-				SWIFT_OBJC_BRIDGING_HEADER = "deltachat-ios/deltachat-ios-Bridging-Header.h";
 				SWIFT_VERSION = 4.2;
 				TARGETED_DEVICE_FAMILY = "1,2";
 			};

+ 3 - 0
deltachat-ios.xcworkspace/contents.xcworkspacedata

@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Workspace
    version = "1.0">
+   <FileRef
+      location = "group:DcCore/DcCore.xcodeproj">
+   </FileRef>
    <FileRef
       location = "group:deltachat-ios.xcodeproj">
    </FileRef>

+ 2 - 0
deltachat-ios/AppDelegate.swift

@@ -4,6 +4,7 @@ import Reachability
 import SwiftyBeaver
 import UIKit
 import UserNotifications
+import DcCore
 
 let logger = SwiftyBeaver.self
 
@@ -51,6 +52,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
         let console = ConsoleDestination()
         logger.addDestination(console)
+        dcContext.logger = DcLogger()
 
         logger.info("launching")
 

+ 1 - 0
deltachat-ios/Controller/AccountSetup/CertificateCheckController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class CertificateCheckController: UITableViewController {
 

+ 1 - 0
deltachat-ios/Controller/AccountSetup/SecuritySettingsController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class SecuritySettingsController: UITableViewController {
 

+ 1 - 0
deltachat-ios/Controller/AccountSetupController.swift

@@ -1,5 +1,6 @@
 import SafariServices
 import UIKit
+import DcCore
 
 class AccountSetupController: UITableViewController, ProgressAlertHandler {
 

+ 1 - 0
deltachat-ios/Controller/ChatListController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class ChatListController: UITableViewController {
     weak var coordinator: ChatListCoordinator?

+ 2 - 9
deltachat-ios/Controller/ChatViewController.swift

@@ -3,6 +3,7 @@ import QuickLook
 import UIKit
 import InputBarAccessoryView
 import AVFoundation
+import DcCore
 
 protocol MediaSendHandler {
     func onSuccess()
@@ -354,15 +355,7 @@ class ChatViewController: MessagesViewController {
     }
 
     private func getMessageIds(_ count: Int, from: Int? = nil) -> [DcMsg] {
-        let cMessageIds = dcContext.getChatMessages(chatId: chatId)
-
-        let ids: [Int]
-        if let from = from {
-            ids = Utils.copyAndFreeArrayWithOffset(inputArray: cMessageIds, len: count, skipEnd: from)
-        } else {
-            ids = Utils.copyAndFreeArrayWithLen(inputArray: cMessageIds, len: count)
-        }
-
+        let ids = dcContext.getMessageIds(chatId: chatId, count: count, from: from)
         let markIds: [UInt32] = ids.map { UInt32($0) }
         dcContext.markSeenMessages(messageIds: markIds, count: ids.count)
 

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

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class EditContactController: NewContactController {
 

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

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class EditGroupViewController: UITableViewController, MediaPickerDelegate {
 

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

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class EditSettingsController: UITableViewController, MediaPickerDelegate {
 

+ 1 - 0
deltachat-ios/Controller/GroupChatDetailViewController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class GroupChatDetailViewController: UIViewController {
 

+ 1 - 0
deltachat-ios/Controller/GroupMembersViewController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class NewGroupAddMembersViewController: GroupMembersViewController {
     weak var coordinator: NewGroupAddMembersCoordinator?

+ 1 - 0
deltachat-ios/Controller/MailboxViewController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class MailboxViewController: ChatViewController {
 

+ 1 - 0
deltachat-ios/Controller/MessageInfoViewController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class MessageInfoViewController: UITableViewController {
     var dcContext: DcContext

+ 1 - 0
deltachat-ios/Controller/NewChatViewController.swift

@@ -1,6 +1,7 @@
 import ALCameraViewController
 import Contacts
 import UIKit
+import DcCore
 
 class NewChatViewController: UITableViewController {
     weak var coordinator: NewChatCoordinator?

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

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class NewContactController: UITableViewController {
 

+ 1 - 0
deltachat-ios/Controller/NewGroupController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class NewGroupController: UITableViewController, MediaPickerDelegate {
 

+ 1 - 0
deltachat-ios/Controller/QrInviteViewController.swift

@@ -1,5 +1,6 @@
 import Foundation
 import UIKit
+import DcCore
 
 class QrInviteViewController: UITableViewController {
     private let rowQRCode = 0

+ 1 - 0
deltachat-ios/Controller/QrViewController.swift

@@ -1,5 +1,6 @@
 import Foundation
 import UIKit
+import DcCore
 
 class QrViewController: UITableViewController {
     private let rowQRCode = 0

+ 1 - 0
deltachat-ios/Controller/SettingsAutodelOverviewController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class SettingsAutodelOverviewController: UITableViewController {
 

+ 1 - 0
deltachat-ios/Controller/SettingsAutodelSetController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class SettingsAutodelSetController: UITableViewController {
 

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

@@ -1,5 +1,5 @@
 import UIKit
-
+import DcCore
 class SettingsClassicViewController: UITableViewController {
 
     var dcContext: DcContext

+ 1 - 0
deltachat-ios/Controller/SettingsController.swift

@@ -1,5 +1,6 @@
 import JGProgressHUD
 import UIKit
+import DcCore
 
 internal final class SettingsViewController: UITableViewController {
 

+ 1 - 0
deltachat-ios/Controller/WelcomeViewController.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class WelcomeViewController: UIViewController, ProgressAlertHandler {
 

+ 1 - 0
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -2,6 +2,7 @@ import UIKit
 import ALCameraViewController
 import Photos
 import MobileCoreServices
+import DcCore
 
 class AppCoordinator: NSObject, Coordinator {
 

+ 26 - 0
deltachat-ios/DC/DcLogger.swift

@@ -0,0 +1,26 @@
+import Foundation
+import DcCore
+
+class DcLogger: Logger {
+    func verbose(_ message: String) {
+        logger.verbose(message)
+    }
+
+    func debug(_ message: String) {
+        logger.debug(message)
+    }
+
+    func info(_ message: String) {
+        logger.info(message)
+    }
+
+    func warning(_ message: String) {
+        logger.warning(message)
+    }
+
+    func error(_ message: String) {
+        logger.error(message)
+    }
+
+
+}

+ 93 - 0
deltachat-ios/DC/DcMsg+Extension.swift

@@ -0,0 +1,93 @@
+import Foundation
+import DcCore
+import UIKit
+import AVFoundation
+
+extension DcMsg: MessageType {
+    
+    public var sender: SenderType {
+        return Sender(id: "\(fromContactId)", displayName: fromContact.displayName)
+    }
+
+    public var kind: MessageKind {
+        if isInfo {
+            let text = NSAttributedString(string: self.text ?? "", attributes: [
+                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12),
+                NSAttributedString.Key.foregroundColor: DcColors.grayTextColor,
+                ])
+            return MessageKind.info(text)
+        } else if isSetupMessage {
+            return MessageKind.text(String.localized("autocrypt_asm_click_body"))
+        }
+
+        let text = self.text ?? ""
+
+        if self.viewtype == nil {
+            return MessageKind.text(text)
+        }
+
+        switch self.viewtype! {
+        case .image:
+            return createImageMessage(text: text)
+        case .video:
+            return createVideoMessage(text: text)
+        case .voice, .audio:
+            return createAudioMessage(text: text)
+        default:
+            // TODO: custom views for audio, etc
+            if let _ = self.filename {
+                if Utils.hasAudioSuffix(url: fileURL!) {
+                   return createAudioMessage(text: text)
+                }
+                return createFileMessage(text: text)
+            }
+            return MessageKind.text(text)
+        }
+    }
+
+    internal func createVideoMessage(text: String) -> MessageKind {
+        let thumbnail = Utils.generateThumbnailFromVideo(url: fileURL)
+        if text.isEmpty {
+            return MessageKind.video(Media(url: fileURL, image: thumbnail))
+        }
+        let attributedString = NSAttributedString(string: text, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16.0),
+                                                                             NSAttributedString.Key.foregroundColor: DcColors.defaultTextColor])
+        return MessageKind.videoText(Media(url: fileURL, image: thumbnail, text: attributedString))
+    }
+
+    internal func createImageMessage(text: String) -> MessageKind {
+        if text.isEmpty {
+            return MessageKind.photo(Media(image: image))
+        }
+        let attributedString = NSAttributedString(string: text, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16.0),
+                                                                             NSAttributedString.Key.foregroundColor: DcColors.defaultTextColor])
+        return MessageKind.photoText(Media(image: image, text: attributedString))
+    }
+
+    internal func createAudioMessage(text: String) -> MessageKind {
+        let audioAsset = AVURLAsset(url: fileURL!)
+        let seconds = Float(CMTimeGetSeconds(audioAsset.duration))
+        if !text.isEmpty {
+            let attributedString = NSAttributedString(string: text, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16.0),
+                                                                                 NSAttributedString.Key.foregroundColor: DcColors.defaultTextColor])
+            return MessageKind.audio(Audio(url: audioAsset.url, duration: seconds, text: attributedString))
+        }
+        return MessageKind.audio(Audio(url: fileURL!, duration: seconds))
+    }
+
+    internal func createFileMessage(text: String) -> MessageKind {
+        let fileString = "\(self.filename ?? "???") (\(self.filesize / 1024) kB)"
+        let attributedFileString = NSMutableAttributedString(string: fileString,
+                                                             attributes: [NSAttributedString.Key.font: UIFont.italicSystemFont(ofSize: 13.0),
+                                                                          NSAttributedString.Key.foregroundColor: DcColors.defaultTextColor])
+        if !text.isEmpty {
+            attributedFileString.append(NSAttributedString(string: "\n\n",
+                                                           attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 7.0)]))
+            attributedFileString.append(NSAttributedString(string: text,
+                                                           attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16.0),
+                                                                        NSAttributedString.Key.foregroundColor: DcColors.defaultTextColor]))
+        }
+        return MessageKind.fileText(Media(text: attributedFileString))
+    }
+    
+}

+ 1 - 0
deltachat-ios/Extensions/DcContact+Extension.swift

@@ -1,4 +1,5 @@
 import Foundation
+import DcCore
 
 extension DcContact {
     func contains(searchText text: String) -> [ContactHighlights] {

+ 0 - 19
deltachat-ios/Extensions/String+Extension.swift

@@ -74,25 +74,6 @@ extension String {
         return attributedText
     }
 
-    static func localized(_ stringID: String) -> String {
-        let value = NSLocalizedString(stringID, comment: "")
-        if value != stringID || NSLocale.preferredLanguages.first == "en" {
-            return value
-        }
-
-        guard
-            let path = Bundle.main.path(forResource: "en", ofType: "lproj"),
-            let bundle = Bundle(path: path)
-        else { return value }
-        return NSLocalizedString(stringID, bundle: bundle, comment: "")
-    }
-
-    static func localized(stringID: String, count: Int) -> String {
-        let formatString: String = localized(stringID)
-        let resultString: String = String.localizedStringWithFormat(formatString, count)
-        return resultString
-    }
-
     static func timeStringForInterval(_ interval: TimeInterval) -> String {
         let time = NSInteger(interval)
         let seconds = time % 60

+ 1 - 59
deltachat-ios/Extensions/UIColor+Extensions.swift

@@ -35,63 +35,5 @@ internal extension UIColor {
     static let inputBarGray = UIColor(red: 247/255, green: 247/255, blue: 247/255, alpha: 1.0)
     static let playButtonLightGray = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1.0)
     static let sendButtonBlue = UIColor(red: 15/255, green: 135/255, blue: 255/255, alpha: 1.0)
-
-    convenience init(alpha: Int, red: Int, green: Int, blue: Int) {
-        assert(red >= 0 && red <= 255, "Invalid red component")
-        assert(green >= 0 && green <= 255, "Invalid green component")
-        assert(blue >= 0 && blue <= 255, "Invalid blue component")
-
-        self.init(red: CGFloat(red) / 255, green: CGFloat(green) / 255, blue: CGFloat(blue) / 255, alpha: CGFloat(alpha) / 255)
-    }
-
-    convenience init(netHex: Int) {
-        var alpha = (netHex >> 24) & 0xFF
-        if alpha == 0 {
-            alpha = 255
-        }
-
-        self.init(alpha: alpha, red: (netHex >> 16) & 0xFF, green: (netHex >> 8) & 0xFF, blue: netHex & 0xFF)
-    }
-
-    // see: https://stackoverflow.com/a/33397427
-    convenience init(hexString: String) {
-        let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
-        var int = UInt32()
-        Scanner(string: hex).scanHexInt32(&int)
-        let a, r, g, b: UInt32
-        switch hex.count {
-        case 3: // RGB (12-bit)
-            (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
-        case 6: // RGB (24-bit)
-            (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
-        case 8: // ARGB (32-bit)
-            (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
-        default:
-            (a, r, g, b) = (255, 0, 0, 0)
-        }
-        self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
-    }
-
-
-    static func themeColor(light: UIColor, dark: UIColor? = nil) -> UIColor {
-        if let dark = dark {
-            if #available(iOS 13, *) {
-                return UIColor.init { (trait) -> UIColor in
-                    return trait.userInterfaceStyle == .dark ? dark : light
-                }
-            }
-        }
-        return light
-    }
-
-    static func themeColor(lightHex: String, darkHex: String? = nil) -> UIColor {
-        if let darkHex = darkHex {
-            if #available(iOS 13, *) {
-                return UIColor.init { (trait) -> UIColor in
-                    return trait.userInterfaceStyle == .dark ? UIColor(hexString: darkHex) :  UIColor(hexString: lightHex)
-                }
-            }
-        }
-        return UIColor(hexString: lightHex)
-    }
+    
 }

+ 1 - 0
deltachat-ios/Handler/DeviceContactsHandler.swift

@@ -1,5 +1,6 @@
 import Contacts
 import UIKit
+import DcCore
 
 class DeviceContactsHandler {
     private let store = CNContactStore()

+ 1 - 0
deltachat-ios/Handler/ProgressAlertHandler.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 protocol ProgressAlertHandler: UIViewController {
     var progressAlert: UIAlertController { get }

+ 1 - 0
deltachat-ios/Helper/AvatarHelper.swift

@@ -1,5 +1,6 @@
 import Foundation
 import UIKit
+import DcCore
 
 class AvatarHelper {
     static let tmpFile = "tempAvatar.jpg"

+ 1 - 0
deltachat-ios/Helper/LocationManager.swift

@@ -1,5 +1,6 @@
 import Foundation
 import CoreLocation
+import DcCore
 
 class LocationManager: NSObject, CLLocationManagerDelegate {
 

+ 1 - 0
deltachat-ios/Helper/RelayHelper.swift

@@ -1,4 +1,5 @@
 import Foundation
+import DcCore
 
 class RelayHelper {
     static var sharedInstance: RelayHelper = RelayHelper()

+ 1 - 125
deltachat-ios/Helper/Utils.swift

@@ -1,6 +1,7 @@
 import Foundation
 import UIKit
 import AVFoundation
+import DcCore
 
 struct Utils {
 
@@ -12,54 +13,6 @@ struct Utils {
         }
     }
 
-    static func copyAndFreeArray(inputArray: OpaquePointer?) -> [Int] {
-        var acc: [Int] = []
-        let len = dc_array_get_cnt(inputArray)
-        for i in 0 ..< len {
-            let e = dc_array_get_id(inputArray, i)
-            acc.append(Int(e))
-        }
-        dc_array_unref(inputArray)
-
-        return acc
-    }
-
-    static func copyAndFreeArrayWithLen(inputArray: OpaquePointer?, len: Int = 0) -> [Int] {
-        var acc: [Int] = []
-        let arrayLen = dc_array_get_cnt(inputArray)
-        let start = max(0, arrayLen - len)
-        for i in start ..< arrayLen {
-            let e = dc_array_get_id(inputArray, i)
-            acc.append(Int(e))
-        }
-        dc_array_unref(inputArray)
-
-        return acc
-    }
-
-    static func copyAndFreeArrayWithOffset(inputArray: OpaquePointer?, len: Int = 0, from: Int = 0, skipEnd: Int = 0) -> [Int] {
-        let lenArray = dc_array_get_cnt(inputArray)
-        if lenArray <= skipEnd || lenArray == 0 {
-            dc_array_unref(inputArray)
-            return []
-        }
-
-        let start = lenArray - 1 - skipEnd
-        let end = max(0, start - len)
-        let finalLen = start - end + (len > 0 ? 0 : 1)
-        var acc: [Int] = [Int](repeating: 0, count: finalLen)
-
-        for i in stride(from: start, to: end, by: -1) {
-            let index = finalLen - (start - i) - 1
-            acc[index] = Int(dc_array_get_id(inputArray, i))
-        }
-
-        dc_array_unref(inputArray)
-        logger.info("got: \(from) \(len) \(lenArray) - \(acc)")
-
-        return acc
-    }
-
     static func isValid(email: String) -> Bool {
         let emailRegEx = "(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
             + "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
@@ -159,80 +112,3 @@ struct Utils {
         return String(lang)
     }
 }
-
-class DateUtils {
-    typealias DtU = DateUtils
-    static let minute: Double = 60
-    static let hour: Double = 3600
-    static let day: Double = 86400
-    static let year: Double = 365 * day
-
-    static func getRelativeTimeInSeconds(timeStamp: Double) -> Double {
-        let unixTime = Double(Date().timeIntervalSince1970)
-        return unixTime - timeStamp
-    }
-
-    private static func is24hDefault() -> Bool {
-        let dateString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current) ?? ""
-        return !dateString.contains("a")
-    }
-
-    private static func getLocalDateFormatter() -> DateFormatter {
-        let formatter = DateFormatter()
-        formatter.timeZone = .current
-        formatter.locale = .current
-        return formatter
-    }
-
-    static func getExtendedRelativeTimeSpanString(timeStamp: Double) -> String {
-        let seconds = getRelativeTimeInSeconds(timeStamp: timeStamp)
-        let date = Date(timeIntervalSince1970: timeStamp)
-        let formatter = getLocalDateFormatter()
-        let is24h = is24hDefault()
-
-        if seconds < DtU.minute {
-            return String.localized("now")
-        } else if seconds < DtU.hour {
-            let mins = seconds / DtU.minute
-            return String.localized(stringID: "n_minutes", count: Int(mins))
-        } else if seconds < DtU.day {
-            formatter.dateFormat = is24h ?  "HH:mm" : "hh:mm a"
-            return formatter.string(from: date)
-        } else if seconds < 6 * DtU.day {
-            formatter.dateFormat = is24h ?  "EEE, HH:mm" : "EEE, hh:mm a"
-            return formatter.string(from: date)
-        } else if seconds < DtU.year {
-            formatter.dateFormat = is24h ? "MMM d, HH:mm" : "MMM d, hh:mm a"
-            return formatter.string(from: date)
-        } else {
-            formatter.dateFormat = is24h ? "MMM d, yyyy, HH:mm" : "MMM d, yyyy, hh:mm a"
-            return formatter.string(from: date)
-        }
-    }
-
-    static func getBriefRelativeTimeSpanString(timeStamp: Double) -> String {
-        let seconds = getRelativeTimeInSeconds(timeStamp: timeStamp)
-        let date = Date(timeIntervalSince1970: timeStamp)
-        let formatter = getLocalDateFormatter()
-
-        if seconds < DtU.minute {
-            return String.localized("now")	// under one minute
-        } else if seconds < DtU.hour {
-            let mins = seconds / DtU.minute
-            return String.localized(stringID: "n_minutes", count: Int(mins))
-        } else if seconds < DtU.day {
-            let hours = seconds / DtU.hour
-            return String.localized(stringID: "n_hours", count: Int(hours))
-        } else if seconds < DtU.day * 6 {
-            formatter.dateFormat = "EEE"
-            return formatter.string(from: date)
-        } else if seconds < DtU.year {
-            formatter.dateFormat = "MMM d"
-            return formatter.string(from: date)
-        } else {
-            formatter.dateFormat = "MMM d, yyyy"
-            let localDate = formatter.string(from: date)
-            return localDate
-        }
-    }
-}

+ 1 - 0
deltachat-ios/View/AvatarSelectionCell.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class AvatarSelectionCell: UITableViewCell {
     let badgeSize: CGFloat = 72

+ 1 - 0
deltachat-ios/View/Cell/ProfileCell.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 class ProfileCell: UITableViewCell {
 

+ 1 - 0
deltachat-ios/View/ContactCell.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 protocol ContactCellDelegate: class {
     func onAvatarTapped(at index: Int)

+ 1 - 0
deltachat-ios/ViewModel/ChatListViewModel.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 // MARK: - ChatListViewModelProtocol
 protocol ChatListViewModelProtocol: class, UISearchResultsUpdating {

+ 1 - 0
deltachat-ios/ViewModel/ContactCellViewModel.swift

@@ -1,4 +1,5 @@
 import Foundation
+import DcCore
 
 protocol AvatarCellViewModel {
     var type: CellModel { get }

+ 1 - 0
deltachat-ios/ViewModel/ContactDetailViewModel.swift

@@ -1,4 +1,5 @@
 import UIKit
+import DcCore
 
 protocol ContactDetailViewModelProtocol {
     var context: DcContext { get }

+ 0 - 7
deltachat-ios/deltachat-ios-Bridging-Header.h

@@ -1,7 +0,0 @@
-//
-//  Use this file to import your target's public headers that you would like to expose to Swift.
-//
-
-#include "deltachat.h"
-#include "wrapper.h"
-