From b367ea7ab82b13837f6129bd3ea1c43fe1aeee5d Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 4 Sep 2019 14:41:38 +1000 Subject: [PATCH 1/4] Set up Mixpanel --- Podfile | 7 ++++--- Podfile.lock | 8 ++++++-- Signal.xcodeproj/project.pbxproj | 6 ++++++ Signal/src/AppDelegate.m | 4 ++++ Signal/src/Loki/Analytics.swift | 9 +++++++++ .../src/Loki/Utilities/BuildConfiguration.swift | 9 ++++++++- 6 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 Signal/src/Loki/Analytics.swift diff --git a/Podfile b/Podfile index bf1a97832..52f327a56 100644 --- a/Podfile +++ b/Podfile @@ -62,7 +62,6 @@ def shared_pods pod 'PureLayout', :inhibit_warnings => true pod 'Reachability', :inhibit_warnings => true pod 'YYImage', :inhibit_warnings => true - pod 'CryptoSwift', :inhibit_warnings => true pod 'IGIdenticon', :inhibit_warnings => true end @@ -72,8 +71,10 @@ target 'Signal' do pod 'SSZipArchive', :inhibit_warnings => true # Loki - pod 'GCDWebServer', '~> 3.0' - pod 'FeedKit', '~> 8.1' + pod 'GCDWebServer', '~> 3.0', :inhibit_warnings => true + pod 'FeedKit', '~> 8.1', :inhibit_warnings => true + pod 'CryptoSwift', '~> 1.0', :inhibit_warnings => true + pod 'Mixpanel', '~> 3.4', :inhibit_warnings => true target 'SignalTests' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock index 5b624389a..aecbc3596 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -52,6 +52,7 @@ PODS: - Mantle (2.1.0): - Mantle/extobjc (= 2.1.0) - Mantle/extobjc (2.1.0) + - Mixpanel (3.4.7) - PromiseKit (6.5.3): - PromiseKit/CorePromise (= 6.5.3) - PromiseKit/Foundation (= 6.5.3) @@ -196,7 +197,7 @@ DEPENDENCIES: - AFNetworking - AxolotlKit (from `https://github.com/signalapp/SignalProtocolKit.git`, branch `master`) - AxolotlKit/Tests (from `https://github.com/signalapp/SignalProtocolKit.git`, branch `master`) - - CryptoSwift + - CryptoSwift (~> 1.0) - Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit`) - Curve25519Kit/Tests (from `https://github.com/signalapp/Curve25519Kit`) - FeedKit (~> 8.1) @@ -206,6 +207,7 @@ DEPENDENCIES: - HKDFKit/Tests (from `https://github.com/signalapp/HKDFKit.git`) - IGIdenticon - Mantle (from `https://github.com/signalapp/Mantle`, branch `signal-master`) + - Mixpanel (~> 3.4) - PromiseKit (= 6.5.3) - PureLayout - Reachability @@ -230,6 +232,7 @@ SPEC REPOS: - GCDWebServer - IGIdenticon - libPhoneNumber-iOS + - Mixpanel - PromiseKit - PureLayout - Reachability @@ -307,6 +310,7 @@ SPEC CHECKSUMS: IGIdenticon: 5790befde4fe56296927c72c0efed3d07b21de8e libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b + Mixpanel: 696e0a1c7f2685aa06bb23829b7a58ab7203d6c7 PromiseKit: c609029bdd801f792551a504c695c7d3098b42cd PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 @@ -321,6 +325,6 @@ SPEC CHECKSUMS: YapDatabase: b418a4baa6906e8028748938f9159807fd039af4 YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 -PODFILE CHECKSUM: 95f41137d4fe8c5b8a27de951b328f8c9531d166 +PODFILE CHECKSUM: 0666e8fade5ac5ba48d0b3c9cb83b2095d1b3cef COCOAPODS: 1.5.3 diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index f10fe677d..9a9b0316a 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -565,6 +565,7 @@ B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; }; B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; }; B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; }; + B8911057231F774C00F15FCC /* Analytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8911056231F774C00F15FCC /* Analytics.swift */; }; B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; }; B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; }; @@ -1359,6 +1360,7 @@ B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = ""; }; B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = ""; }; B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = ""; }; + B8911056231F774C00F15FCC /* Analytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Analytics.swift; sourceTree = ""; }; B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = ""; }; B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; @@ -2616,6 +2618,7 @@ isa = PBXGroup; children = ( B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */, + B8911056231F774C00F15FCC /* Analytics.swift */, B8162F0222891AD600D46544 /* FriendRequestView.swift */, B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */, B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */, @@ -3291,6 +3294,7 @@ "${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework", "${BUILT_PRODUCTS_DIR}/IGIdenticon/IGIdenticon.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", + "${BUILT_PRODUCTS_DIR}/Mixpanel/Mixpanel.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/PureLayout/PureLayout.framework", "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework", @@ -3319,6 +3323,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGIdenticon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mixpanel.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PureLayout.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", @@ -3674,6 +3679,7 @@ 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */, 34A8B3512190A40E00218A25 /* MediaAlbumCellView.swift in Sources */, 34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */, + B8911057231F774C00F15FCC /* Analytics.swift in Sources */, 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, 3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 1d0c684cb..3eadb2f82 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -46,6 +46,7 @@ #import #import #import +#import @import WebRTC; @import Intents; @@ -348,6 +349,9 @@ static NSTimeInterval launchStartedAt; // NSLog(@"[Loki] Failed to start P2P server."); // } + // Loki - Set up beta analytics + [Mixpanel sharedInstanceWithToken:@"0410357303b7b6b45b740e6f0e6d34be"]; + return YES; } diff --git a/Signal/src/Loki/Analytics.swift b/Signal/src/Loki/Analytics.swift new file mode 100644 index 000000000..faeecc6c0 --- /dev/null +++ b/Signal/src/Loki/Analytics.swift @@ -0,0 +1,9 @@ +import Mixpanel + +@objc(LKAnalytics) +final class Analytics : NSObject { + + @objc static func track(_ event: String) { + Mixpanel.sharedInstance()?.track(event, properties: [ "configuration" : BuildConfiguration.current.description ]) + } +} diff --git a/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift b/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift index 8dc686d40..eb5c4aaf8 100644 --- a/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift +++ b/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift @@ -1,5 +1,5 @@ -public enum BuildConfiguration { +public enum BuildConfiguration : CustomStringConvertible { case debug, production public static let current: BuildConfiguration = { @@ -9,4 +9,11 @@ public enum BuildConfiguration { return .production #endif }() + + public var description: String { + switch self { + case .debug: return "debug" + case .production: return "production" + } + } } From bf7dd703277fbc6e459bcae5bb47598de87f67b2 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 4 Sep 2019 15:55:17 +1000 Subject: [PATCH 2/4] Add basic events --- Signal.xcodeproj/project.pbxproj | 4 ---- Signal/src/AppDelegate.m | 4 ++++ Signal/src/Loki/Analytics.swift | 9 --------- Signal/src/Loki/NewConversationViewController.swift | 2 ++ Signal/src/Loki/SeedViewController.swift | 5 +++++ .../ConversationView/ConversationViewController.m | 10 ++++++++++ SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift | 5 +++++ SignalServiceKit/src/Loki/API/LokiAPI.swift | 4 ++-- SignalServiceKit/src/Loki/API/LokiGroupChatAPI.swift | 8 +++++++- SignalServiceKit/src/Loki/Utilities/Analytics.swift | 11 +++++++++++ .../src/Loki/Utilities/BuildConfiguration.swift | 7 +++++++ SignalServiceKit/src/Messages/OWSMessageSender.m | 2 ++ 12 files changed, 55 insertions(+), 16 deletions(-) delete mode 100644 Signal/src/Loki/Analytics.swift create mode 100644 SignalServiceKit/src/Loki/Utilities/Analytics.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 9a9b0316a..082b40de1 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -565,7 +565,6 @@ B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; }; B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; }; B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; }; - B8911057231F774C00F15FCC /* Analytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8911056231F774C00F15FCC /* Analytics.swift */; }; B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; }; B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; }; @@ -1360,7 +1359,6 @@ B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = ""; }; B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = ""; }; B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = ""; }; - B8911056231F774C00F15FCC /* Analytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Analytics.swift; sourceTree = ""; }; B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = ""; }; B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; @@ -2618,7 +2616,6 @@ isa = PBXGroup; children = ( B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */, - B8911056231F774C00F15FCC /* Analytics.swift */, B8162F0222891AD600D46544 /* FriendRequestView.swift */, B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */, B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */, @@ -3679,7 +3676,6 @@ 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */, 34A8B3512190A40E00218A25 /* MediaAlbumCellView.swift in Sources */, 34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */, - B8911057231F774C00F15FCC /* Analytics.swift in Sources */, 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, 3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 3eadb2f82..a9a57e969 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -351,6 +351,10 @@ static NSTimeInterval launchStartedAt; // Loki - Set up beta analytics [Mixpanel sharedInstanceWithToken:@"0410357303b7b6b45b740e6f0e6d34be"]; + LKAnalytics.shared.trackImplementation = ^(NSString *event) { + NSDictionary *properties = @{ @"configuration" : LKBuildConfiguration.current }; + [Mixpanel.sharedInstance track:event properties:properties]; + }; return YES; } diff --git a/Signal/src/Loki/Analytics.swift b/Signal/src/Loki/Analytics.swift deleted file mode 100644 index faeecc6c0..000000000 --- a/Signal/src/Loki/Analytics.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Mixpanel - -@objc(LKAnalytics) -final class Analytics : NSObject { - - @objc static func track(_ event: String) { - Mixpanel.sharedInstance()?.track(event, properties: [ "configuration" : BuildConfiguration.current.description ]) - } -} diff --git a/Signal/src/Loki/NewConversationViewController.swift b/Signal/src/Loki/NewConversationViewController.swift index f47c05e5c..be5a0dd32 100644 --- a/Signal/src/Loki/NewConversationViewController.swift +++ b/Signal/src/Loki/NewConversationViewController.swift @@ -91,6 +91,7 @@ final class NewConversationViewController : OWSViewController, OWSQRScannerDeleg } func controller(_ controller: OWSQRCodeScanningViewController, didDetectQRCodeWith string: String) { + Analytics.shared.track("QR Code Scanned") let hexEncodedPublicKey = string startNewConversationIfPossible(with: hexEncodedPublicKey) } @@ -111,6 +112,7 @@ final class NewConversationViewController : OWSViewController, OWSQRScannerDeleg presentAlert(alert) } else { let thread = TSContactThread.getOrCreateThread(contactId: hexEncodedPublicKey) + Analytics.shared.track("New Conversation Started") SignalApp.shared().presentConversation(for: thread, action: .compose, animated: false) presentingViewController!.dismiss(animated: true, completion: nil) } diff --git a/Signal/src/Loki/SeedViewController.swift b/Signal/src/Loki/SeedViewController.swift index 87e1f2143..f03b9ddca 100644 --- a/Signal/src/Loki/SeedViewController.swift +++ b/Signal/src/Loki/SeedViewController.swift @@ -207,6 +207,7 @@ final class SeedViewController : OnboardingBaseViewController { @objc private func registerOrRestore() { var seed: Data + let mode = self.mode switch mode { case .register: seed = self.seed case .restore: @@ -232,6 +233,10 @@ final class SeedViewController : OnboardingBaseViewController { accountManager.phoneNumberAwaitingVerification = hexEncodedPublicKey accountManager.didRegister() let onSuccess = { [weak self] in + switch mode { + case .register: Analytics.shared.track("Seed Created") + case .restore: Analytics.shared.track("Seed Restored") + } guard let strongSelf = self else { return } strongSelf.onboardingController.verificationDidComplete(fromView: strongSelf) UserDefaults.standard.set(true, forKey: "didUpdateForMainnet") diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 622fa3195..cc35a97c1 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -611,6 +611,16 @@ typedef enum : NSUInteger { [self loadDraftInCompose]; [self applyTheme]; [self.conversationViewModel viewDidLoad]; + + if (self.thread.isGroupThread) { + if (self.isRSSFeed) { + [LKAnalytics.shared track:@"RSS Feed Opened"]; + } else { + [LKAnalytics.shared track:@"Loki Public Chat Opened"]; + } + } else { + [LKAnalytics.shared track:@"Conversation Opened"]; + } } - (void)createContents diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index 6e0e99ef8..458c70d92 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -74,6 +74,9 @@ public extension LokiAPI { return LokiAPITarget(address: "https://\(address)", port: UInt16(port)) }) return randomSnodePool.randomElement()! + }.recover { error -> Promise in + Analytics.shared.track("Seed Node Failed") + throw error } } else { return Promise { seal in @@ -126,6 +129,7 @@ internal extension Promise { let newFailureCount = oldFailureCount + 1 LokiAPI.failureCount[target] = newFailureCount print("[Loki] Couldn't reach snode at: \(target); setting failure count to \(newFailureCount).") + Analytics.shared.track("Unreachable Snode") if newFailureCount >= LokiAPI.failureThreshold { print("[Loki] Failure threshold reached for: \(target); dropping it.") LokiAPI.dropIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey) // Remove it from the swarm cache associated with the given public key @@ -135,6 +139,7 @@ internal extension Promise { case 421: // The snode isn't associated with the given public key anymore print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).") + Analytics.shared.track("Migrated Snode") LokiAPI.dropIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey) case 432: // The PoW difficulty is too low diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index c81a39589..f9cc88fa4 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -76,7 +76,7 @@ public final class LokiAPI : NSObject { return lokiMessage.calculatePoW().then { lokiMessageWithPoW in return getTargetSnodes(for: destination).map { swarm in return Set(swarm.map { target in - sendLokiMessage(lokiMessageWithPoW, to: target).map { rawResponse in + sendLokiMessage(lokiMessageWithPoW, to: target).map { rawResponse -> Any in if let json = rawResponse as? JSON, let powDifficulty = json["difficulty"] as? Int { guard powDifficulty != LokiAPI.powDifficulty else { return rawResponse } print("[Loki] Setting proof of work difficulty to \(powDifficulty).") @@ -87,7 +87,7 @@ public final class LokiAPI : NSObject { return rawResponse } }) - }.retryingIfNeeded(maxRetryCount: maxRetryCount) + } } } if let peer = LokiP2PAPI.getInfo(for: destination), (lokiMessage.isPing || peer.isOnline) { diff --git a/SignalServiceKit/src/Loki/API/LokiGroupChatAPI.swift b/SignalServiceKit/src/Loki/API/LokiGroupChatAPI.swift index b1ff3f76a..e272aa506 100644 --- a/SignalServiceKit/src/Loki/API/LokiGroupChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiGroupChatAPI.swift @@ -178,7 +178,13 @@ public final class LokiGroupChatAPI : NSObject { storage.dbReadWriteConnection.removeObject(forKey: server, inCollection: authTokenCollection) } throw error - }.retryingIfNeeded(maxRetryCount: maxRetryCount) + }.retryingIfNeeded(maxRetryCount: maxRetryCount).map { message in + Analytics.shared.track("Group Message Sent") + return message + }.recover { error -> Promise in + Analytics.shared.track("Failed to Send Group Message") + throw error + } } public static func getDeletedMessageServerIDs(for group: UInt64, on server: String) -> Promise<[UInt64]> { diff --git a/SignalServiceKit/src/Loki/Utilities/Analytics.swift b/SignalServiceKit/src/Loki/Utilities/Analytics.swift new file mode 100644 index 000000000..49ddaee8b --- /dev/null +++ b/SignalServiceKit/src/Loki/Utilities/Analytics.swift @@ -0,0 +1,11 @@ + +@objc(LKAnalytics) +public final class Analytics : NSObject { + @objc public var trackImplementation: ((String) -> Void)! // Set in AppDelegate.m + + @objc public static let shared = Analytics() + + @objc public func track(_ event: String) { + trackImplementation(event) + } +} diff --git a/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift b/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift index eb5c4aaf8..00e55b775 100644 --- a/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift +++ b/SignalServiceKit/src/Loki/Utilities/BuildConfiguration.swift @@ -17,3 +17,10 @@ public enum BuildConfiguration : CustomStringConvertible { } } } + +@objc public final class LKBuildConfiguration : NSObject { + + override private init() { } + + @objc public static var current: String { return BuildConfiguration.current.description } +} diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 875e0b743..1adf7b43d 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1171,6 +1171,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [promise .thenOn(OWSDispatch.sendingQueue, ^(id result) { if (isSuccess) { return; } // Succeed as soon as the first promise succeeds + [LKAnalytics.shared track:@"Sent Message Using Swarm API"]; isSuccess = YES; if (signalMessage.type == TSFriendRequestMessageType) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { @@ -1190,6 +1191,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { errorCount += 1; if (errorCount != promiseCount) { return; } // Only error out if all promises failed + [LKAnalytics.shared track:@"Failed to Send Message Using Swarm API"]; handleError(error); }) retainUntilComplete]; } From 55b57182713bff85201c56da11ca8436fc38014b Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 4 Sep 2019 15:59:44 +1000 Subject: [PATCH 3/4] Fix regression --- SignalServiceKit/src/Loki/API/LokiAPI.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index f9cc88fa4..03e9959e1 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -87,7 +87,7 @@ public final class LokiAPI : NSObject { return rawResponse } }) - } + }.retryingIfNeeded(maxRetryCount: maxRetryCount) } } if let peer = LokiP2PAPI.getInfo(for: destination), (lokiMessage.isPing || peer.isOnline) { From 4825ba07d8f673fbfbbb648bad194dae59160cc3 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 4 Sep 2019 16:08:47 +1000 Subject: [PATCH 4/4] Clean --- Pods | 2 +- SignalServiceKit/src/Loki/API/LokiAPI.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Pods b/Pods index 8b30c2d91..eea56e7a7 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 8b30c2d91fe7f9743350dd30521b5ca74e78766c +Subproject commit eea56e7a7f25a5a9e282c742cf1c618765ca5ca8 diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index 03e9959e1..c81a39589 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -76,7 +76,7 @@ public final class LokiAPI : NSObject { return lokiMessage.calculatePoW().then { lokiMessageWithPoW in return getTargetSnodes(for: destination).map { swarm in return Set(swarm.map { target in - sendLokiMessage(lokiMessageWithPoW, to: target).map { rawResponse -> Any in + sendLokiMessage(lokiMessageWithPoW, to: target).map { rawResponse in if let json = rawResponse as? JSON, let powDifficulty = json["difficulty"] as? Int { guard powDifficulty != LokiAPI.powDifficulty else { return rawResponse } print("[Loki] Setting proof of work difficulty to \(powDifficulty).")