Resolve more errors

This commit is contained in:
Niels Andriesse 2021-07-30 10:01:05 +10:00
parent b7c6dba0f3
commit 53a8c9fd57
10 changed files with 205 additions and 37 deletions

View File

@ -169,6 +169,9 @@
B822F9BD26B26CA2003B8CB8 /* TSCall.m in Sources */ = {isa = PBXBuildFile; fileRef = B822F9BC26B26CA2003B8CB8 /* TSCall.m */; };
B822F9BE26B26CA8003B8CB8 /* TSCall.h in Headers */ = {isa = PBXBuildFile; fileRef = B822F9BB26B26C82003B8CB8 /* TSCall.h */; settings = {ATTRIBUTES = (Public, ); }; };
B822F9C526B27C9B003B8CB8 /* Dependencies+MainApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B822F9C426B27C9B003B8CB8 /* Dependencies+MainApp.swift */; };
B822F9C826B376EF003B8CB8 /* DarwinNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = B822F9C726B376EF003B8CB8 /* DarwinNotificationCenter.m */; };
B822F9C926B376F6003B8CB8 /* DarwinNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = B822F9C626B376D2003B8CB8 /* DarwinNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; };
B822F9CB26B37798003B8CB8 /* DarwinNotificationName.swift in Sources */ = {isa = PBXBuildFile; fileRef = B822F9CA26B37798003B8CB8 /* DarwinNotificationName.swift */; };
B8269D2925C7A4B400488AB4 /* InputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8269D2825C7A4B400488AB4 /* InputView.swift */; };
B8269D3325C7A8C600488AB4 /* InputViewButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8269D3225C7A8C600488AB4 /* InputViewButton.swift */; };
B8269D3D25C7B34D00488AB4 /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8269D3C25C7B34D00488AB4 /* InputTextView.swift */; };
@ -1170,6 +1173,9 @@
B822F9BC26B26CA2003B8CB8 /* TSCall.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TSCall.m; sourceTree = "<group>"; };
B822F9C326B275FA003B8CB8 /* INSTRUCTIONS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = INSTRUCTIONS.md; sourceTree = "<group>"; };
B822F9C426B27C9B003B8CB8 /* Dependencies+MainApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dependencies+MainApp.swift"; sourceTree = "<group>"; };
B822F9C626B376D2003B8CB8 /* DarwinNotificationCenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinNotificationCenter.h; sourceTree = "<group>"; };
B822F9C726B376EF003B8CB8 /* DarwinNotificationCenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DarwinNotificationCenter.m; sourceTree = "<group>"; };
B822F9CA26B37798003B8CB8 /* DarwinNotificationName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DarwinNotificationName.swift; sourceTree = "<group>"; };
B8269D2825C7A4B400488AB4 /* InputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputView.swift; sourceTree = "<group>"; };
B8269D3225C7A8C600488AB4 /* InputViewButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputViewButton.swift; sourceTree = "<group>"; };
B8269D3C25C7B34D00488AB4 /* InputTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
@ -2334,6 +2340,9 @@
B882A79826AE897E00B5AB69 /* Atomics.swift */,
C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */,
B8F5F58225EC94A6003BF8D4 /* Collection+Subscripting.swift */,
B822F9C626B376D2003B8CB8 /* DarwinNotificationCenter.h */,
B822F9C726B376EF003B8CB8 /* DarwinNotificationCenter.m */,
B822F9CA26B37798003B8CB8 /* DarwinNotificationName.swift */,
B8AE75A325A6C6A6001A84D2 /* Data+Trimming.swift */,
C3C2A5D52553860A00C340D1 /* Dictionary+Description.swift */,
B87EF18026377A1D00124B3C /* Features.swift */,
@ -3699,6 +3708,7 @@
buildActionMask = 2147483647;
files = (
C32C5FAA256DFED9003C73A2 /* NSArray+Functional.h in Headers */,
B822F9C926B376F6003B8CB8 /* DarwinNotificationCenter.h in Headers */,
C3D9E3FA25676BCE0040E4F3 /* TSYapDatabaseObject.h in Headers */,
C3D9E3A4256763DE0040E4F3 /* AppContext.h in Headers */,
C3D9E38A256760390040E4F3 /* OWSFileSystem.h in Headers */,
@ -4662,6 +4672,7 @@
C3BBE0A82554D4DE0050F1E3 /* JSON.swift in Sources */,
C352A36D2557858E00338F3E /* NSTimer+Proxying.m in Sources */,
C32C5A2D256DB849003C73A2 /* LKGroupUtilities.m in Sources */,
B822F9CB26B37798003B8CB8 /* DarwinNotificationName.swift in Sources */,
C3C2ABD22553C6C900C340D1 /* Data+SecureRandom.swift in Sources */,
B8856E09256F1676001CE70E /* UIDevice+featureSupport.swift in Sources */,
B8856DEF256F161F001CE70E /* NSString+SSK.m in Sources */,
@ -4679,6 +4690,7 @@
C32C600F256E07F5003C73A2 /* NSUserDefaults+OWS.m in Sources */,
C3D9E35E25675F640040E4F3 /* OWSFileSystem.m in Sources */,
C3C2AC2E2553CBEB00C340D1 /* String+Trimming.swift in Sources */,
B822F9C826B376EF003B8CB8 /* DarwinNotificationCenter.m in Sources */,
C32C5B48256DC211003C73A2 /* NSNotificationCenter+OWS.m in Sources */,
C3D9E3C925676AF30040E4F3 /* TSYapDatabaseObject.m in Sources */,
C352A3A62557B60D00338F3E /* TSRequest.m in Sources */,

View File

@ -827,7 +827,7 @@ extension CallService {
owsFailDebug("Unknown thread")
return
}
Self.notificationPresenter.notifyUser(for: message, thread: thread, wantsSound: true, transaction: transaction)
AppEnvironment.shared.notificationPresenter.notifyUser(for: message, thread: thread, wantsSound: true, transaction: transaction)
}
}
@ -891,7 +891,7 @@ extension CallService: CallManagerDelegate {
transaction: transaction
)
}.then { thread throws -> Promise<Void> in
let opaqueBuilder = SSKProtoCallMessageOpaque.builder()
let opaqueBuilder = SNProtoCallMessageOpaque.builder()
opaqueBuilder.setData(message)
let callMessage = OWSOutgoingCallMessage(
@ -955,7 +955,7 @@ extension CallService: CallManagerDelegate {
return request
}
firstly(on: .sharedUtility) {
session.dataTaskPromise(url, method: httpMethod, headers: headers, body: body)
}.done(on: .main) { response in

View File

@ -39,7 +39,7 @@ class GroupCallUpdateMessageHandler: CallServiceObserver, CallObserver, Dependen
}
}
func handleUpdateMessage(_ message: SSKProtoDataMessageGroupCallUpdate, for thread: TSGroupThread, serverReceivedTimestamp: UInt64) {
func handleUpdateMessage(_ message: SNProtoDataMessageGroupCallUpdate, for thread: TSGroupThread, serverReceivedTimestamp: UInt64) {
Logger.info("Received group call update message for thread: \(thread.uniqueId) eraId: \(String(describing: message.eraID))")
DispatchQueue.main.async {
Self.callService.peekCallAndUpdateThread(

View File

@ -393,7 +393,7 @@ import WebRTC
/**
* Remote client (could be caller or callee) sent us a connectivity update.
*/
public func handleReceivedIceCandidates(thread: TSContactThread, callId: UInt64, sourceDevice: UInt32, candidates: [SSKProtoCallMessageIceUpdate]) {
public func handleReceivedIceCandidates(thread: TSContactThread, callId: UInt64, sourceDevice: UInt32, candidates: [SNProtoCallMessageIceUpdate]) {
AssertIsOnMainThread()
let iceCandidates = candidates.filter { $0.id == callId && $0.opaque != nil }.map { $0.opaque! }
@ -415,7 +415,7 @@ import WebRTC
/**
* The remote client (caller or callee) ended the call.
*/
public func handleReceivedHangup(thread: TSContactThread, callId: UInt64, sourceDevice: UInt32, type: SSKProtoCallMessageHangupType, deviceId: UInt32) {
public func handleReceivedHangup(thread: TSContactThread, callId: UInt64, sourceDevice: UInt32, type: SNProtoCallMessageHangupType, deviceId: UInt32) {
AssertIsOnMainThread()
let hangupType: HangupType

View File

@ -19,7 +19,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
// MARK: - Call Handlers
public func receivedOffer(
_ offer: SSKProtoCallMessageOffer,
_ offer: SNProtoCallMessageOffer,
from caller: SignalServiceAddress,
sourceDevice: UInt32,
sentAtTimestamp: UInt64,
@ -29,7 +29,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
) {
AssertIsOnMainThread()
let callType: SSKProtoCallMessageOfferType
let callType: SNProtoCallMessageOfferType
if offer.hasType {
callType = offer.unwrappedType
} else {
@ -52,7 +52,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
)
}
public func receivedAnswer(_ answer: SSKProtoCallMessageAnswer, from caller: SignalServiceAddress, sourceDevice: UInt32, supportsMultiRing: Bool) {
public func receivedAnswer(_ answer: SNProtoCallMessageAnswer, from caller: SignalServiceAddress, sourceDevice: UInt32, supportsMultiRing: Bool) {
AssertIsOnMainThread()
let thread = TSContactThread.getOrCreateThread(contactAddress: caller)
@ -66,7 +66,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
)
}
public func receivedIceUpdate(_ iceUpdate: [SSKProtoCallMessageIceUpdate], from caller: SignalServiceAddress, sourceDevice: UInt32) {
public func receivedIceUpdate(_ iceUpdate: [SNProtoCallMessageIceUpdate], from caller: SignalServiceAddress, sourceDevice: UInt32) {
AssertIsOnMainThread()
let thread = TSContactThread.getOrCreateThread(contactAddress: caller)
@ -78,13 +78,13 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
)
}
public func receivedHangup(_ hangup: SSKProtoCallMessageHangup, from caller: SignalServiceAddress, sourceDevice: UInt32) {
public func receivedHangup(_ hangup: SNProtoCallMessageHangup, from caller: SignalServiceAddress, sourceDevice: UInt32) {
AssertIsOnMainThread()
// deviceId is optional and defaults to 0.
var deviceId: UInt32 = 0
let type: SSKProtoCallMessageHangupType
let type: SNProtoCallMessageHangupType
if hangup.hasType {
type = hangup.unwrappedType
@ -106,7 +106,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
)
}
public func receivedBusy(_ busy: SSKProtoCallMessageBusy, from caller: SignalServiceAddress, sourceDevice: UInt32) {
public func receivedBusy(_ busy: SNProtoCallMessageBusy, from caller: SignalServiceAddress, sourceDevice: UInt32) {
AssertIsOnMainThread()
let thread = TSContactThread.getOrCreateThread(contactAddress: caller)
@ -118,7 +118,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
}
public func receivedOpaque(
_ opaque: SSKProtoCallMessageOpaque,
_ opaque: SNProtoCallMessageOpaque,
from caller: SignalServiceAddress,
sourceDevice: UInt32,
serverReceivedTimestamp: UInt64,
@ -150,7 +150,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
}
public func receivedGroupCallUpdateMessage(
_ update: SSKProtoDataMessageGroupCallUpdate,
_ update: SNProtoDataMessageGroupCallUpdate,
for groupThread: TSGroupThread,
serverReceivedTimestamp: UInt64) {
@ -158,7 +158,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
callService.groupCallMessageHandler.handleUpdateMessage(update, for: groupThread, serverReceivedTimestamp: serverReceivedTimestamp)
}
public func externallyHandleCallMessage(envelope: SSKProtoEnvelope, plaintextData: Data, wasReceivedByUD: Bool, serverDeliveryTimestamp: UInt64, transaction: SDSAnyWriteTransaction) -> Bool {
public func externallyHandleCallMessage(envelope: SNProtoEnvelope, plaintextData: Data, wasReceivedByUD: Bool, serverDeliveryTimestamp: UInt64, transaction: SDSAnyWriteTransaction) -> Bool {
return false
}
}

View File

@ -68,7 +68,6 @@ extension AppNotificationCategory {
case .missedCallFromNoLongerVerifiedIdentity:
return "Signal.AppNotificationCategory.missedCallFromNoLongerVerifiedIdentity"
}
}
}
var actions: [AppNotificationAction] {
@ -186,8 +185,8 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
}
public func presentIncomingCall(_ call: IndividualCallNotificationInfo, callerName: String) {
let remoteAddress = call.remoteAddress
let thread = TSContactThread.getOrCreateThread(contactAddress: remoteAddress)
let publicKey = call.publicKey
let thread = TSContactThread.getOrCreateThread(contactSessionID: publicKey)
let notificationTitle: String?
let threadIdentifier: String?
@ -201,9 +200,10 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
}
let notificationBody: String
// TODO: Distinguish between incoming audio calls and incoming video calls in the copy here
switch call.offerMediaType {
case .audio: notificationBody = NotificationStrings.incomingAudioCallBody
case .video: notificationBody = NotificationStrings.incomingVideoCallBody
case .audio: notificationBody = NotificationStrings.incomingCallBody
case .video: notificationBody = NotificationStrings.incomingCallBody
}
let userInfo = [
@ -215,7 +215,6 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
self.adaptee.notify(category: .incomingCall,
title: notificationTitle,
body: notificationBody,
threadIdentifier: threadIdentifier,
userInfo: userInfo,
sound: nil,
replacingIdentifier: call.localId.uuidString)
@ -223,9 +222,8 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
}
public func presentMissedCall(_ call: IndividualCallNotificationInfo, callerName: String) {
let remoteAddress = call.remoteAddress
let thread = TSContactThread.getOrCreateThread(contactAddress: remoteAddress)
let publicKey = call.publicKey
let thread = TSContactThread.getOrCreateThread(contactSessionID: publicKey)
let notificationTitle: String?
let threadIdentifier: String?
@ -239,12 +237,13 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
}
let notificationBody: String
// TODO: Distinguish between incoming audio calls and incoming video calls in the copy here
switch call.offerMediaType {
case .audio: notificationBody = NotificationStrings.missedAudioCallBody
case .video: notificationBody = NotificationStrings.missedVideoCallBody
case .audio: notificationBody = NotificationStrings.missedCallBody
case .video: notificationBody = NotificationStrings.missedCallBody
}
let userInfo = userInfoForMissedCall(thread: thread, remoteAddress: remoteAddress)
let userInfo = userInfoForMissedCall(thread: thread, publicKey: publicKey)
let category: AppNotificationCategory = (shouldShowActions
? .missedCallWithActions
@ -254,7 +253,6 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
self.adaptee.notify(category: category,
title: notificationTitle,
body: notificationBody,
threadIdentifier: threadIdentifier,
userInfo: userInfo,
sound: sound,
replacingIdentifier: call.localId.uuidString)
@ -286,7 +284,6 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
self.adaptee.notify(category: .missedCallFromNoLongerVerifiedIdentity,
title: notificationTitle,
body: notificationBody,
threadIdentifier: threadIdentifier,
userInfo: userInfo,
sound: sound,
replacingIdentifier: call.localId.uuidString)
@ -295,8 +292,8 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
public func presentMissedCallBecauseOfNewIdentity(call: IndividualCallNotificationInfo, callerName: String) {
let remoteAddress = call.remoteAddress
let thread = TSContactThread.getOrCreateThread(contactAddress: remoteAddress)
let publicKey = call.publicKey
let thread = TSContactThread.getOrCreateThread(contactSessionID: publicKey)
let notificationTitle: String?
let threadIdentifier: String?
@ -309,7 +306,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
threadIdentifier = thread.uniqueId
}
let notificationBody = NotificationStrings.missedCallBecauseOfIdentityChangeBody
let userInfo = userInfoForMissedCall(thread: thread, remoteAddress: remoteAddress)
let userInfo = userInfoForMissedCall(thread: thread, publicKey: publicKey)
let category: AppNotificationCategory = (shouldShowActions
? .missedCallWithActions
@ -319,16 +316,15 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
self.adaptee.notify(category: category,
title: notificationTitle,
body: notificationBody,
threadIdentifier: threadIdentifier,
userInfo: userInfo,
sound: sound,
replacingIdentifier: call.localId.uuidString)
}
}
private func userInfoForMissedCall(thread: TSThread, remoteAddress: SignalServiceAddress) -> [String: Any] {
private func userInfoForMissedCall(thread: TSThread, publicKey: String) -> [String: Any] {
var userInfo: [String: Any] = [
AppNotificationUserInfoKey.threadId: thread.uniqueId
AppNotificationUserInfoKey.threadId: thread.uniqueId!
]
if let uuid = remoteAddress.uuid {
userInfo[AppNotificationUserInfoKey.callBackUuid] = uuid.uuidString
@ -630,7 +626,7 @@ extension TruncatedList: Collection {
}
public protocol IndividualCallNotificationInfo {
var remoteAddress: SignalServiceAddress { get }
var publicKey: String { get }
var localId: UUID { get }
var offerMediaType: TSRecentCallOfferType { get }
}

View File

@ -0,0 +1,53 @@
//
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class DarwinNotificationName;
extern const int DarwinNotificationInvalidObserver;
@interface DarwinNotificationCenter : NSObject
/// Determines if an observer token is valid for a current registration.
/// Negative integers are never valid. A positive or zero value is valid
/// if the current process has a registration associated with the given value.
/// @param observerToken The token returned by `addObserverForName:`
+ (BOOL)isValidObserver:(int)observerToken;
/// Post a darwin notification that can be listened for from other processes.
/// @param name The name of the notification to post.
+ (void)postNotificationName:(DarwinNotificationName *)name;
/// Add an observer for a darwin notification of the given name.
/// @param name The name of the notification to listen for.
/// @param queue The queue to callback on.
/// @param block The block to callback. Includes the observer token as an input parameter to allow
/// removing the observer after receipt.
/// @return An `int` observer token that can be used to remove this observer.
+ (int)addObserverForName:(DarwinNotificationName *)name queue:(dispatch_queue_t)queue usingBlock:(void (^)(int))block;
/// Stops listening for notifications registered by the given observer token.
/// @param observerToken The token returned by `addObserverForName:` for the notification you want to stop listening
/// for.
+ (void)removeObserver:(int)observerToken;
/// Sets the state value for a given observer. This value can be set and read from
/// any process listening for this notification. Note: `setState:` and `getState`
/// are vulnerable to races.
/// @param state The `uint64_t` state you wish to share with another process.
/// @param observerToken The token returned by `addObserverForName:` for the notification you want to set state for.
+ (void)setState:(uint64_t)state forObserver:(int)observerToken;
/// Retrieves the state for a given observer. This value can be set and read from
/// any process listening for this notification. Note: `setState:` and `getState`
/// are vulnerable to races.
/// @param observerToken The token returned by `addObserverForName:` for the notification you want to get state for.
+ (uint64_t)getStateForObserver:(int)observerToken;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,61 @@
//
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
#import <SessionUtilitiesKit/DarwinNotificationCenter.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit-Swift.h>
#import <notify.h>
const int DarwinNotificationInvalidObserver = NOTIFY_TOKEN_INVALID;
@implementation DarwinNotificationCenter
+ (BOOL)isValidObserver:(int)observerToken
{
return notify_is_valid_token(observerToken);
}
+ (void)postNotificationName:(DarwinNotificationName *)name
{
notify_post((const char *)name.cString);
}
+ (int)addObserverForName:(DarwinNotificationName *)name
queue:(dispatch_queue_t)queue
usingBlock:(notify_handler_t)block
{
int observerToken;
notify_register_dispatch((const char *)name.cString, &observerToken, queue, block);
return observerToken;
}
+ (void)removeObserver:(int)observerToken
{
if (![self isValidObserver:observerToken]) {
return;
}
notify_cancel(observerToken);
}
+ (void)setState:(uint64_t)state forObserver:(int)observerToken
{
if (![self isValidObserver:observerToken]) {
return;
}
notify_set_state(observerToken, state);
}
+ (uint64_t)getStateForObserver:(int)observerToken
{
if (![self isValidObserver:observerToken]) {
return 0;
}
uint64_t state;
notify_get_state(observerToken, &state);
return state;
}
@end

View File

@ -0,0 +1,45 @@
//
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
import Foundation
@objc
public class DarwinNotificationName: NSObject, ExpressibleByStringLiteral {
@objc public static let sdsCrossProcess: DarwinNotificationName = "org.signal.sdscrossprocess"
@objc public static let nseDidReceiveNotification: DarwinNotificationName = "org.signal.nseDidReceiveNotification"
@objc public static let mainAppHandledNotification: DarwinNotificationName = "org.signal.mainAppHandledNotification"
@objc public static let mainAppLaunched: DarwinNotificationName = "org.signal.mainAppLaunched"
public typealias StringLiteralType = String
private let stringValue: String
@objc
public var cString: UnsafePointer<Int8> {
return stringValue.withCString { $0 }
}
@objc
public var isValid: Bool {
return stringValue.isEmpty == false
}
public required init(stringLiteral value: String) {
stringValue = value
}
@objc
public init(_ name: String) {
stringValue = name
}
public override func isEqual(_ object: Any?) -> Bool {
guard let otherName = object as? DarwinNotificationName else { return false }
return otherName.stringValue == stringValue
}
public override var hash: Int {
return stringValue.hashValue
}
}

View File

@ -4,6 +4,7 @@ FOUNDATION_EXPORT double SessionUtilitiesKitVersionNumber;
FOUNDATION_EXPORT const unsigned char SessionUtilitiesKitVersionString[];
#import <SessionUtilitiesKit/AppContext.h>
#import <SessionUtilitiesKit/DarwinNotificationCenter.h>
#import <SessionUtilitiesKit/DataSource.h>
#import <SessionUtilitiesKit/LKGroupUtilities.h>
#import <SessionUtilitiesKit/MIMETypeUtil.h>