From 4e34db16be390364b688840b7087efacb63145e0 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sun, 3 Jan 2021 10:52:46 +0800 Subject: [PATCH 01/67] refactor: use Dir.glob --- NBus.podspec | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/NBus.podspec b/NBus.podspec index d3d5b0e..2963d30 100644 --- a/NBus.podspec +++ b/NBus.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| end s.subspec "Core" do |ss| - ss.source_files = ["NBus/Classes/Core/**/*.swift"] + ss.source_files = Dir.glob("NBus/Classes/Core/**/*.swift") end s.subspec "QQSDKHandler" do |ss| @@ -53,31 +53,31 @@ Pod::Spec.new do |s| end s.subspec "QQSDK" do |ss| - ss.vendored_frameworks = ["NBus/Vendor/QQ_SDK/**/*.framework"] + ss.vendored_frameworks = Dir.glob("NBus/Vendor/QQ_SDK/**/*.framework") ss.frameworks = ["SystemConfiguration", "WebKit"] ss.source_files = Dir.glob("NBus/Vendor/QQ_SDK/**/*.h") .reject { |name| name.include?("TencentOpenApiUmbrellaHeader.h") } - ss.resources = ["NBus/Vendor/QQ_SDK/**/*.bundle"] + ss.resources = Dir.glob("NBus/Vendor/QQ_SDK/**/*.bundle") end s.subspec "WechatSDK" do |ss| - ss.vendored_libraries = ["NBus/Vendor/Wechat_SDK/**/*.a"] + ss.vendored_libraries = Dir.glob("NBus/Vendor/Wechat_SDK/**/*.a") ss.frameworks = ["WebKit"] ss.libraries = ["c++"] - ss.source_files = ["NBus/Vendor/Wechat_SDK/**/*.h"] + ss.source_files = Dir.glob("NBus/Vendor/Wechat_SDK/**/*.h") ss.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-ObjC -all_load" } end s.subspec "WeiboSDK" do |ss| - ss.vendored_libraries = ["NBus/Vendor/Weibo_SDK/**/*.a"] + ss.vendored_libraries = Dir.glob("NBus/Vendor/Weibo_SDK/**/*.a") - ss.source_files = ["NBus/Vendor/Weibo_SDK/**/*.h"] + ss.source_files = Dir.glob("NBus/Vendor/Weibo_SDK/**/*.h") - ss.resources = ["NBus/Vendor/Weibo_SDK/**/*.bundle"] + ss.resources = Dir.glob("NBus/Vendor/Weibo_SDK/**/*.bundle") end s.prepare_command = <<-CMD From e2e129b8abef171b5ba20c45e086d8285b228535 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 14:35:45 +0800 Subject: [PATCH 02/67] fix: update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cd05f23..89396be 100644 --- a/.gitignore +++ b/.gitignore @@ -48,7 +48,7 @@ fastlane/FastlaneRunner .LSOverride # Icon must end with two \r -Icon +Icon # Thumbnails ._* From 9e0365740c3d72f3fcb273bff4474dfd251e054f Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 14:55:03 +0800 Subject: [PATCH 03/67] feat: update swiftlint --- .swiftlint.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 16751af..1e6db25 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -13,7 +13,6 @@ identifier_name: line_length: ignores_comments: true ignores_interpolated_strings: true - warning: 140 type_name: excluded: From 64d8d8e5279d49e5e3b656132feb09b796de6fb5 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 15:01:24 +0800 Subject: [PATCH 04/67] refactor: disable line_length lint --- NBus/Classes/Handler/SystemHandler.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NBus/Classes/Handler/SystemHandler.swift b/NBus/Classes/Handler/SystemHandler.swift index 498f4b1..3000ff2 100644 --- a/NBus/Classes/Handler/SystemHandler.swift +++ b/NBus/Classes/Handler/SystemHandler.swift @@ -185,8 +185,12 @@ extension SystemHandler { public enum ShareOptionKeys { + // swiftlint:disable line_length + public static let presentingViewController = Bus.ShareOptionKey(rawValue: "com.nuomi1.bus.systemHandler.presentingViewController") + // swiftlint:enable line_length + public static let sourceView = Bus.ShareOptionKey(rawValue: "com.nuomi1.bus.systemHandler.sourceView") public static let sourceRect = Bus.ShareOptionKey(rawValue: "com.nuomi1.bus.systemHandler.sourceRect") @@ -199,8 +203,12 @@ extension SystemHandler { public static let identityToken = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.systemHandler.identityToken") + // swiftlint:disable line_length + public static let authorizationCode = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.systemHandler.authorizationCode") + // swiftlint:enable line_length + public static let user = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.systemHandler.user") public static let email = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.systemHandler.email") From e86dd9358b7fd281de3d14b5a6274dc4b62c248d Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 15:34:21 +0800 Subject: [PATCH 05/67] chore: update --- Example/Podfile.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 1bfd493..15f4526 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,24 +1,24 @@ PODS: - - NBus (0.6.0): - - NBus/SDKHandlers (= 0.6.0) - - NBus/Core (0.6.0) - - NBus/QQSDK (0.6.0) - - NBus/QQSDKHandler (0.6.0): + - NBus (0.7.0): + - NBus/SDKHandlers (= 0.7.0) + - NBus/Core (0.7.0) + - NBus/QQSDK (0.7.0) + - NBus/QQSDKHandler (0.7.0): - NBus/Core - NBus/QQSDK - - NBus/SDKHandlers (0.6.0): + - NBus/SDKHandlers (0.7.0): - NBus/QQSDKHandler - NBus/SystemHandler - NBus/WechatSDKHandler - NBus/WeiboSDKHandler - - NBus/SystemHandler (0.6.0): + - NBus/SystemHandler (0.7.0): - NBus/Core - - NBus/WechatSDK (0.6.0) - - NBus/WechatSDKHandler (0.6.0): + - NBus/WechatSDK (0.7.0) + - NBus/WechatSDKHandler (0.7.0): - NBus/Core - NBus/WechatSDK - - NBus/WeiboSDK (0.6.0) - - NBus/WeiboSDKHandler (0.6.0): + - NBus/WeiboSDK (0.7.0) + - NBus/WeiboSDKHandler (0.7.0): - NBus/Core - NBus/WeiboSDK - PinLayout (1.9.2) @@ -46,7 +46,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - NBus: af1724058bfe5c1b70803657f1aa5add29c42007 + NBus: 956e0711f202ced6ffe2b9eaccb8b696f9e87585 PinLayout: 0d96022e46e8b80468d819f182a393b97ca038da RxCocoa: 32065309a38d29b5b0db858819b5bf9ef038b601 RxRelay: d77f7d771495f43c556cbc43eebd1bb54d01e8e9 From 185d135bec3c96f6a800693ea9548532e7f1d857 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 16:37:25 +0800 Subject: [PATCH 06/67] feat: add SwiftTrace --- Example/Podfile | 1 + Example/Podfile.lock | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Example/Podfile b/Example/Podfile index d57dfa6..95c91e2 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -7,6 +7,7 @@ target "BusMock" do pod "PinLayout" pod "RxCocoa" + pod "SwiftTrace" end post_install do |installer| diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 15f4526..01950cf 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -28,11 +28,13 @@ PODS: - RxRelay (5.1.1): - RxSwift (~> 5) - RxSwift (5.1.1) + - SwiftTrace (6.6.0) DEPENDENCIES: - NBus (from `../`) - PinLayout - RxCocoa + - SwiftTrace SPEC REPOS: trunk: @@ -40,6 +42,7 @@ SPEC REPOS: - RxCocoa - RxRelay - RxSwift + - SwiftTrace EXTERNAL SOURCES: NBus: @@ -51,7 +54,8 @@ SPEC CHECKSUMS: RxCocoa: 32065309a38d29b5b0db858819b5bf9ef038b601 RxRelay: d77f7d771495f43c556cbc43eebd1bb54d01e8e9 RxSwift: 81470a2074fa8780320ea5fe4102807cb7118178 + SwiftTrace: affc6601a316add7c299a3916d9f43c286a583ef -PODFILE CHECKSUM: 375fd17d41450a3e1f41c4b4dd1d218a2089309d +PODFILE CHECKSUM: f587d3fe8cbd747cd65b94bf52b0ee7e71effe2a COCOAPODS: 1.10.0 From f2e38763b719570ccd94356a14c0df93cea6c9ef Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 16:37:38 +0800 Subject: [PATCH 07/67] feat: observeQQ --- Example/NBus/AppDelegate.swift | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index 466f7c5..bd55484 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -9,6 +9,8 @@ import NBus import PinLayout import RxCocoa +import RxSwift +import SwiftTrace import UIKit @UIApplicationMain @@ -52,3 +54,58 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return Bus.shared.openUserActivity(userActivity) } } + +extension AppDelegate { + + private func pasteboardItems() -> Observable<[[String]]> { + NotificationCenter.default.rx + .notification(UIPasteboard.changedNotification) + .map { _ -> [[String]] in + UIPasteboard.general.items.map { item -> [String] in + item.map { key, value -> String in + switch value { + case let data as Data: + if + let plist = try? PropertyListSerialization.propertyList( + from: data, + options: [], + format: nil + ) { + return "\(key), \(plist)" + } else if + let string = String( + data: data, + encoding: .utf8 + ) { + return "\(key), \(string)" + } else { + assertionFailure() + return "\(key), \(value)" + } + case let string as String: + return "\(key), \(string)" + default: + assertionFailure() + return "\(key), \(value)" + } + } + } + } + .distinctUntilChanged() + } +} + +extension AppDelegate { + + private func observeQQ() { + SwiftTrace.traceClasses(matchingPattern: "^QQ") + SwiftTrace.traceClasses(matchingPattern: "^Tencent") + + _ = pasteboardItems() + .delay(.seconds(1), scheduler: MainScheduler.instance) + .takeUntil(rx.deallocating) + .bind(onNext: { items in + logger.debug("\(items)") + }) + } +} From 62092c2dd5c62ca44613430657d87659a15b9081 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 21:14:35 +0800 Subject: [PATCH 08/67] feat: add WoodPeckeriOS --- Example/Podfile | 1 + Example/Podfile.lock | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Example/Podfile b/Example/Podfile index 95c91e2..fb298cc 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -8,6 +8,7 @@ target "BusMock" do pod "PinLayout" pod "RxCocoa" pod "SwiftTrace" + pod "WoodPeckeriOS" end post_install do |installer| diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 01950cf..917ee79 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -29,12 +29,14 @@ PODS: - RxSwift (~> 5) - RxSwift (5.1.1) - SwiftTrace (6.6.0) + - WoodPeckeriOS (1.2.9) DEPENDENCIES: - NBus (from `../`) - PinLayout - RxCocoa - SwiftTrace + - WoodPeckeriOS SPEC REPOS: trunk: @@ -43,6 +45,7 @@ SPEC REPOS: - RxRelay - RxSwift - SwiftTrace + - WoodPeckeriOS EXTERNAL SOURCES: NBus: @@ -55,7 +58,8 @@ SPEC CHECKSUMS: RxRelay: d77f7d771495f43c556cbc43eebd1bb54d01e8e9 RxSwift: 81470a2074fa8780320ea5fe4102807cb7118178 SwiftTrace: affc6601a316add7c299a3916d9f43c286a583ef + WoodPeckeriOS: f16864f7a78d5c6daa605591dd66690d466d95be -PODFILE CHECKSUM: f587d3fe8cbd747cd65b94bf52b0ee7e71effe2a +PODFILE CHECKSUM: 997337f6cf183fc4e4ba8e80d4eaa8ad4f55c321 COCOAPODS: 1.10.0 From dcaccbedbf6fa3f38aba0e06fb014905642fd6ff Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 4 Jan 2021 21:14:46 +0800 Subject: [PATCH 09/67] fix: WoodPeckeriOS with iOS 14 --- Example/NBus/Info.plist | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Example/NBus/Info.plist b/Example/NBus/Info.plist index 7550fca..0669614 100644 --- a/Example/NBus/Info.plist +++ b/Example/NBus/Info.plist @@ -106,6 +106,12 @@ LSRequiresIPhoneOS + NSBonjourServices + + _adhp._tcp + + NSLocalNetworkUsageDescription + WoodPeckeriOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile From ad2e85ae5d37259d30ced95c9e3649400da09a8c Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:28:28 +0800 Subject: [PATCH 10/67] fix: more than zero --- Example/NBus/View/PlatformViewController+Oauth.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/NBus/View/PlatformViewController+Oauth.swift b/Example/NBus/View/PlatformViewController+Oauth.swift index db8b3ea..4ad9c99 100644 --- a/Example/NBus/View/PlatformViewController+Oauth.swift +++ b/Example/NBus/View/PlatformViewController+Oauth.swift @@ -89,7 +89,7 @@ extension PlatformViewController.OauthView { height: subview.intrinsicContentSize.height ) : CGSize( - width: superview.bounds.size.width - 2 * Constant.spacing, + width: max(0, superview.bounds.size.width - 2 * Constant.spacing), height: 5 * Constant.spacing ) }() From 602c44995cfbfea386170a03fe800766b22e5303 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:30:23 +0800 Subject: [PATCH 11/67] feat: switch handler --- Example/NBus/Model/AppState.swift | 38 ++++++++++------ .../PlatformViewController+ViewModel.swift | 26 ++++++----- .../NBus/View/PlatformViewController.swift | 43 +++++++++++++++++++ 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/Example/NBus/Model/AppState.swift b/Example/NBus/Model/AppState.swift index a9e0308..247b8cf 100644 --- a/Example/NBus/Model/AppState.swift +++ b/Example/NBus/Model/AppState.swift @@ -23,11 +23,20 @@ extension AppState { struct PlatformItem { let platform: Platform - let handler: HandlerType + let category: Category + let handlers: [Category: HandlerType] let viewController: () -> UIViewController } } +extension AppState.PlatformItem { + + enum Category: Hashable { + case bus + case sdk + } +} + extension AppState { func setup() { @@ -51,7 +60,10 @@ extension AppState { let wechatItem = AppState.PlatformItem( platform: Platforms.wechat, - handler: wechatSDKHandler, + category: .sdk, + handlers: [ + .sdk: wechatSDKHandler, + ], viewController: { PlatformViewController() } ) @@ -68,7 +80,10 @@ extension AppState { let qqItem = AppState.PlatformItem( platform: Platforms.qq, - handler: qqSDKHandler, + category: .sdk, + handlers: [ + .sdk: qqSDKHandler, + ], viewController: { PlatformViewController() } ) @@ -86,7 +101,10 @@ extension AppState { let weiboItem = AppState.PlatformItem( platform: Platforms.weibo, - handler: weiboSDKHandler, + category: .sdk, + handlers: [ + .sdk: weiboSDKHandler, + ], viewController: { PlatformViewController() } ) @@ -100,7 +118,10 @@ extension AppState { let systemItem = AppState.PlatformItem( platform: Platforms.system, - handler: systemHandler, + category: .bus, + handlers: [ + .bus: systemHandler, + ], viewController: { PlatformViewController() } ) @@ -110,13 +131,6 @@ extension AppState { weiboItem, systemItem, ]) - - Bus.shared.handlers = [ - wechatSDKHandler, - qqSDKHandler, - weiboSDKHandler, - systemHandler, - ] } // swiftlint:enable function_body_length diff --git a/Example/NBus/View/PlatformViewController+ViewModel.swift b/Example/NBus/View/PlatformViewController+ViewModel.swift index 1fae009..44471be 100644 --- a/Example/NBus/View/PlatformViewController+ViewModel.swift +++ b/Example/NBus/View/PlatformViewController+ViewModel.swift @@ -21,6 +21,10 @@ extension PlatformViewController { let title: Observable + let isSwitchEnabled: Observable + let currentCategory: BehaviorRelay + let currentHandler: Observable + let endpoints: Observable<[Endpoint]> let currentEndpoint: BehaviorRelay @@ -33,23 +37,25 @@ extension PlatformViewController { init(_ element: AppState.PlatformItem) { title = .just("\(element.platform)") - endpoints = .just(element.endpoints ?? []) + isSwitchEnabled = .just(element.handlers.count > 1) + currentCategory = .init(value: element.category) + currentHandler = currentCategory + .compactMap { element.handlers[$0] } + + endpoints = currentHandler + .compactMap { $0 as? ShareHandlerType } + .map { $0.endpoints } currentEndpoint = .init(value: nil) platform = .init(value: element.platform) oauthInfo = .init(value: Self.defaultOauthInfo) - isShareEnabled = .just(element.handler is ShareHandlerType) - isOauthEnabled = .just(element.handler is OauthHandlerType) + isShareEnabled = currentHandler + .map { $0 is ShareHandlerType } + isOauthEnabled = currentHandler + .map { $0 is OauthHandlerType } } static let defaultOauthInfo = OauthInfo(isLogin: false, parameter: "未登录") } } - -extension AppState.PlatformItem { - - fileprivate var endpoints: [Endpoint]? { - (handler as? ShareHandlerType)?.endpoints - } -} diff --git a/Example/NBus/View/PlatformViewController.swift b/Example/NBus/View/PlatformViewController.swift index eb63438..b56a453 100644 --- a/Example/NBus/View/PlatformViewController.swift +++ b/Example/NBus/View/PlatformViewController.swift @@ -29,6 +29,8 @@ class PlatformViewController: UIViewController { private let disposeBag = DisposeBag() + private let handlerBarButtonItem = UIBarButtonItem() + private let scrollView = UIScrollView() private let contentView = UIView() @@ -43,6 +45,7 @@ extension PlatformViewController { view.backgroundColor = .white + setupNavigationItem() setupSubviews() } @@ -75,6 +78,10 @@ extension PlatformViewController { scrollView.contentSize = contentView.bounds.size } + private func setupNavigationItem() { + navigationItem.rightBarButtonItem = handlerBarButtonItem + } + private func setupSubviews() { view.addSubview(scrollView) scrollView.addSubview(contentView) @@ -93,6 +100,42 @@ extension PlatformViewController { .bind(to: rx.title) .disposed(by: disposeBag) + viewModel.isSwitchEnabled + .bind(to: handlerBarButtonItem.rx.isEnabled) + .disposed(by: disposeBag) + + viewModel.currentCategory + .map { + switch $0 { + case .bus: + return "开源" + case .sdk: + return "闭源" + } + } + .bind(to: handlerBarButtonItem.rx.title) + .disposed(by: disposeBag) + + viewModel.currentHandler + .bind(onNext: { + Bus.shared.handlers = [$0] + }) + .disposed(by: disposeBag) + + handlerBarButtonItem.rx + .tap + .withLatestFrom(viewModel.currentCategory) + .map { + switch $0 { + case .bus: + return .sdk + case .sdk: + return .bus + } + } + .bind(to: viewModel.currentCategory) + .disposed(by: disposeBag) + shareView.contentView.binding(viewModel) shareView.contentView.onShare = { [weak self] message, endpoint, view in let options: [Bus.ShareOptionKey: Any] = { From c93bb433648cbce2c5535dd75be8d865c9ff6cf0 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:31:17 +0800 Subject: [PATCH 12/67] feat: log url --- Example/NBus/AppDelegate.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index bd55484..831129c 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -43,6 +43,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:] ) -> Bool { + logger.debug("\(url)") return Bus.shared.openURL(url) } @@ -51,6 +52,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void ) -> Bool { + logger.debug("\(userActivity.webpageURL!)") return Bus.shared.openUserActivity(userActivity) } } From a9d9b4266870f6e1e31a64be3ed3f2382cb86b3a Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:31:40 +0800 Subject: [PATCH 13/67] refactor: log type --- Example/NBus/AppDelegate.swift | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index 831129c..42aed51 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -68,24 +68,29 @@ extension AppDelegate { switch value { case let data as Data: if + let object = NSKeyedUnarchiver.unarchiveObject( + with: data + ) { + return "[Data-Keyed] \(key), \(object)" + } else if let plist = try? PropertyListSerialization.propertyList( from: data, options: [], format: nil ) { - return "\(key), \(plist)" + return "[Data-Plist] \(key), \(plist)" } else if let string = String( data: data, encoding: .utf8 ) { - return "\(key), \(string)" + return "[Data-String] \(key), \(string)" } else { assertionFailure() return "\(key), \(value)" } case let string as String: - return "\(key), \(string)" + return "[String] \(key), \(string)" default: assertionFailure() return "\(key), \(value)" From 921eebdd7533ed5c4250b49b4d76088ffecf2a7b Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:32:02 +0800 Subject: [PATCH 14/67] feat: clear --- Example/NBus/AppDelegate.swift | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index 42aed51..bbf1caf 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -23,6 +23,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + clearKeychains() + clearPasteboard() + clearUserDefaults() + AppState.shared.setup() let viewController = ViewController() @@ -102,6 +106,41 @@ extension AppDelegate { } } +extension AppDelegate { + + private func clearKeychains() { + let items = [ + kSecClassGenericPassword, + kSecClassInternetPassword, + kSecClassCertificate, + kSecClassKey, + kSecClassIdentity, + ] + + let status = items + .map { [kSecClass: $0] as CFDictionary } + .map { SecItemDelete($0) } + + assert(status.allSatisfy { + $0 == errSecSuccess || $0 == errSecItemNotFound + }) + } + + private func clearPasteboard() { + let pasteboard = UIPasteboard.general + + pasteboard.items = [] + } + + private func clearUserDefaults() { + let defaults = UserDefaults.standard + + for (key, _) in defaults.dictionaryRepresentation() { + defaults.removeObject(forKey: key) + } + } +} + extension AppDelegate { private func observeQQ() { From 4dd33635c0c8a46c34cfeeb0a23820eea96cf188 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:32:32 +0800 Subject: [PATCH 15/67] feat: observe --- Example/NBus/AppDelegate.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index bbf1caf..3e21f19 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -27,6 +27,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { clearPasteboard() clearUserDefaults() +// observeQQ() + AppState.shared.setup() let viewController = ViewController() From b9dbe9af6bf05e109fb3c4b93b770d1659cedc34 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:33:09 +0800 Subject: [PATCH 16/67] feat: FileMessage with fileName --- NBus/Classes/Core/Bus+Message.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NBus/Classes/Core/Bus+Message.swift b/NBus/Classes/Core/Bus+Message.swift index 50c3147..ccd3af5 100644 --- a/NBus/Classes/Core/Bus+Message.swift +++ b/NBus/Classes/Core/Bus+Message.swift @@ -104,6 +104,7 @@ public enum Messages { public static func file( data: Data, fileExtension: String, + fileName: String? = nil, title: String? = nil, description: String? = nil, thumbnail: Data? = nil @@ -111,6 +112,7 @@ public enum Messages { FileMessage( data: data, fileExtension: fileExtension, + fileName: fileName, title: title, description: description, thumbnail: thumbnail @@ -217,11 +219,17 @@ public struct FileMessage: MediaMessageType { public let fileExtension: String + public let fileName: String? + public let title: String? public let description: String? public let thumbnail: Data? + + public var fullName: String? { + fileName.map { "\($0).\(fileExtension)" } + } } public struct MiniProgramMessage: MessageType { From 2fdabcaed30d63f023977c2b4e64e7334eddfa58 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:33:55 +0800 Subject: [PATCH 17/67] feat: set flashURL in QQApiAudioObject --- NBus/Classes/Handler/QQSDKHandler.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NBus/Classes/Handler/QQSDKHandler.swift b/NBus/Classes/Handler/QQSDKHandler.swift index 71068f8..9549f62 100644 --- a/NBus/Classes/Handler/QQSDKHandler.swift +++ b/NBus/Classes/Handler/QQSDKHandler.swift @@ -111,6 +111,8 @@ extension QQSDKHandler: ShareHandlerType { targetContentType: .audio ) + audioObject?.flashURL = message.dataLink + request = SendMessageToQQReq(content: audioObject) case let message as VideoMessage: From c99cbe02282e66e5f0edc4f62811420e535d142a Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:34:29 +0800 Subject: [PATCH 18/67] feat: set fileName in QQApiFileObject --- NBus/Classes/Handler/QQSDKHandler.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NBus/Classes/Handler/QQSDKHandler.swift b/NBus/Classes/Handler/QQSDKHandler.swift index 9549f62..09be76f 100644 --- a/NBus/Classes/Handler/QQSDKHandler.swift +++ b/NBus/Classes/Handler/QQSDKHandler.swift @@ -145,6 +145,8 @@ extension QQSDKHandler: ShareHandlerType { description: message.description ) + fileObject?.fileName = message.fullName + request = SendMessageToQQReq(content: fileObject) case let message as MiniProgramMessage: From 0228c3ca2be55886bc0cbd5b42dfa52df1fe8458 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:34:42 +0800 Subject: [PATCH 19/67] fix: use QQApiNewsObject --- NBus/Classes/Handler/QQSDKHandler.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NBus/Classes/Handler/QQSDKHandler.swift b/NBus/Classes/Handler/QQSDKHandler.swift index 09be76f..05ed2be 100644 --- a/NBus/Classes/Handler/QQSDKHandler.swift +++ b/NBus/Classes/Handler/QQSDKHandler.swift @@ -127,7 +127,7 @@ extension QQSDKHandler: ShareHandlerType { request = SendMessageToQQReq(content: videoObject) case let message as WebPageMessage: - let webPageObject = QQApiURLObject( + let webPageObject = QQApiNewsObject( url: message.link, title: message.title, description: message.description, @@ -150,7 +150,7 @@ extension QQSDKHandler: ShareHandlerType { request = SendMessageToQQReq(content: fileObject) case let message as MiniProgramMessage: - let webPageObject = QQApiURLObject( + let webPageObject = QQApiNewsObject( url: message.link, title: message.link.absoluteString, description: "", From 02d5287861d3920b4f1097080a5cc934da5454ee Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:35:02 +0800 Subject: [PATCH 20/67] feat: BusWrapper --- NBus/Classes/Core/Bus+Wrapper.swift | 33 +++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 NBus/Classes/Core/Bus+Wrapper.swift diff --git a/NBus/Classes/Core/Bus+Wrapper.swift b/NBus/Classes/Core/Bus+Wrapper.swift new file mode 100644 index 0000000..168076c --- /dev/null +++ b/NBus/Classes/Core/Bus+Wrapper.swift @@ -0,0 +1,33 @@ +// +// Bus+Wrapper.swift +// NBus +// +// Created by nuomi1 on 2021/1/4. +// Copyright © 2021 nuomi1. All rights reserved. +// + +import Foundation + +public struct BusWrapper { + + public let base: Base + + public init(_ base: Base) { + self.base = base + } +} + +public protocol BusCompatible { + + associatedtype BusBase + + var bus: BusWrapper { get set } +} + +extension BusCompatible { + + public var bus: BusWrapper { + get { BusWrapper(self) } + set {} + } +} From f356e62e886265d346dc863953c37f7ca06a0670 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:35:39 +0800 Subject: [PATCH 21/67] refactor: compactMapContent --- NBus/Classes/Core/Bus+Helper.swift | 8 +++++--- NBus/Classes/Handler/QQSDKHandler.swift | 1 + NBus/Classes/Handler/SystemHandler.swift | 1 + NBus/Classes/Handler/WechatSDKHandler.swift | 1 + NBus/Classes/Handler/WeiboSDKHandler.swift | 1 + 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/NBus/Classes/Core/Bus+Helper.swift b/NBus/Classes/Core/Bus+Helper.swift index 6b4b25b..1624682 100644 --- a/NBus/Classes/Core/Bus+Helper.swift +++ b/NBus/Classes/Core/Bus+Helper.swift @@ -8,10 +8,12 @@ import Foundation -extension Dictionary where Key == Bus.OauthInfoKey, Value == String? { +extension Dictionary: BusCompatible {} - func compactMapContent() -> [Bus.OauthInfoKey: String] { - compactMapValues { value -> String? in +extension BusWrapper where Base == [Bus.OauthInfoKey: String?] { + + public func compactMapContent() -> [Bus.OauthInfoKey: String] { + base.compactMapValues { value -> String? in guard let value = value, !value.isEmpty else { return nil } diff --git a/NBus/Classes/Handler/QQSDKHandler.swift b/NBus/Classes/Handler/QQSDKHandler.swift index 05ed2be..3960d71 100644 --- a/NBus/Classes/Handler/QQSDKHandler.swift +++ b/NBus/Classes/Handler/QQSDKHandler.swift @@ -330,6 +330,7 @@ extension QQSDKHandler { OauthInfoKeys.accessToken: owner?.oauthCoordinator.accessToken, OauthInfoKeys.openID: owner?.oauthCoordinator.openId, ] + .bus .compactMapContent() if !parameters.isEmpty { diff --git a/NBus/Classes/Handler/SystemHandler.swift b/NBus/Classes/Handler/SystemHandler.swift index 3000ff2..eed3541 100644 --- a/NBus/Classes/Handler/SystemHandler.swift +++ b/NBus/Classes/Handler/SystemHandler.swift @@ -252,6 +252,7 @@ extension SystemHandler { OauthInfoKeys.givenName: credential.fullName?.givenName, OauthInfoKeys.familyName: credential.fullName?.familyName, ] + .bus .compactMapContent() if !parameters.isEmpty { diff --git a/NBus/Classes/Handler/WechatSDKHandler.swift b/NBus/Classes/Handler/WechatSDKHandler.swift index 0768618..4b1011c 100644 --- a/NBus/Classes/Handler/WechatSDKHandler.swift +++ b/NBus/Classes/Handler/WechatSDKHandler.swift @@ -274,6 +274,7 @@ extension WechatSDKHandler { let parameters = [ OauthInfoKeys.code: code, ] + .bus .compactMapContent() if !parameters.isEmpty { diff --git a/NBus/Classes/Handler/WeiboSDKHandler.swift b/NBus/Classes/Handler/WeiboSDKHandler.swift index c70c0ce..7dc7dfc 100644 --- a/NBus/Classes/Handler/WeiboSDKHandler.swift +++ b/NBus/Classes/Handler/WeiboSDKHandler.swift @@ -205,6 +205,7 @@ extension WeiboSDKHandler { let parameters = [ OauthInfoKeys.accessToken: accessToken, ] + .bus .compactMapContent() if !parameters.isEmpty { From f413ae8de42a81b169d913864c53435325d24bf7 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:36:13 +0800 Subject: [PATCH 22/67] feat: BusWrapper with Bundle --- NBus/Classes/Core/Bus+Helper.swift | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/NBus/Classes/Core/Bus+Helper.swift b/NBus/Classes/Core/Bus+Helper.swift index 1624682..97951c1 100644 --- a/NBus/Classes/Core/Bus+Helper.swift +++ b/NBus/Classes/Core/Bus+Helper.swift @@ -22,3 +22,33 @@ extension BusWrapper where Base == [Bus.OauthInfoKey: String?] { } } } + +extension NSObject: BusCompatible {} + +extension BusWrapper where Base: Bundle { + + private func value(forKeys keys: [String]) -> T? { + let infos = [ + base.localizedInfoDictionary ?? [:], + base.infoDictionary ?? [:], + ] + + for key in keys { + for info in infos { + if let value = info[key] as? T { + return value + } + } + } + + return nil + } + + public var identifier: String? { + value(forKeys: ["CFBundleIdentifier"]) + } + + public var displayName: String? { + value(forKeys: ["CFBundleDisplayName", "CFBundleName"]) + } +} From 507400623d601c586751e0105b36763b3abe733e Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:36:29 +0800 Subject: [PATCH 23/67] feat: BusWrapper with UIPasteboard --- NBus/Classes/Core/Bus+Helper.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NBus/Classes/Core/Bus+Helper.swift b/NBus/Classes/Core/Bus+Helper.swift index 97951c1..89bc245 100644 --- a/NBus/Classes/Core/Bus+Helper.swift +++ b/NBus/Classes/Core/Bus+Helper.swift @@ -52,3 +52,19 @@ extension BusWrapper where Base: Bundle { value(forKeys: ["CFBundleDisplayName", "CFBundleName"]) } } + +extension BusWrapper where Base: UIPasteboard { + + public var oldText: String? { + guard + let typeListString = UIPasteboard.typeListString as? [String] + else { + assertionFailure() + return nil + } + + guard base.contains(pasteboardTypes: typeListString) else { return nil } + + return base.string + } +} From 028574b4d47ffd5cbb50d79527a0542388534878 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Mon, 11 Jan 2021 23:39:19 +0800 Subject: [PATCH 24/67] feat: QQHandler --- NBus/Classes/Handler/QQHandler.swift | 416 +++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 NBus/Classes/Handler/QQHandler.swift diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift new file mode 100644 index 0000000..85152c8 --- /dev/null +++ b/NBus/Classes/Handler/QQHandler.swift @@ -0,0 +1,416 @@ +// +// QQHandler.swift +// NBus +// +// Created by nuomi1 on 2021/1/4. +// Copyright © 2021 nuomi1. All rights reserved. +// + +import Foundation + +public class QQHandler { + + public let endpoints: [Endpoint] = [ + Endpoints.QQ.friend, + Endpoints.QQ.timeline, + ] + + public var isInstalled: Bool { + guard let url = URL(string: "mqq://") else { + assertionFailure() + return false + } + + return UIApplication.shared.canOpenURL(url) + } + + private var shareCompletionHandler: Bus.ShareCompletionHandler? + + public let appID: String + public let universalLink: URL + + private let sdkVersion = "3.5.1" + private var token: String? { + get { + let object = UserDefaults.standard + .object(forKey: "com.nuomi1.bus.qqHandler.token") + return object as? String + } + set { + if let token = newValue { + UserDefaults.standard + .set(token, forKey: "com.nuomi1.bus.qqHandler.token") + } + } + } + + public init(appID: String, universalLink: URL) { + self.appID = appID + self.universalLink = universalLink + } +} + +extension QQHandler: ShareHandlerType { + + public func share( + message: MessageType, + to endpoint: Endpoint, + options: [Bus.ShareOptionKey: Any], + completionHandler: @escaping Bus.ShareCompletionHandler + ) { + guard isInstalled else { + completionHandler(.failure(.missingApplication)) + return + } + + guard canShare(message: message.identifier, to: endpoint) else { + completionHandler(.failure(.unsupportedMessage)) + return + } + + guard + let identifier = identifier(), + let displayName = displayName(), + let cflag = cflag(endpoint, message.identifier), + let txID = txID() + else { + assertionFailure() + completionHandler(.failure(.invalidMessage)) + return + } + + shareCompletionHandler = completionHandler + + var urlItems: [String: String] = [:] + var pasteBoardItems: [String: Any?] = [:] + + urlItems["appsign_txid"] = txID + urlItems["bundleid"] = identifier + urlItems["callback_name"] = txID + urlItems["callback_type"] = "scheme" + urlItems["cflag"] = cflag + urlItems["generalpastboard"] = "1" + urlItems["sdkv"] = sdkVersion + urlItems["shareType"] = "0" + urlItems["src_type"] = "app" + urlItems["thirdAppDisplayName"] = displayName + urlItems["version"] = "1" + + if let token = token { + urlItems["appsign_token"] = token + } + + if let oldText = UIPasteboard.general.bus.oldText { + pasteBoardItems["pasted_string"] = oldText + } + + if let message = message as? MediaMessageType { + if let title = message.title?.data(using: .utf8)?.base64EncodedString() { + urlItems["title"] = title + } + + if let description = message.description?.data(using: .utf8)?.base64EncodedString() { + urlItems["description"] = description + } + } + + switch message { + case let message as TextMessage: + guard + let text = message.text.data(using: .utf8)?.base64EncodedString() + else { + completionHandler(.failure(.invalidMessage)) + return + } + + urlItems["file_type"] = "text" + + urlItems["file_data"] = text + + case let message as ImageMessage: + urlItems["file_type"] = "img" + + pasteBoardItems["file_data"] = message.data + + case let message as AudioMessage: + guard + let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + else { + completionHandler(.failure(.invalidMessage)) + return + } + + urlItems["file_type"] = "audio" + + urlItems["url"] = url + + case let message as VideoMessage: + guard + let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + else { + completionHandler(.failure(.invalidMessage)) + return + } + + urlItems["file_type"] = "video" + + urlItems["url"] = url + + case let message as WebPageMessage: + guard + let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + else { + completionHandler(.failure(.invalidMessage)) + return + } + + urlItems["file_type"] = "news" + + urlItems["url"] = url + + case let message as FileMessage: + urlItems["file_type"] = "localFile" + + if + let fileName = message.fullName?.data(using: .utf8)?.base64EncodedString() { + urlItems["fileName"] = fileName + } + + pasteBoardItems["file_data"] = message.data + + case let message as MiniProgramMessage: + guard + let path = message.path.data(using: .utf8)?.base64EncodedString(), + let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + else { + completionHandler(.failure(.invalidMessage)) + return + } + + urlItems["file_type"] = "news" + + urlItems["url"] = url + + urlItems["mini_appid"] = message.miniProgramID + urlItems["mini_path"] = path + urlItems["mini_weburl"] = url + urlItems["mini_type"] = miniProgramType(message.miniProgramType) + urlItems["mini_code64"] = "1" + + default: + assertionFailure() + completionHandler(.failure(.unsupportedMessage)) + return + } + + let pbItems = pasteBoardItems.compactMapValues { $0 } + + if !pbItems.isEmpty { + urlItems["objectlocation"] = "pasteboard" + + let data = NSKeyedArchiver.archivedData(withRootObject: pbItems) + + UIPasteboard.general.setData( + data, + forPasteboardType: "com.tencent.mqq.api.apiLargeData" + ) + } + + var components = URLComponents() + + components.scheme = "https" + components.host = "qm.qq.com" + components.path = "/opensdkul/mqqapi/share/to_fri" + + components.queryItems = urlItems.map { key, value in + URLQueryItem(name: key, value: value) + } + + guard let url = components.url else { + completionHandler(.failure(.invalidMessage)) + return + } + + guard UIApplication.shared.canOpenURL(url) else { + completionHandler(.failure(.unknown)) + return + } + + UIApplication.shared.open(url) { result in + if !result { + completionHandler(.failure(.unknown)) + } + } + } + + private func canShare(message: Message, to endpoint: Endpoint) -> Bool { + switch endpoint { + case Endpoints.QQ.friend: + return true + case Endpoints.QQ.timeline: + return ![ + Messages.file, + Messages.miniProgram, + ].contains(message) + default: + assertionFailure() + return false + } + } + + private func identifier() -> String? { + let identifier = Bundle.main.bus.identifier + return identifier?.data(using: .utf8)?.base64EncodedString() + } + + private func displayName() -> String? { + let displayName = Bundle.main.bus.displayName + return displayName?.data(using: .utf8)?.base64EncodedString() + } + + private func txID() -> String? { + let number = appID.trimmingCharacters(in: .letters) + let txID = String(format: "%08llX", (number as NSString).longLongValue) + return "QQ\(txID)" + } + + private func cflag(_ endpoint: Endpoint, _ message: Message) -> String? { + var flags: [Int] = [] + + switch endpoint { + case Endpoints.QQ.friend: + flags.append(2) // qqapiCtrlFlagQZoneShareForbid + + if message == Messages.file { + flags.append(16) // qqapiCtrlFlagQQShareDataline + } + + if message == Messages.miniProgram { + flags.append(64) // kQQAPICtrlFlagQQShareEnableMiniProgram + } + case Endpoints.QQ.timeline: + break + default: + return nil + } + + let result = flags.reduce(0) { result, flag in result | flag } + return "\(result)" + } + + private func miniProgramType(_ miniProgramType: MiniProgramMessage.MiniProgramType) -> String { + let result: Int + + switch miniProgramType { + case .release: + result = 3 // online + case .test: + result = 1 // test + case .preview: + result = 4 // preview + } + + return "\(result)" + } +} + +extension QQHandler: OpenUserActivityHandlerType { + + public func openUserActivity(_ userActivity: NSUserActivity) { + guard + let url = userActivity.webpageURL, + let components = URLComponents(url: url, resolvingAgainstBaseURL: false), + let identifier = Bundle.main.bus.identifier + else { return } + + switch components.path { + case universalLink.appendingPathComponent("\(identifier)/mqqsignapp").path: + handleSignToken(with: components) + case universalLink.appendingPathComponent("\(identifier)").path: + handleShare(with: components) + default: + assertionFailure() + } + } + + private func handleSignToken(with components: URLComponents) { + let decoder = JSONDecoder() + decoder.dataDecodingStrategy = .base64 + + guard + let item = components.queryItems?.first(where: { $0.name == "appsign_extrainfo" }), + let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), + let infos = try? decoder.decode([String: String].self, from: itemData), + let appSignRedirect = infos["appsign_redirect"], + let appSignToken = infos["appsign_token"], + var components = URLComponents(string: appSignRedirect) + else { + return + } + + token = appSignToken + + var items: [String: String] = [:] + + items["openredirect"] = "1" + items["appsign_token"] = appSignToken + + components.scheme = "https" + components.host = "qm.qq.com" + components.path = "/opensdkul/mqqapi/share/to_fri" + + components.queryItems?.append(contentsOf: items.map { key, value in + URLQueryItem(name: key, value: value) + }) + + guard + let url = components.url, + UIApplication.shared.canOpenURL(url) + else { return } + + UIApplication.shared.open(url) { [weak self] result in + if !result { + self?.shareCompletionHandler?(.failure(.unknown)) + } + } + } + + private func handleShare(with components: URLComponents) { + let decoder = JSONDecoder() + decoder.dataDecodingStrategy = .base64 + + guard + let item = components.queryItems?.first(where: { $0.name == "sdkactioninfo" }), + let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), + let infos = try? decoder.decode([String: String].self, from: itemData) + else { return } + + var components = URLComponents() + + components.scheme = infos["sdk_action_sheme"] + components.host = infos["sdk_action_host"] + components.path = infos["sdk_action_path"] ?? "" + components.query = infos["sdk_action_query"] + + switch components.host { + case "response_from_qq": + guard + let item = components.queryItems?.first(where: { $0.name == "error" }) + else { + assertionFailure() + return + } + + switch item.value { + case "0": + shareCompletionHandler?(.success(())) + case "-4": + shareCompletionHandler?(.failure(.userCancelled)) + default: + shareCompletionHandler?(.failure(.unknown)) + } + default: + assertionFailure() + } + } +} From 6a52391bdb7f1f2743559d8d16e33d3d25fc9f8e Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:50:29 +0800 Subject: [PATCH 25/67] feat: QQHandler with oauth --- NBus/Classes/Handler/QQHandler.swift | 144 +++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 85152c8..8a38a4e 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -15,6 +15,8 @@ public class QQHandler { Endpoints.QQ.timeline, ] + public let platform: Platform = Platforms.qq + public var isInstalled: Bool { guard let url = URL(string: "mqq://") else { assertionFailure() @@ -25,6 +27,7 @@ public class QQHandler { } private var shareCompletionHandler: Bus.ShareCompletionHandler? + private var oauthCompletionHandler: Bus.OauthCompletionHandler? public let appID: String public let universalLink: URL @@ -314,6 +317,99 @@ extension QQHandler: ShareHandlerType { } } +extension QQHandler: OauthHandlerType { + + public func oauth( + options: [Bus.OauthOptionKey: Any], + completionHandler: @escaping Bus.OauthCompletionHandler + ) { + guard isInstalled else { + completionHandler(.failure(.missingApplication)) + return + } + + guard + let identifier = identifier(), + let txID = txID() + else { + assertionFailure() + completionHandler(.failure(.invalidMessage)) + return + } + + oauthCompletionHandler = completionHandler + + var urlItems: [String: String] = [:] + var pasteBoardItems: [String: Any?] = [:] + + pasteBoardItems["app_id"] = appID.trimmingCharacters(in: .letters) + pasteBoardItems["sdkp"] = "i" + pasteBoardItems["response_type"] = "token" + pasteBoardItems["app_name"] = Bundle.main.bus.displayName + pasteBoardItems["appsign_token"] = "" + pasteBoardItems["scope"] = "get_user_info" + pasteBoardItems["bundleid"] = Bundle.main.bus.identifier + pasteBoardItems["status_version"] = "14" + pasteBoardItems["sdkv"] = "3.5.1_lite" + pasteBoardItems["status_machine"] = "iPhone12,1" + pasteBoardItems["status_os"] = "14.3" + pasteBoardItems["client_id"] = appID.trimmingCharacters(in: .letters) + pasteBoardItems["refUniversallink"] = universalLink.absoluteString + + let pbItems = pasteBoardItems.compactMapValues { $0 } + let data = NSKeyedArchiver.archivedData(withRootObject: pbItems) + + urlItems["pasteboard"] = data.base64EncodedString() + + urlItems["appsign_txid"] = txID + urlItems["bundleid"] = identifier + urlItems["sdkv"] = sdkVersion + urlItems["objectlocation"] = "url" + + var components = URLComponents() + + components.scheme = "https" + components.host = "qm.qq.com" + components.path = "/opensdkul/mqqOpensdkSSoLogin/SSoLogin/\(appID)" + + components.queryItems = urlItems.map { key, value in + URLQueryItem(name: key, value: value) + } + + guard let url = components.url else { + completionHandler(.failure(.invalidMessage)) + return + } + + guard UIApplication.shared.canOpenURL(url) else { + completionHandler(.failure(.unknown)) + return + } + + UIApplication.shared.open(url) { result in + if !result { + completionHandler(.failure(.unknown)) + } + } + } +} + +extension QQHandler: OpenURLHandlerType { + + public func openURL(_ url: URL) { + guard + let components = URLComponents(url: url, resolvingAgainstBaseURL: false) + else { return } + + switch components.host { + case "qzapp": + handleOauth(with: components) + default: + assertionFailure() + } + } +} + extension QQHandler: OpenUserActivityHandlerType { public func openUserActivity(_ userActivity: NSUserActivity) { @@ -409,8 +505,56 @@ extension QQHandler: OpenUserActivityHandlerType { default: shareCompletionHandler?(.failure(.unknown)) } + case "qzapp": + handleOauth(with: components) default: assertionFailure() } } + + private func handleOauth(with components: URLComponents) { + guard + let item = components.queryItems?.first(where: { $0.name == "pasteboard" }), + let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), + let infos = NSKeyedUnarchiver.unarchiveObject(with: itemData) as? [String: Any] + else { + assertionFailure() + return + } + + let isUserCancelled = infos["user_cancelled"] as? String + + switch isUserCancelled { + case "YES": + oauthCompletionHandler?(.failure(.userCancelled)) + case "NO": + let accessToken = infos["access_token"] as? String + let openID = infos["openid"] as? String + + let parameters = [ + OauthInfoKeys.accessToken: accessToken, + OauthInfoKeys.openID: openID, + ] + .bus + .compactMapContent() + + if !parameters.isEmpty { + oauthCompletionHandler?(.success(parameters)) + } else { + oauthCompletionHandler?(.failure(.unknown)) + } + default: + assertionFailure() + } + } +} + +extension QQHandler { + + public enum OauthInfoKeys { + + public static let accessToken = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qqHandler.accessToken") + + public static let openID = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qqHandler.openID") + } } From 9682ab4f7dd39698db1472ce546f409838aaa8dd Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:51:13 +0800 Subject: [PATCH 26/67] feat: add QQHandler --- NBus.podspec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NBus.podspec b/NBus.podspec index 2963d30..2cdf075 100644 --- a/NBus.podspec +++ b/NBus.podspec @@ -32,6 +32,12 @@ Pod::Spec.new do |s| ss.source_files = ["NBus/Classes/Handler/QQSDKHandler.swift"] end + s.subspec "QQHandler" do |ss| + ss.dependency "NBus/Core" + + ss.source_files = ["NBus/Classes/Handler/QQHandler.swift"] + end + s.subspec "WechatSDKHandler" do |ss| ss.dependency "NBus/Core" ss.dependency "NBus/WechatSDK" From 8583f826144fa693d507367250fcc2d65ca87081 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:51:24 +0800 Subject: [PATCH 27/67] feat: add BusHandlers --- NBus.podspec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NBus.podspec b/NBus.podspec index 2cdf075..b5d57af 100644 --- a/NBus.podspec +++ b/NBus.podspec @@ -14,6 +14,11 @@ Pod::Spec.new do |s| s.default_subspecs = "SDKHandlers" + s.subspec "BusHandlers" do |ss| + ss.dependency "NBus/QQHandler" + ss.dependency "NBus/SystemHandler" + end + s.subspec "SDKHandlers" do |ss| ss.dependency "NBus/QQSDKHandler" ss.dependency "NBus/WechatSDKHandler" From 9b7559c470d576f319153ff1d6e7a005b9689dd5 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:51:41 +0800 Subject: [PATCH 28/67] feat: use BusHandlers and SDKHandlers --- Example/Podfile | 3 ++- Example/Podfile.lock | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Example/Podfile b/Example/Podfile index fb298cc..712638c 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -3,7 +3,8 @@ platform :ios, "10.0" use_frameworks! :linkage => :static target "BusMock" do - pod "NBus", :path => "../" + pod "NBus/BusHandlers", :path => "../" + pod "NBus/SDKHandlers", :path => "../" pod "PinLayout" pod "RxCocoa" diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 917ee79..030e898 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,7 +1,10 @@ PODS: - - NBus (0.7.0): - - NBus/SDKHandlers (= 0.7.0) + - NBus/BusHandlers (0.7.0): + - NBus/QQHandler + - NBus/SystemHandler - NBus/Core (0.7.0) + - NBus/QQHandler (0.7.0): + - NBus/Core - NBus/QQSDK (0.7.0) - NBus/QQSDKHandler (0.7.0): - NBus/Core @@ -32,7 +35,8 @@ PODS: - WoodPeckeriOS (1.2.9) DEPENDENCIES: - - NBus (from `../`) + - NBus/BusHandlers (from `../`) + - NBus/SDKHandlers (from `../`) - PinLayout - RxCocoa - SwiftTrace @@ -52,7 +56,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - NBus: 956e0711f202ced6ffe2b9eaccb8b696f9e87585 + NBus: 909effc8a33bd2e5e3549406dc8b718f028f1776 PinLayout: 0d96022e46e8b80468d819f182a393b97ca038da RxCocoa: 32065309a38d29b5b0db858819b5bf9ef038b601 RxRelay: d77f7d771495f43c556cbc43eebd1bb54d01e8e9 @@ -60,6 +64,6 @@ SPEC CHECKSUMS: SwiftTrace: affc6601a316add7c299a3916d9f43c286a583ef WoodPeckeriOS: f16864f7a78d5c6daa605591dd66690d466d95be -PODFILE CHECKSUM: 997337f6cf183fc4e4ba8e80d4eaa8ad4f55c321 +PODFILE CHECKSUM: 5bd2560c0821586df3f229f1739f98be39727940 COCOAPODS: 1.10.0 From d264c770dca706e15bed48be5ca96608419d3ccd Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:51:54 +0800 Subject: [PATCH 29/67] feat: use QQHandler --- Example/NBus/Model/AppState.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Example/NBus/Model/AppState.swift b/Example/NBus/Model/AppState.swift index 247b8cf..701e486 100644 --- a/Example/NBus/Model/AppState.swift +++ b/Example/NBus/Model/AppState.swift @@ -78,10 +78,16 @@ extension AppState { logger.debug("\(message)", file: file, function: function, line: line) } + let qqHandler = QQHandler( + appID: AppState.getAppID(for: Platforms.qq)!, + universalLink: AppState.getUniversalLink(for: Platforms.qq)! + ) + let qqItem = AppState.PlatformItem( platform: Platforms.qq, category: .sdk, handlers: [ + .bus: qqHandler, .sdk: qqSDKHandler, ], viewController: { PlatformViewController() } From fdc65a94d5e0a2e4b95a8b6268a42907fea32e65 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:54:16 +0800 Subject: [PATCH 30/67] fix: name --- NBus/Classes/Handler/QQHandler.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 8a38a4e..1c6b211 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -423,7 +423,7 @@ extension QQHandler: OpenUserActivityHandlerType { case universalLink.appendingPathComponent("\(identifier)/mqqsignapp").path: handleSignToken(with: components) case universalLink.appendingPathComponent("\(identifier)").path: - handleShare(with: components) + handleGeneral(with: components) default: assertionFailure() } @@ -471,7 +471,7 @@ extension QQHandler: OpenUserActivityHandlerType { } } - private func handleShare(with components: URLComponents) { + private func handleGeneral(with components: URLComponents) { let decoder = JSONDecoder() decoder.dataDecodingStrategy = .base64 From 994eeedbb653625278c6740571241ebe54c63f93 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Tue, 12 Jan 2021 23:56:05 +0800 Subject: [PATCH 31/67] refactor: handleShare --- NBus/Classes/Handler/QQHandler.swift | 34 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 1c6b211..f79d6ed 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -490,21 +490,7 @@ extension QQHandler: OpenUserActivityHandlerType { switch components.host { case "response_from_qq": - guard - let item = components.queryItems?.first(where: { $0.name == "error" }) - else { - assertionFailure() - return - } - - switch item.value { - case "0": - shareCompletionHandler?(.success(())) - case "-4": - shareCompletionHandler?(.failure(.userCancelled)) - default: - shareCompletionHandler?(.failure(.unknown)) - } + handleShare(with: components) case "qzapp": handleOauth(with: components) default: @@ -512,6 +498,24 @@ extension QQHandler: OpenUserActivityHandlerType { } } + private func handleShare(with components: URLComponents) { + guard + let item = components.queryItems?.first(where: { $0.name == "error" }) + else { + assertionFailure() + return + } + + switch item.value { + case "0": + shareCompletionHandler?(.success(())) + case "-4": + shareCompletionHandler?(.failure(.userCancelled)) + default: + shareCompletionHandler?(.failure(.unknown)) + } + } + private func handleOauth(with components: URLComponents) { guard let item = components.queryItems?.first(where: { $0.name == "pasteboard" }), From b720cf34fb90f1c303e177897bba17cdc3609d6c Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 10:49:12 +0800 Subject: [PATCH 32/67] fix: path --- NBus/Classes/Handler/QQHandler.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index f79d6ed..91879ab 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -402,7 +402,7 @@ extension QQHandler: OpenURLHandlerType { else { return } switch components.host { - case "qzapp": + case "qzapp" where components.path == "/mqzone/0": handleOauth(with: components) default: assertionFailure() From e24db6525cca71b868c1cba7f87d207a9b841042 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 10:49:33 +0800 Subject: [PATCH 33/67] chore: update PinLayout and RxSwift --- Example/Podfile.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 030e898..abee88a 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -24,13 +24,13 @@ PODS: - NBus/WeiboSDKHandler (0.7.0): - NBus/Core - NBus/WeiboSDK - - PinLayout (1.9.2) - - RxCocoa (5.1.1): - - RxRelay (~> 5) - - RxSwift (~> 5) - - RxRelay (5.1.1): - - RxSwift (~> 5) - - RxSwift (5.1.1) + - PinLayout (1.9.3) + - RxCocoa (6.0.0): + - RxRelay (= 6.0.0) + - RxSwift (= 6.0.0) + - RxRelay (6.0.0): + - RxSwift (= 6.0.0) + - RxSwift (6.0.0) - SwiftTrace (6.6.0) - WoodPeckeriOS (1.2.9) @@ -57,10 +57,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: NBus: 909effc8a33bd2e5e3549406dc8b718f028f1776 - PinLayout: 0d96022e46e8b80468d819f182a393b97ca038da - RxCocoa: 32065309a38d29b5b0db858819b5bf9ef038b601 - RxRelay: d77f7d771495f43c556cbc43eebd1bb54d01e8e9 - RxSwift: 81470a2074fa8780320ea5fe4102807cb7118178 + PinLayout: 4d8733121f8687edcc8f00c19bf1379d12808767 + RxCocoa: 3f79328fafa3645b34600f37c31e64c73ae3a80e + RxRelay: 8d593be109c06ea850df027351beba614b012ffb + RxSwift: c14e798c59b9f6e9a2df8fd235602e85cc044295 SwiftTrace: affc6601a316add7c299a3916d9f43c286a583ef WoodPeckeriOS: f16864f7a78d5c6daa605591dd66690d466d95be From 8f2467c154c5bd014b45abefeeb655f1d04aa54c Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 11:08:51 +0800 Subject: [PATCH 34/67] feat: DisposeBag --- Example/NBus/AppDelegate.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index 3e21f19..c0a350e 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -18,6 +18,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? + private let disposeBag = DisposeBag() + func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? @@ -149,11 +151,11 @@ extension AppDelegate { SwiftTrace.traceClasses(matchingPattern: "^QQ") SwiftTrace.traceClasses(matchingPattern: "^Tencent") - _ = pasteboardItems() + pasteboardItems() .delay(.seconds(1), scheduler: MainScheduler.instance) - .takeUntil(rx.deallocating) .bind(onNext: { items in logger.debug("\(items)") }) + .disposed(by: disposeBag) } } From 8ea2dfe0ae2aef13eed735f89480de1f4a5bb594 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 11:24:48 +0800 Subject: [PATCH 35/67] feat: url --- Example/NBus/AppDelegate.swift | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index c0a350e..1a9a248 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -108,6 +108,22 @@ extension AppDelegate { } .distinctUntilChanged() } + + private func canOpenURL() -> Observable { + UIApplication.shared.rx + .methodInvoked(#selector(UIApplication.canOpenURL(_:))) + .compactMap { args in + args[0] as? URL + } + } + + private func openURL() -> Observable { + UIApplication.shared.rx + .methodInvoked(#selector(UIApplication.open(_:options:completionHandler:))) + .compactMap { args in + args[0] as? URL + } + } } extension AppDelegate { @@ -157,5 +173,17 @@ extension AppDelegate { logger.debug("\(items)") }) .disposed(by: disposeBag) + + canOpenURL() + .bind(onNext: { url in + logger.debug("\(url)") + }) + .disposed(by: disposeBag) + + openURL() + .bind(onNext: { url in + logger.debug("\(url)") + }) + .disposed(by: disposeBag) } } From d42d647ea5e8564203f7c81ca4776cfcbe08b3f5 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 11:25:09 +0800 Subject: [PATCH 36/67] feat: ignore --- Example/NBus/AppDelegate.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index 1a9a248..a6f7bc5 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -164,8 +164,8 @@ extension AppDelegate { extension AppDelegate { private func observeQQ() { - SwiftTrace.traceClasses(matchingPattern: "^QQ") - SwiftTrace.traceClasses(matchingPattern: "^Tencent") +// SwiftTrace.traceClasses(matchingPattern: "^QQ") +// SwiftTrace.traceClasses(matchingPattern: "^Tencent") pasteboardItems() .delay(.seconds(1), scheduler: MainScheduler.instance) From 33e6f57b04a8756d8ee116bc92cb5600605499bc Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 11:28:46 +0800 Subject: [PATCH 37/67] feat: observeSDK --- Example/NBus/AppDelegate.swift | 43 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index a6f7bc5..9665aec 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -126,6 +126,30 @@ extension AppDelegate { } } +extension AppDelegate { + + private func observeSDK() { + pasteboardItems() + .delay(.seconds(1), scheduler: MainScheduler.instance) + .bind(onNext: { items in + logger.debug("\(items)") + }) + .disposed(by: disposeBag) + + canOpenURL() + .bind(onNext: { url in + logger.debug("\(url)") + }) + .disposed(by: disposeBag) + + openURL() + .bind(onNext: { url in + logger.debug("\(url)") + }) + .disposed(by: disposeBag) + } +} + extension AppDelegate { private func clearKeychains() { @@ -167,23 +191,6 @@ extension AppDelegate { // SwiftTrace.traceClasses(matchingPattern: "^QQ") // SwiftTrace.traceClasses(matchingPattern: "^Tencent") - pasteboardItems() - .delay(.seconds(1), scheduler: MainScheduler.instance) - .bind(onNext: { items in - logger.debug("\(items)") - }) - .disposed(by: disposeBag) - - canOpenURL() - .bind(onNext: { url in - logger.debug("\(url)") - }) - .disposed(by: disposeBag) - - openURL() - .bind(onNext: { url in - logger.debug("\(url)") - }) - .disposed(by: disposeBag) + observeSDK() } } From 58cdbb08887b22b5953e64b824e7ebc1b7c4a6f5 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 11:30:35 +0800 Subject: [PATCH 38/67] feat: clearStorage --- Example/NBus/AppDelegate.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Example/NBus/AppDelegate.swift b/Example/NBus/AppDelegate.swift index 9665aec..be2b092 100644 --- a/Example/NBus/AppDelegate.swift +++ b/Example/NBus/AppDelegate.swift @@ -25,9 +25,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - clearKeychains() - clearPasteboard() - clearUserDefaults() + clearStorage() // observeQQ() @@ -185,6 +183,15 @@ extension AppDelegate { } } +extension AppDelegate { + + private func clearStorage() { + clearKeychains() + clearPasteboard() + clearUserDefaults() + } +} + extension AppDelegate { private func observeQQ() { From ca99a3b0e03dd0e4314554ca26d596cf0a4fbeea Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:29:50 +0800 Subject: [PATCH 39/67] feat: BusUserDefaults --- NBus/Classes/Core/Bus+Wrapper.swift | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/NBus/Classes/Core/Bus+Wrapper.swift b/NBus/Classes/Core/Bus+Wrapper.swift index 168076c..6837278 100644 --- a/NBus/Classes/Core/Bus+Wrapper.swift +++ b/NBus/Classes/Core/Bus+Wrapper.swift @@ -31,3 +31,34 @@ extension BusCompatible { set {} } } + +@propertyWrapper +public struct BusUserDefaults { + + public let userDefaults: UserDefaults + + public let key: String + + public var wrappedValue: T? { + get { userDefaults.object(forKey: key) as? T } + set { userDefaults.set(newValue, forKey: key) } + } + + public init( + key: String, + userDefaults: UserDefaults = .standard + ) { + self.key = key + self.userDefaults = userDefaults + } +} + +extension BusUserDefaults { + + public init( + key: U, + userDefaults: UserDefaults = .standard + ) where U: RawRepresentable, U.RawValue == String { + self.init(key: key.rawValue, userDefaults: userDefaults) + } +} From 1eba606f190ed4113ed7f0aa6711351e2a390e78 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:30:24 +0800 Subject: [PATCH 40/67] refactor: signToken --- NBus/Classes/Handler/QQHandler.swift | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 91879ab..94675b6 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -33,19 +33,9 @@ public class QQHandler { public let universalLink: URL private let sdkVersion = "3.5.1" - private var token: String? { - get { - let object = UserDefaults.standard - .object(forKey: "com.nuomi1.bus.qqHandler.token") - return object as? String - } - set { - if let token = newValue { - UserDefaults.standard - .set(token, forKey: "com.nuomi1.bus.qqHandler.token") - } - } - } + + @BusUserDefaults(key: ShareOptionKeys.signToken) + private var signToken: String? public init(appID: String, universalLink: URL) { self.appID = appID @@ -99,7 +89,7 @@ extension QQHandler: ShareHandlerType { urlItems["thirdAppDisplayName"] = displayName urlItems["version"] = "1" - if let token = token { + if let token = signToken { urlItems["appsign_token"] = token } @@ -444,7 +434,7 @@ extension QQHandler: OpenUserActivityHandlerType { return } - token = appSignToken + signToken = appSignToken var items: [String: String] = [:] @@ -553,6 +543,14 @@ extension QQHandler: OpenUserActivityHandlerType { } } +extension QQHandler { + + public enum ShareOptionKeys { + + public static let signToken = Bus.ShareOptionKey(rawValue: "com.nuomi1.bus.qqHandler.signToken") + } +} + extension QQHandler { public enum OauthInfoKeys { From eb9b492e0c435ab62c8dd597a93afc64d44836e8 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:30:37 +0800 Subject: [PATCH 41/67] fix: response_from_qq --- NBus/Classes/Handler/QQHandler.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 94675b6..34f313b 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -392,6 +392,8 @@ extension QQHandler: OpenURLHandlerType { else { return } switch components.host { + case "response_from_qq" where components.path == "": + handleShare(with: components) case "qzapp" where components.path == "/mqzone/0": handleOauth(with: components) default: From edcef3d6683332a3e6b41546680c98d30a61c835 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:32:41 +0800 Subject: [PATCH 42/67] refactor: handleSignToken --- NBus/Classes/Handler/QQHandler.swift | 87 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 34f313b..69857d7 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -421,48 +421,6 @@ extension QQHandler: OpenUserActivityHandlerType { } } - private func handleSignToken(with components: URLComponents) { - let decoder = JSONDecoder() - decoder.dataDecodingStrategy = .base64 - - guard - let item = components.queryItems?.first(where: { $0.name == "appsign_extrainfo" }), - let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), - let infos = try? decoder.decode([String: String].self, from: itemData), - let appSignRedirect = infos["appsign_redirect"], - let appSignToken = infos["appsign_token"], - var components = URLComponents(string: appSignRedirect) - else { - return - } - - signToken = appSignToken - - var items: [String: String] = [:] - - items["openredirect"] = "1" - items["appsign_token"] = appSignToken - - components.scheme = "https" - components.host = "qm.qq.com" - components.path = "/opensdkul/mqqapi/share/to_fri" - - components.queryItems?.append(contentsOf: items.map { key, value in - URLQueryItem(name: key, value: value) - }) - - guard - let url = components.url, - UIApplication.shared.canOpenURL(url) - else { return } - - UIApplication.shared.open(url) { [weak self] result in - if !result { - self?.shareCompletionHandler?(.failure(.unknown)) - } - } - } - private func handleGeneral(with components: URLComponents) { let decoder = JSONDecoder() decoder.dataDecodingStrategy = .base64 @@ -545,6 +503,51 @@ extension QQHandler: OpenUserActivityHandlerType { } } +extension QQHandler { + + private func handleSignToken(with components: URLComponents) { + let decoder = JSONDecoder() + decoder.dataDecodingStrategy = .base64 + + guard + let item = components.queryItems?.first(where: { $0.name == "appsign_extrainfo" }), + let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), + let infos = try? decoder.decode([String: String].self, from: itemData), + let appSignRedirect = infos["appsign_redirect"], + let appSignToken = infos["appsign_token"], + var components = URLComponents(string: appSignRedirect) + else { + return + } + + signToken = appSignToken + + var items: [String: String] = [:] + + items["openredirect"] = "1" + items["appsign_token"] = appSignToken + + components.scheme = "https" + components.host = "qm.qq.com" + components.path = "/opensdkul/mqqapi/share/to_fri" + + components.queryItems?.append(contentsOf: items.map { key, value in + URLQueryItem(name: key, value: value) + }) + + guard + let url = components.url, + UIApplication.shared.canOpenURL(url) + else { return } + + UIApplication.shared.open(url) { [weak self] result in + if !result { + self?.shareCompletionHandler?(.failure(.unknown)) + } + } + } +} + extension QQHandler { public enum ShareOptionKeys { From f608012e043c1b93ed75872e8c4cf0daf0bf1c07 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:34:45 +0800 Subject: [PATCH 43/67] refactor: handleActionInfo --- NBus/Classes/Handler/QQHandler.swift | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 69857d7..a043c17 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -415,34 +415,7 @@ extension QQHandler: OpenUserActivityHandlerType { case universalLink.appendingPathComponent("\(identifier)/mqqsignapp").path: handleSignToken(with: components) case universalLink.appendingPathComponent("\(identifier)").path: - handleGeneral(with: components) - default: - assertionFailure() - } - } - - private func handleGeneral(with components: URLComponents) { - let decoder = JSONDecoder() - decoder.dataDecodingStrategy = .base64 - - guard - let item = components.queryItems?.first(where: { $0.name == "sdkactioninfo" }), - let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), - let infos = try? decoder.decode([String: String].self, from: itemData) - else { return } - - var components = URLComponents() - - components.scheme = infos["sdk_action_sheme"] - components.host = infos["sdk_action_host"] - components.path = infos["sdk_action_path"] ?? "" - components.query = infos["sdk_action_query"] - - switch components.host { - case "response_from_qq": - handleShare(with: components) - case "qzapp": - handleOauth(with: components) + handleActionInfo(with: components) default: assertionFailure() } @@ -546,6 +519,33 @@ extension QQHandler { } } } + + private func handleActionInfo(with components: URLComponents) { + let decoder = JSONDecoder() + decoder.dataDecodingStrategy = .base64 + + guard + let item = components.queryItems?.first(where: { $0.name == "sdkactioninfo" }), + let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), + let infos = try? decoder.decode([String: String].self, from: itemData) + else { return } + + var components = URLComponents() + + components.scheme = infos["sdk_action_sheme"] + components.host = infos["sdk_action_host"] + components.path = infos["sdk_action_path"] ?? "" + components.query = infos["sdk_action_query"] + + switch components.host { + case "response_from_qq": + handleShare(with: components) + case "qzapp": + handleOauth(with: components) + default: + assertionFailure() + } + } } extension QQHandler { From f880a95420817ba380fc2e6a59ce85d0ebd2c86d Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:36:08 +0800 Subject: [PATCH 44/67] refactor: handleShare and handleOauth --- NBus/Classes/Handler/QQHandler.swift | 111 ++++++++++++++------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index a043c17..0420dd9 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -420,60 +420,6 @@ extension QQHandler: OpenUserActivityHandlerType { assertionFailure() } } - - private func handleShare(with components: URLComponents) { - guard - let item = components.queryItems?.first(where: { $0.name == "error" }) - else { - assertionFailure() - return - } - - switch item.value { - case "0": - shareCompletionHandler?(.success(())) - case "-4": - shareCompletionHandler?(.failure(.userCancelled)) - default: - shareCompletionHandler?(.failure(.unknown)) - } - } - - private func handleOauth(with components: URLComponents) { - guard - let item = components.queryItems?.first(where: { $0.name == "pasteboard" }), - let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), - let infos = NSKeyedUnarchiver.unarchiveObject(with: itemData) as? [String: Any] - else { - assertionFailure() - return - } - - let isUserCancelled = infos["user_cancelled"] as? String - - switch isUserCancelled { - case "YES": - oauthCompletionHandler?(.failure(.userCancelled)) - case "NO": - let accessToken = infos["access_token"] as? String - let openID = infos["openid"] as? String - - let parameters = [ - OauthInfoKeys.accessToken: accessToken, - OauthInfoKeys.openID: openID, - ] - .bus - .compactMapContent() - - if !parameters.isEmpty { - oauthCompletionHandler?(.success(parameters)) - } else { - oauthCompletionHandler?(.failure(.unknown)) - } - default: - assertionFailure() - } - } } extension QQHandler { @@ -548,6 +494,63 @@ extension QQHandler { } } +extension QQHandler { + + private func handleShare(with components: URLComponents) { + guard + let item = components.queryItems?.first(where: { $0.name == "error" }) + else { + assertionFailure() + return + } + + switch item.value { + case "0": + shareCompletionHandler?(.success(())) + case "-4": + shareCompletionHandler?(.failure(.userCancelled)) + default: + shareCompletionHandler?(.failure(.unknown)) + } + } + + private func handleOauth(with components: URLComponents) { + guard + let item = components.queryItems?.first(where: { $0.name == "pasteboard" }), + let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), + let infos = NSKeyedUnarchiver.unarchiveObject(with: itemData) as? [String: Any] + else { + assertionFailure() + return + } + + let isUserCancelled = infos["user_cancelled"] as? String + + switch isUserCancelled { + case "YES": + oauthCompletionHandler?(.failure(.userCancelled)) + case "NO": + let accessToken = infos["access_token"] as? String + let openID = infos["openid"] as? String + + let parameters = [ + OauthInfoKeys.accessToken: accessToken, + OauthInfoKeys.openID: openID, + ] + .bus + .compactMapContent() + + if !parameters.isEmpty { + oauthCompletionHandler?(.success(parameters)) + } else { + oauthCompletionHandler?(.failure(.unknown)) + } + default: + assertionFailure() + } + } +} + extension QQHandler { public enum ShareOptionKeys { From e0333fc37adafb0bbbddc73bc624a7e079e40b56 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 13:40:42 +0800 Subject: [PATCH 45/67] refactor: handleGeneral --- NBus/Classes/Handler/QQHandler.swift | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 0420dd9..7bb303f 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -391,14 +391,7 @@ extension QQHandler: OpenURLHandlerType { let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return } - switch components.host { - case "response_from_qq" where components.path == "": - handleShare(with: components) - case "qzapp" where components.path == "/mqzone/0": - handleOauth(with: components) - default: - assertionFailure() - } + handleGeneral(with: components) } } @@ -483,10 +476,14 @@ extension QQHandler { components.path = infos["sdk_action_path"] ?? "" components.query = infos["sdk_action_query"] + handleGeneral(with: components) + } + + private func handleGeneral(with components: URLComponents) { switch components.host { - case "response_from_qq": + case "response_from_qq" where components.path == "": handleShare(with: components) - case "qzapp": + case "qzapp" where components.path == "/mqzone/0": handleOauth(with: components) default: assertionFailure() From 71cf1f1d3c5e394a8f92eff7c85c36d9e39f25ca Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 14:11:32 +0800 Subject: [PATCH 46/67] refactor: OauthInfoKeys --- NBus/Classes/Core/Bus.swift | 13 +++++++++++++ NBus/Classes/Handler/QQHandler.swift | 4 ++-- NBus/Classes/Handler/QQSDKHandler.swift | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/NBus/Classes/Core/Bus.swift b/NBus/Classes/Core/Bus.swift index a790570..9f6912e 100644 --- a/NBus/Classes/Core/Bus.swift +++ b/NBus/Classes/Core/Bus.swift @@ -139,3 +139,16 @@ extension Bus { return true } } + +extension Bus { + + enum OauthInfoKeys { + + enum QQ { + + static let accessToken = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qq.accessToken") + + static let openID = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qq.openID") + } + } +} diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 7bb303f..52a9dfc 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -560,8 +560,8 @@ extension QQHandler { public enum OauthInfoKeys { - public static let accessToken = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qqHandler.accessToken") + public static let accessToken = Bus.OauthInfoKeys.QQ.accessToken - public static let openID = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qqHandler.openID") + public static let openID = Bus.OauthInfoKeys.QQ.openID } } diff --git a/NBus/Classes/Handler/QQSDKHandler.swift b/NBus/Classes/Handler/QQSDKHandler.swift index 3960d71..c64a6fb 100644 --- a/NBus/Classes/Handler/QQSDKHandler.swift +++ b/NBus/Classes/Handler/QQSDKHandler.swift @@ -285,9 +285,9 @@ extension QQSDKHandler { public enum OauthInfoKeys { - public static let accessToken = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qqSDKHandler.accessToken") + public static let accessToken = Bus.OauthInfoKeys.QQ.accessToken - public static let openID = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.qqSDKHandler.openID") + public static let openID = Bus.OauthInfoKeys.QQ.openID } } From cbe9f5c727f86098113c93109c951ab533acd250 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 20:30:52 +0800 Subject: [PATCH 47/67] feat: base64EncodedString --- NBus/Classes/Core/Bus+Helper.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NBus/Classes/Core/Bus+Helper.swift b/NBus/Classes/Core/Bus+Helper.swift index 89bc245..1d11798 100644 --- a/NBus/Classes/Core/Bus+Helper.swift +++ b/NBus/Classes/Core/Bus+Helper.swift @@ -23,6 +23,15 @@ extension BusWrapper where Base == [Bus.OauthInfoKey: String?] { } } +extension String: BusCompatible {} + +extension BusWrapper where Base == String { + + var base64EncodedString: String? { + base.data(using: .utf8)?.base64EncodedString() + } +} + extension NSObject: BusCompatible {} extension BusWrapper where Base: Bundle { From 2ad2757ed224c2040fd8d5a1f4d919acb8dfe77d Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 20:31:12 +0800 Subject: [PATCH 48/67] refactor: parameters --- NBus/Classes/Handler/QQHandler.swift | 140 +++++++++++++++------------ 1 file changed, 80 insertions(+), 60 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 52a9dfc..1dec3fb 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -32,8 +32,6 @@ public class QQHandler { public let appID: String public let universalLink: URL - private let sdkVersion = "3.5.1" - @BusUserDefaults(key: ShareOptionKeys.signToken) private var signToken: String? @@ -62,10 +60,9 @@ extension QQHandler: ShareHandlerType { } guard - let identifier = identifier(), - let displayName = displayName(), + let identifierEncoded = identifier?.bus.base64EncodedString, let cflag = cflag(endpoint, message.identifier), - let txID = txID() + let displayNameEncoded = displayName?.bus.base64EncodedString else { assertionFailure() completionHandler(.failure(.invalidMessage)) @@ -78,31 +75,31 @@ extension QQHandler: ShareHandlerType { var pasteBoardItems: [String: Any?] = [:] urlItems["appsign_txid"] = txID - urlItems["bundleid"] = identifier + urlItems["bundleid"] = identifierEncoded urlItems["callback_name"] = txID urlItems["callback_type"] = "scheme" urlItems["cflag"] = cflag urlItems["generalpastboard"] = "1" - urlItems["sdkv"] = sdkVersion + urlItems["sdkv"] = sdkShortVersion urlItems["shareType"] = "0" urlItems["src_type"] = "app" - urlItems["thirdAppDisplayName"] = displayName + urlItems["thirdAppDisplayName"] = displayNameEncoded urlItems["version"] = "1" - if let token = signToken { - urlItems["appsign_token"] = token + if let signToken = signToken { + urlItems["appsign_token"] = signToken } - if let oldText = UIPasteboard.general.bus.oldText { + if let oldText = oldText { pasteBoardItems["pasted_string"] = oldText } if let message = message as? MediaMessageType { - if let title = message.title?.data(using: .utf8)?.base64EncodedString() { + if let title = message.title?.bus.base64EncodedString { urlItems["title"] = title } - if let description = message.description?.data(using: .utf8)?.base64EncodedString() { + if let description = message.description?.bus.base64EncodedString { urlItems["description"] = description } } @@ -110,7 +107,7 @@ extension QQHandler: ShareHandlerType { switch message { case let message as TextMessage: guard - let text = message.text.data(using: .utf8)?.base64EncodedString() + let text = message.text.bus.base64EncodedString else { completionHandler(.failure(.invalidMessage)) return @@ -127,7 +124,7 @@ extension QQHandler: ShareHandlerType { case let message as AudioMessage: guard - let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + let url = message.link.absoluteString.bus.base64EncodedString else { completionHandler(.failure(.invalidMessage)) return @@ -139,7 +136,7 @@ extension QQHandler: ShareHandlerType { case let message as VideoMessage: guard - let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + let url = message.link.absoluteString.bus.base64EncodedString else { completionHandler(.failure(.invalidMessage)) return @@ -151,7 +148,7 @@ extension QQHandler: ShareHandlerType { case let message as WebPageMessage: guard - let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + let url = message.link.absoluteString.bus.base64EncodedString else { completionHandler(.failure(.invalidMessage)) return @@ -164,8 +161,7 @@ extension QQHandler: ShareHandlerType { case let message as FileMessage: urlItems["file_type"] = "localFile" - if - let fileName = message.fullName?.data(using: .utf8)?.base64EncodedString() { + if let fileName = message.fullName?.bus.base64EncodedString { urlItems["fileName"] = fileName } @@ -173,8 +169,8 @@ extension QQHandler: ShareHandlerType { case let message as MiniProgramMessage: guard - let path = message.path.data(using: .utf8)?.base64EncodedString(), - let url = message.link.absoluteString.data(using: .utf8)?.base64EncodedString() + let path = message.path.bus.base64EncodedString, + let url = message.link.absoluteString.bus.base64EncodedString else { completionHandler(.failure(.invalidMessage)) return @@ -199,12 +195,10 @@ extension QQHandler: ShareHandlerType { let pbItems = pasteBoardItems.compactMapValues { $0 } if !pbItems.isEmpty { - urlItems["objectlocation"] = "pasteboard" - - let data = NSKeyedArchiver.archivedData(withRootObject: pbItems) + let pbData = NSKeyedArchiver.archivedData(withRootObject: pbItems) UIPasteboard.general.setData( - data, + pbData, forPasteboardType: "com.tencent.mqq.api.apiLargeData" ) } @@ -251,20 +245,32 @@ extension QQHandler: ShareHandlerType { } } - private func identifier() -> String? { - let identifier = Bundle.main.bus.identifier - return identifier?.data(using: .utf8)?.base64EncodedString() + private var appNumber: String { + appID.trimmingCharacters(in: .letters) + } + + private var txID: String { + "QQ\(String(format: "%08llX", (appNumber as NSString).longLongValue))" + } + + private var identifier: String? { + Bundle.main.bus.identifier + } + + private var displayName: String? { + Bundle.main.bus.displayName + } + + private var sdkShortVersion: String { + "3.5.1" } - private func displayName() -> String? { - let displayName = Bundle.main.bus.displayName - return displayName?.data(using: .utf8)?.base64EncodedString() + private var sdkVersion: String { + "3.5.1_lite" } - private func txID() -> String? { - let number = appID.trimmingCharacters(in: .letters) - let txID = String(format: "%08llX", (number as NSString).longLongValue) - return "QQ\(txID)" + private var oldText: String? { + UIPasteboard.general.bus.oldText } private func cflag(_ endpoint: Endpoint, _ message: Message) -> String? { @@ -319,8 +325,9 @@ extension QQHandler: OauthHandlerType { } guard - let identifier = identifier(), - let txID = txID() + let displayName = displayName, + let identifier = identifier, + let identifierEncoded = identifier.bus.base64EncodedString else { assertionFailure() completionHandler(.failure(.invalidMessage)) @@ -332,29 +339,27 @@ extension QQHandler: OauthHandlerType { var urlItems: [String: String] = [:] var pasteBoardItems: [String: Any?] = [:] - pasteBoardItems["app_id"] = appID.trimmingCharacters(in: .letters) - pasteBoardItems["sdkp"] = "i" + pasteBoardItems["app_id"] = appNumber + pasteBoardItems["app_name"] = displayName + pasteBoardItems["bundleid"] = identifier + pasteBoardItems["client_id"] = appNumber + pasteBoardItems["refUniversallink"] = universalLink.absoluteString pasteBoardItems["response_type"] = "token" - pasteBoardItems["app_name"] = Bundle.main.bus.displayName - pasteBoardItems["appsign_token"] = "" pasteBoardItems["scope"] = "get_user_info" - pasteBoardItems["bundleid"] = Bundle.main.bus.identifier - pasteBoardItems["status_version"] = "14" - pasteBoardItems["sdkv"] = "3.5.1_lite" - pasteBoardItems["status_machine"] = "iPhone12,1" - pasteBoardItems["status_os"] = "14.3" - pasteBoardItems["client_id"] = appID.trimmingCharacters(in: .letters) - pasteBoardItems["refUniversallink"] = universalLink.absoluteString + pasteBoardItems["sdkp"] = "i" + pasteBoardItems["sdkv"] = sdkVersion + pasteBoardItems["status_machine"] = UIDevice.current.model + pasteBoardItems["status_os"] = UIDevice.current.systemVersion + pasteBoardItems["status_version"] = UIDevice.current.systemVersion let pbItems = pasteBoardItems.compactMapValues { $0 } - let data = NSKeyedArchiver.archivedData(withRootObject: pbItems) - - urlItems["pasteboard"] = data.base64EncodedString() + let pbData = NSKeyedArchiver.archivedData(withRootObject: pbItems) urlItems["appsign_txid"] = txID - urlItems["bundleid"] = identifier - urlItems["sdkv"] = sdkVersion + urlItems["bundleid"] = identifierEncoded urlItems["objectlocation"] = "url" + urlItems["pasteboard"] = pbData.base64EncodedString() + urlItems["sdkv"] = sdkShortVersion var components = URLComponents() @@ -389,7 +394,10 @@ extension QQHandler: OpenURLHandlerType { public func openURL(_ url: URL) { guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) - else { return } + else { + assertionFailure() + return + } handleGeneral(with: components) } @@ -402,7 +410,10 @@ extension QQHandler: OpenUserActivityHandlerType { let url = userActivity.webpageURL, let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let identifier = Bundle.main.bus.identifier - else { return } + else { + assertionFailure() + return + } switch components.path { case universalLink.appendingPathComponent("\(identifier)/mqqsignapp").path: @@ -429,6 +440,7 @@ extension QQHandler { let appSignToken = infos["appsign_token"], var components = URLComponents(string: appSignRedirect) else { + assertionFailure() return } @@ -447,10 +459,15 @@ extension QQHandler { URLQueryItem(name: key, value: value) }) - guard - let url = components.url, - UIApplication.shared.canOpenURL(url) - else { return } + guard let url = components.url else { + shareCompletionHandler?(.failure(.invalidMessage)) + return + } + + guard UIApplication.shared.canOpenURL(url) else { + shareCompletionHandler?(.failure(.unknown)) + return + } UIApplication.shared.open(url) { [weak self] result in if !result { @@ -467,7 +484,10 @@ extension QQHandler { let item = components.queryItems?.first(where: { $0.name == "sdkactioninfo" }), let itemData = item.value.flatMap({ Data(base64Encoded: $0) }), let infos = try? decoder.decode([String: String].self, from: itemData) - else { return } + else { + assertionFailure() + return + } var components = URLComponents() From b075b5c6c85d0a0a1eb67973c9718eac0fbddf31 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 20:37:35 +0800 Subject: [PATCH 49/67] fix: pasteboard --- NBus/Classes/Handler/QQHandler.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 1dec3fb..e1683e3 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -203,6 +203,10 @@ extension QQHandler: ShareHandlerType { ) } + if pbItems.contains(where: { $0.key == "file_data" }) { + urlItems["objectlocation"] = "pasteboard" + } + var components = URLComponents() components.scheme = "https" From 1c8bd7ff8b2b06843a3eb4fad839d4a6ca3d6dc5 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 20:51:27 +0800 Subject: [PATCH 50/67] feat: flashURL --- NBus/Classes/Handler/QQHandler.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index e1683e3..0d1da56 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -134,6 +134,10 @@ extension QQHandler: ShareHandlerType { urlItems["url"] = url + if let flashURL = message.dataLink?.absoluteString.bus.base64EncodedString { + urlItems["flashurl"] = flashURL + } + case let message as VideoMessage: guard let url = message.link.absoluteString.bus.base64EncodedString From 5f491484f71abd926518e70da8d7177422e93a50 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 21:04:37 +0800 Subject: [PATCH 51/67] feat: shareType --- NBus/Classes/Handler/QQHandler.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 0d1da56..b161a6d 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -62,6 +62,7 @@ extension QQHandler: ShareHandlerType { guard let identifierEncoded = identifier?.bus.base64EncodedString, let cflag = cflag(endpoint, message.identifier), + let shareType = shareType(endpoint, message.identifier), let displayNameEncoded = displayName?.bus.base64EncodedString else { assertionFailure() @@ -81,7 +82,7 @@ extension QQHandler: ShareHandlerType { urlItems["cflag"] = cflag urlItems["generalpastboard"] = "1" urlItems["sdkv"] = sdkShortVersion - urlItems["shareType"] = "0" + urlItems["shareType"] = shareType urlItems["src_type"] = "app" urlItems["thirdAppDisplayName"] = displayNameEncoded urlItems["version"] = "1" @@ -319,6 +320,21 @@ extension QQHandler: ShareHandlerType { return "\(result)" } + + private func shareType(_ endpoint: Endpoint, _ message: Message) -> String? { + switch endpoint { + case Endpoints.QQ.friend: + return "0" + case Endpoints.QQ.timeline: + return ![ + Messages.text, + Messages.image, + ].contains(message) + ? "1" : "0" + default: + return nil + } + } } extension QQHandler: OauthHandlerType { From ca407978a31c16de66f3eccd2f41411d7acb38f9 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 21:18:34 +0800 Subject: [PATCH 52/67] refactor: error --- NBus/Classes/Core/Bus+Error.swift | 2 +- NBus/Classes/Handler/QQHandler.swift | 20 ++++++++++---------- NBus/Classes/Handler/QQSDKHandler.swift | 2 +- NBus/Classes/Handler/WechatSDKHandler.swift | 2 +- NBus/Classes/Handler/WeiboSDKHandler.swift | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/NBus/Classes/Core/Bus+Error.swift b/NBus/Classes/Core/Bus+Error.swift index 522c75e..3f49e57 100644 --- a/NBus/Classes/Core/Bus+Error.swift +++ b/NBus/Classes/Core/Bus+Error.swift @@ -18,7 +18,7 @@ extension Bus { case unsupportedMessage - case invalidMessage + case invalidParameter case userCancelled diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index b161a6d..27c2253 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -66,7 +66,7 @@ extension QQHandler: ShareHandlerType { let displayNameEncoded = displayName?.bus.base64EncodedString else { assertionFailure() - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -110,7 +110,7 @@ extension QQHandler: ShareHandlerType { guard let text = message.text.bus.base64EncodedString else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -127,7 +127,7 @@ extension QQHandler: ShareHandlerType { guard let url = message.link.absoluteString.bus.base64EncodedString else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -143,7 +143,7 @@ extension QQHandler: ShareHandlerType { guard let url = message.link.absoluteString.bus.base64EncodedString else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -155,7 +155,7 @@ extension QQHandler: ShareHandlerType { guard let url = message.link.absoluteString.bus.base64EncodedString else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -177,7 +177,7 @@ extension QQHandler: ShareHandlerType { let path = message.path.bus.base64EncodedString, let url = message.link.absoluteString.bus.base64EncodedString else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -223,7 +223,7 @@ extension QQHandler: ShareHandlerType { } guard let url = components.url else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -354,7 +354,7 @@ extension QQHandler: OauthHandlerType { let identifierEncoded = identifier.bus.base64EncodedString else { assertionFailure() - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -396,7 +396,7 @@ extension QQHandler: OauthHandlerType { } guard let url = components.url else { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) return } @@ -484,7 +484,7 @@ extension QQHandler { }) guard let url = components.url else { - shareCompletionHandler?(.failure(.invalidMessage)) + shareCompletionHandler?(.failure(.invalidParameter)) return } diff --git a/NBus/Classes/Handler/QQSDKHandler.swift b/NBus/Classes/Handler/QQSDKHandler.swift index c64a6fb..20d93b7 100644 --- a/NBus/Classes/Handler/QQSDKHandler.swift +++ b/NBus/Classes/Handler/QQSDKHandler.swift @@ -192,7 +192,7 @@ extension QQSDKHandler: ShareHandlerType { case .EQQAPISENDSUCESS: break case .EQQAPIMESSAGECONTENTINVALID: - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.invalidParameter)) default: completionHandler(.failure(.unknown)) } diff --git a/NBus/Classes/Handler/WechatSDKHandler.swift b/NBus/Classes/Handler/WechatSDKHandler.swift index 4b1011c..2959d5a 100644 --- a/NBus/Classes/Handler/WechatSDKHandler.swift +++ b/NBus/Classes/Handler/WechatSDKHandler.swift @@ -147,7 +147,7 @@ extension WechatSDKHandler: ShareHandlerType { WXApi.send(request) { result in if !result { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.unknown)) } } } diff --git a/NBus/Classes/Handler/WeiboSDKHandler.swift b/NBus/Classes/Handler/WeiboSDKHandler.swift index 7dc7dfc..b07b990 100644 --- a/NBus/Classes/Handler/WeiboSDKHandler.swift +++ b/NBus/Classes/Handler/WeiboSDKHandler.swift @@ -107,7 +107,7 @@ extension WeiboSDKHandler: ShareHandlerType { WeiboSDK.send(request) { result in if !result { - completionHandler(.failure(.invalidMessage)) + completionHandler(.failure(.unknown)) } } } From a275da784cab1e52515f215272c7849dbeaa3168 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 21:28:57 +0800 Subject: [PATCH 53/67] refactor: wechatMiniProgram --- Example/NBus/Model/MediaSource.swift | 2 +- Example/NBus/View/PlatformViewController+Share.swift | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Example/NBus/Model/MediaSource.swift b/Example/NBus/Model/MediaSource.swift index 3482ac7..4a3ca2b 100644 --- a/Example/NBus/Model/MediaSource.swift +++ b/Example/NBus/Model/MediaSource.swift @@ -95,7 +95,7 @@ enum MediaSource { ) }() - static let miniProgram: MessageType = { + static let wechatMiniProgram: MessageType = { let path = "/pages/community/topics/id?id=565" let url = URL(string: "https://www.apple.com.cn/iphone/")! diff --git a/Example/NBus/View/PlatformViewController+Share.swift b/Example/NBus/View/PlatformViewController+Share.swift index 88b4e10..3b602c3 100644 --- a/Example/NBus/View/PlatformViewController+Share.swift +++ b/Example/NBus/View/PlatformViewController+Share.swift @@ -221,7 +221,12 @@ extension PlatformViewController.ShareView { } private func didTapMiniProgramButton() { - share(MediaSource.miniProgram, in: miniProgramButton) + switch viewModel?.platform.value { + case Platforms.wechat: + share(MediaSource.wechatMiniProgram, in: miniProgramButton) + default: + share(MediaSource.wechatMiniProgram, in: miniProgramButton) + } } } From 91d375bbc8d93c9270477eb7e8f3aa328f0c4ade Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 21:44:11 +0800 Subject: [PATCH 54/67] feat: qqMiniProgram --- Example/NBus/Model/MediaSource.swift | 14 ++++++++++++++ .../NBus/View/PlatformViewController+Share.swift | 10 ++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Example/NBus/Model/MediaSource.swift b/Example/NBus/Model/MediaSource.swift index 4a3ca2b..a85b1d6 100644 --- a/Example/NBus/Model/MediaSource.swift +++ b/Example/NBus/Model/MediaSource.swift @@ -95,6 +95,20 @@ enum MediaSource { ) }() + static let qqMiniProgram: MessageType = { + let path = "/pages/component/pages/launchApp813/launchApp813?a=aaa&b=bbb&c=ccc" + let url = URL(string: "https://www.apple.com.cn/iphone/")! + + let miniProgramID = AppState.getMiniProgramID(for: Platforms.qq)! + + return Messages.miniProgram( + miniProgramID: miniProgramID, + path: path, + link: url, + miniProgramType: .release + ) + }() + static let wechatMiniProgram: MessageType = { let path = "/pages/community/topics/id?id=565" let url = URL(string: "https://www.apple.com.cn/iphone/")! diff --git a/Example/NBus/View/PlatformViewController+Share.swift b/Example/NBus/View/PlatformViewController+Share.swift index 3b602c3..ad8826e 100644 --- a/Example/NBus/View/PlatformViewController+Share.swift +++ b/Example/NBus/View/PlatformViewController+Share.swift @@ -221,12 +221,18 @@ extension PlatformViewController.ShareView { } private func didTapMiniProgramButton() { + let message: MessageType + switch viewModel?.platform.value { case Platforms.wechat: - share(MediaSource.wechatMiniProgram, in: miniProgramButton) + message = MediaSource.wechatMiniProgram + case Platforms.qq: + message = MediaSource.qqMiniProgram default: - share(MediaSource.wechatMiniProgram, in: miniProgramButton) + message = MediaSource.wechatMiniProgram } + + share(message, in: miniProgramButton) } } From cf5f43a3169d4b9d902987c57e858baf575d68db Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 21:45:19 +0800 Subject: [PATCH 55/67] feat: QQ mini program info --- Example/NBus/Info.plist | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Example/NBus/Info.plist b/Example/NBus/Info.plist index 0669614..750dbd4 100644 --- a/Example/NBus/Info.plist +++ b/Example/NBus/Info.plist @@ -4,6 +4,12 @@ BMMiniProgramIDTypes + + BMMiniProgramID + ${QQ_MINIPROGRAMID} + BMPlatform + QQ + BMMiniProgramID ${WECHAT_MINIPROGRAMID} From 9a454830e8e6c1b94278c517da5c05966128334a Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 21:46:44 +0800 Subject: [PATCH 56/67] feat: QQ MID --- Example/NBus/Config.xcconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Example/NBus/Config.xcconfig b/Example/NBus/Config.xcconfig index 5a86090..106ce08 100644 --- a/Example/NBus/Config.xcconfig +++ b/Example/NBus/Config.xcconfig @@ -13,6 +13,7 @@ SIMPLE_SLASH = / DOMAIN = www.nuomi1.com QQ_ID = 123456 +QQ_MID = 123456 WECHAT_ID = 123456 WECHAT_MID = 123456 WEIBO_ID = 123456 @@ -21,6 +22,7 @@ ASSOCIATED_DOMAIN = applinks:$(DOMAIN) DEVELOPMENT_TEAM = BUSMOCK PRODUCT_BUNDLE_IDENTIFIER = com.nuomi1.bus.mock QQ_APPID = tencent$(QQ_ID) +QQ_MINIPROGRAMID = $(QQ_MID) QQ_UNIVERSALLINK = https:$(SIMPLE_SLASH)/$(DOMAIN)/qq_conn/$(QQ_ID)/ WECHAT_APPID = wx$(WECHAT_ID) WECHAT_MINIPROGRAMID = gh_$(WECHAT_MID) From bc4aa312a522ca6b164d96831b777587dba9efc8 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 23:33:11 +0800 Subject: [PATCH 57/67] feat: thumbnail --- Example/NBus/Model/MediaSource.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Example/NBus/Model/MediaSource.swift b/Example/NBus/Model/MediaSource.swift index a85b1d6..02a5dc9 100644 --- a/Example/NBus/Model/MediaSource.swift +++ b/Example/NBus/Model/MediaSource.swift @@ -33,8 +33,12 @@ enum MediaSource { // https://giphy.com/gifs/bus-J1ZajKJKzD0PK let dataAsset = NSDataAsset(name: "giphy-J1ZajKJKzD0PK")! let data = dataAsset.data + let thumbnail = UIImage(data: data)?.jpegData(compressionQuality: 0.2) - return Messages.image(data: data) + return Messages.image( + data: data, + thumbnail: thumbnail + ) }() static let audio: MessageType = { From 43133f953fc572575037ba5fbfc36cf305dc04f6 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 13 Jan 2021 23:34:00 +0800 Subject: [PATCH 58/67] feat: thumbnail --- NBus/Classes/Handler/QQHandler.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 27c2253..6f9beb1 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -103,6 +103,10 @@ extension QQHandler: ShareHandlerType { if let description = message.description?.bus.base64EncodedString { urlItems["description"] = description } + + if let thumbnail = message.thumbnail { + pasteBoardItems["previewimagedata"] = thumbnail + } } switch message { @@ -185,6 +189,10 @@ extension QQHandler: ShareHandlerType { urlItems["url"] = url + if let thumbnail = message.thumbnail { + pasteBoardItems["previewimagedata"] = thumbnail + } + urlItems["mini_appid"] = message.miniProgramID urlItems["mini_path"] = path urlItems["mini_weburl"] = url From a7fbfc148d79433a2e41244c490b5229560ee840 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Fri, 15 Jan 2021 12:48:12 +0800 Subject: [PATCH 59/67] fix: force Universal Link --- NBus/Classes/Handler/QQHandler.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 6f9beb1..1729b5c 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -240,7 +240,7 @@ extension QQHandler: ShareHandlerType { return } - UIApplication.shared.open(url) { result in + UIApplication.shared.open(url, options: [.universalLinksOnly: true]) { result in if !result { completionHandler(.failure(.unknown)) } @@ -413,7 +413,7 @@ extension QQHandler: OauthHandlerType { return } - UIApplication.shared.open(url) { result in + UIApplication.shared.open(url, options: [.universalLinksOnly: true]) { result in if !result { completionHandler(.failure(.unknown)) } @@ -501,7 +501,7 @@ extension QQHandler { return } - UIApplication.shared.open(url) { [weak self] result in + UIApplication.shared.open(url, options: [.universalLinksOnly: true]) { [weak self] result in if !result { self?.shareCompletionHandler?(.failure(.unknown)) } From fe7e486118fd7543b9065480480b1cdae32a7557 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:45:36 +0800 Subject: [PATCH 60/67] fix: use fileName --- Example/NBus/Model/MediaSource.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/NBus/Model/MediaSource.swift b/Example/NBus/Model/MediaSource.swift index 02a5dc9..3899120 100644 --- a/Example/NBus/Model/MediaSource.swift +++ b/Example/NBus/Model/MediaSource.swift @@ -90,12 +90,12 @@ enum MediaSource { let dataAsset = NSDataAsset(name: "giphy-J1ZajKJKzD0PK")! let data = dataAsset.data - let title = "J1ZajKJKzD0PK" + let fileName = "J1ZajKJKzD0PK" return Messages.file( data: data, fileExtension: "gif", - title: title + fileName: fileName ) }() From 2906a4ab5ea87952da54ffb3ef2c6b22df644381 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:46:58 +0800 Subject: [PATCH 61/67] feat: machine --- NBus/Classes/Core/Bus+Helper.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/NBus/Classes/Core/Bus+Helper.swift b/NBus/Classes/Core/Bus+Helper.swift index 1d11798..422a56a 100644 --- a/NBus/Classes/Core/Bus+Helper.swift +++ b/NBus/Classes/Core/Bus+Helper.swift @@ -62,6 +62,25 @@ extension BusWrapper where Base: Bundle { } } +extension BusWrapper where Base: UIDevice { + + private var systemInfo: utsname { + var systemInfo = utsname() + uname(&systemInfo) + return systemInfo + } + + private func toString(from mirror: Mirror) -> String { + let cString = mirror.children.compactMap { $1 as? Int8 } + return String(cString: cString) + } + + public var machine: String { + let mirror = Mirror(reflecting: systemInfo.machine) + return toString(from: mirror) + } +} + extension BusWrapper where Base: UIPasteboard { public var oldText: String? { From d765d7f3d38ca0dd35b98fd1c575662e5d7c6394 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:47:43 +0800 Subject: [PATCH 62/67] feat: use get property --- NBus/Classes/Handler/QQHandler.swift | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/NBus/Classes/Handler/QQHandler.swift b/NBus/Classes/Handler/QQHandler.swift index 1729b5c..953ba00 100644 --- a/NBus/Classes/Handler/QQHandler.swift +++ b/NBus/Classes/Handler/QQHandler.swift @@ -380,9 +380,9 @@ extension QQHandler: OauthHandlerType { pasteBoardItems["scope"] = "get_user_info" pasteBoardItems["sdkp"] = "i" pasteBoardItems["sdkv"] = sdkVersion - pasteBoardItems["status_machine"] = UIDevice.current.model - pasteBoardItems["status_os"] = UIDevice.current.systemVersion - pasteBoardItems["status_version"] = UIDevice.current.systemVersion + pasteBoardItems["status_machine"] = statusMachine + pasteBoardItems["status_os"] = statusOS + pasteBoardItems["status_version"] = statusVersion let pbItems = pasteBoardItems.compactMapValues { $0 } let pbData = NSKeyedArchiver.archivedData(withRootObject: pbItems) @@ -419,6 +419,18 @@ extension QQHandler: OauthHandlerType { } } } + + private var statusMachine: String { + UIDevice.current.bus.machine + } + + private var statusOS: String { + UIDevice.current.systemVersion + } + + private var statusVersion: String { + "\(ProcessInfo.processInfo.operatingSystemVersion.majorVersion)" + } } extension QQHandler: OpenURLHandlerType { From 234e328ead3455bdb71a85e8ae5260f5e5a66aea Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:51:11 +0800 Subject: [PATCH 63/67] docs: sort --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 626f63f..6cf2ba8 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ nuomi1, nuomi1@qq.com ## Related articles - [NBus 的由来](https://nuomi1.github.io/archives/2020/09/nbus-comes-from.html) -- [NBus 之 WechatSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-wechatsdkhandler.html) - [NBus 之 QQSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-qqsdkhandler.html) -- [NBus 之 WeiboSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-weibosdkhandler.html) - [NBus 之 SystemHandler](https://nuomi1.github.io/archives/2020/12/nbus-systemhandler.html) +- [NBus 之 WechatSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-wechatsdkhandler.html) +- [NBus 之 WeiboSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-weibosdkhandler.html) ## Credits From 0af2c25e0e292551290959119187599a6cf4eb3e Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:54:14 +0800 Subject: [PATCH 64/67] feat: update link --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6cf2ba8..15da931 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ nuomi1, nuomi1@qq.com ## Related articles -- [NBus 的由来](https://nuomi1.github.io/archives/2020/09/nbus-comes-from.html) -- [NBus 之 QQSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-qqsdkhandler.html) -- [NBus 之 SystemHandler](https://nuomi1.github.io/archives/2020/12/nbus-systemhandler.html) -- [NBus 之 WechatSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-wechatsdkhandler.html) -- [NBus 之 WeiboSDKHandler](https://nuomi1.github.io/archives/2020/12/nbus-weibosdkhandler.html) +- [NBus 的由来](https://blog.nuomi1.com/archives/2020/09/nbus-comes-from.html) +- [NBus 之 QQSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-qqsdkhandler.html) +- [NBus 之 SystemHandler](https://blog.nuomi1.com/archives/2020/12/nbus-systemhandler.html) +- [NBus 之 WechatSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-wechatsdkhandler.html) +- [NBus 之 WeiboSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-weibosdkhandler.html) ## Credits From 154df84263588e51a4a4375be9ca9b13ff6c40b5 Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:54:33 +0800 Subject: [PATCH 65/67] feat: rename --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15da931..b3c7a2c 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ nuomi1, nuomi1@qq.com - [NBus 之 WechatSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-wechatsdkhandler.html) - [NBus 之 WeiboSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-weibosdkhandler.html) -## Credits +## Thanks - [MonkeyKing](https://github.com/nixzhu/MonkeyKing) - [LQThirdParty](https://github.com/LQi2009/LQThirdParty) From 683bc0152ff55955db51b59773698617ff4b061c Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:55:46 +0800 Subject: [PATCH 66/67] feat: add QQHandler article --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b3c7a2c..bba73dd 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ nuomi1, nuomi1@qq.com ## Related articles - [NBus 的由来](https://blog.nuomi1.com/archives/2020/09/nbus-comes-from.html) +- [NBus 之 QQHandler](https://blog.nuomi1.com/archives/2021/01/nbus-qqhandler.html) - [NBus 之 QQSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-qqsdkhandler.html) - [NBus 之 SystemHandler](https://blog.nuomi1.com/archives/2020/12/nbus-systemhandler.html) - [NBus 之 WechatSDKHandler](https://blog.nuomi1.com/archives/2020/12/nbus-wechatsdkhandler.html) From 4954d75f38c7c74623ea92c75183f2164a258f4b Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Sat, 16 Jan 2021 09:55:58 +0800 Subject: [PATCH 67/67] bump to 0.8.0 --- NBus.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NBus.podspec b/NBus.podspec index b5d57af..a15d1a3 100644 --- a/NBus.podspec +++ b/NBus.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "NBus" - s.version = "0.7.0" + s.version = "0.8.0" s.summary = "A short description of NBus." s.homepage = "https://github.com/nuomi1/NBus"