From 4fb69a641dcee9770a235c0e601d198dde4e174b Mon Sep 17 00:00:00 2001 From: Fin Date: Sun, 26 Sep 2021 16:28:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8E=A8=E9=80=81IC?= =?UTF-8?q?ON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bark.xcodeproj/project.pbxproj | 168 ++++++++++++++++-- .../icon.imageset/Contents.json | 21 +++ .../icon.imageset/IMG_1116 2.jpg | Bin 0 -> 43276 bytes Bark/en.lproj/Localizable.strings | 3 + Bark/zh-Hans.lproj/Localizable.strings | 3 + Controller/HomeViewModel.swift | 6 + Intent/Info.plist | 22 +++ Intent/IntentHandler.swift | 125 +++++++++++++ NotificationServiceExtension/Info.plist | 7 + .../NotificationService.swift | 153 ++++++++++++---- 10 files changed, 463 insertions(+), 45 deletions(-) create mode 100644 Bark/Assets.xcassets/icon.imageset/Contents.json create mode 100644 Bark/Assets.xcassets/icon.imageset/IMG_1116 2.jpg create mode 100644 Intent/Info.plist create mode 100644 Intent/IntentHandler.swift diff --git a/Bark.xcodeproj/project.pbxproj b/Bark.xcodeproj/project.pbxproj index 538aa18..c953ce6 100644 --- a/Bark.xcodeproj/project.pbxproj +++ b/Bark.xcodeproj/project.pbxproj @@ -71,6 +71,9 @@ 065BE44B2563D8E1002A8CA4 /* Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065BE44A2563D8E1002A8CA4 /* Reusable.swift */; }; 065BE4502563D939002A8CA4 /* SoundCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065BE44F2563D939002A8CA4 /* SoundCellViewModel.swift */; }; 065BE4552565055F002A8CA4 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065BE4542565055F002A8CA4 /* HomeViewModel.swift */; }; + 0660480B2700550600938904 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0660480A2700550600938904 /* Intents.framework */; }; + 0660480E2700550600938904 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0660480D2700550600938904 /* IntentHandler.swift */; }; + 066048122700550600938904 /* Intent.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 066048092700550600938904 /* Intent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 0661A543204FDA4100965E4E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0661A542204FDA4100965E4E /* AppDelegate.swift */; }; 0661A545204FDA4100965E4E /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0661A544204FDA4100965E4E /* HomeViewController.swift */; }; 0661A54A204FDA4100965E4E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0661A549204FDA4100965E4E /* Assets.xcassets */; }; @@ -118,6 +121,13 @@ remoteGlobalIDString = 0632CE1D20EC9098003FDF46; remoteInfo = NotificationContentExtension; }; + 066048102700550600938904 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0661A537204FDA4100965E4E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 066048082700550600938904; + remoteInfo = Intent; + }; 06CF784521C7A50300A052D7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0661A537204FDA4100965E4E /* Project object */; @@ -142,6 +152,7 @@ dstSubfolderSpec = 13; files = ( 0632CE2A20EC9098003FDF46 /* NotificationContentExtension.appex in Embed App Extensions */, + 066048122700550600938904 /* Intent.appex in Embed App Extensions */, 06CF784721C7A50300A052D7 /* NotificationServiceExtension.appex in Embed App Extensions */, ); name = "Embed App Extensions"; @@ -213,6 +224,10 @@ 065BE44A2563D8E1002A8CA4 /* Reusable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reusable.swift; sourceTree = ""; }; 065BE44F2563D939002A8CA4 /* SoundCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundCellViewModel.swift; sourceTree = ""; }; 065BE4542565055F002A8CA4 /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = ""; }; + 066048092700550600938904 /* Intent.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Intent.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 0660480A2700550600938904 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; }; + 0660480D2700550600938904 /* IntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = ""; }; + 0660480F2700550600938904 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 0661A53F204FDA4100965E4E /* Bark.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Bark.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0661A542204FDA4100965E4E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 0661A544204FDA4100965E4E /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; @@ -273,6 +288,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 066048062700550600938904 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0660480B2700550600938904 /* Intents.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 0661A53C204FDA4100965E4E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -435,6 +458,15 @@ path = Moya; sourceTree = ""; }; + 0660480C2700550600938904 /* Intent */ = { + isa = PBXGroup; + children = ( + 0660480D2700550600938904 /* IntentHandler.swift */, + 0660480F2700550600938904 /* Info.plist */, + ); + path = Intent; + sourceTree = ""; + }; 0661A536204FDA4100965E4E = { isa = PBXGroup; children = ( @@ -447,6 +479,7 @@ 0632CE2120EC9098003FDF46 /* NotificationContentExtension */, 06CF784121C7A50300A052D7 /* NotificationServiceExtension */, 06EE1FD126843E9300586708 /* BarkTests */, + 0660480C2700550600938904 /* Intent */, 0661A540204FDA4100965E4E /* Products */, 9563D0DB71FE280909AB1C63 /* Pods */, 99BD309BDB7F62B5DC0CECE1 /* Frameworks */, @@ -460,6 +493,7 @@ 0632CE1E20EC9098003FDF46 /* NotificationContentExtension.appex */, 06CF784021C7A50300A052D7 /* NotificationServiceExtension.appex */, 06EE1FD026843E9300586708 /* BarkTests.xctest */, + 066048092700550600938904 /* Intent.appex */, ); name = Products; sourceTree = ""; @@ -516,6 +550,7 @@ 14F0F73EC45A35FC2482F967 /* Pods_NotificationContentExtension.framework */, E4EA0C04469BF7B418FF3CB7 /* libPods-Bark.a */, A24A28EB12CA35B953807C99 /* libPods-NotificationServiceExtension.a */, + 0660480A2700550600938904 /* Intents.framework */, ); name = Frameworks; sourceTree = ""; @@ -540,6 +575,23 @@ productReference = 0632CE1E20EC9098003FDF46 /* NotificationContentExtension.appex */; productType = "com.apple.product-type.app-extension"; }; + 066048082700550600938904 /* Intent */ = { + isa = PBXNativeTarget; + buildConfigurationList = 066048132700550600938904 /* Build configuration list for PBXNativeTarget "Intent" */; + buildPhases = ( + 066048052700550600938904 /* Sources */, + 066048062700550600938904 /* Frameworks */, + 066048072700550600938904 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Intent; + productName = Intent; + productReference = 066048092700550600938904 /* Intent.appex */; + productType = "com.apple.product-type.app-extension"; + }; 0661A53E204FDA4100965E4E /* Bark */ = { isa = PBXNativeTarget; buildConfigurationList = 0661A551204FDA4100965E4E /* Build configuration list for PBXNativeTarget "Bark" */; @@ -556,6 +608,7 @@ dependencies = ( 0632CE2920EC9098003FDF46 /* PBXTargetDependency */, 06CF784621C7A50300A052D7 /* PBXTargetDependency */, + 066048112700550600938904 /* PBXTargetDependency */, ); name = Bark; productName = Bark; @@ -604,7 +657,7 @@ 0661A537204FDA4100965E4E /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1250; + LastSwiftUpdateCheck = 1300; LastUpgradeCheck = 0930; ORGANIZATIONNAME = Fin; TargetAttributes = { @@ -612,6 +665,10 @@ CreatedOnToolsVersion = 9.3; ProvisioningStyle = Manual; }; + 066048082700550600938904 = { + CreatedOnToolsVersion = 13.0; + ProvisioningStyle = Automatic; + }; 0661A53E204FDA4100965E4E = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Manual; @@ -650,6 +707,7 @@ 0632CE1D20EC9098003FDF46 /* NotificationContentExtension */, 06CF783F21C7A50300A052D7 /* NotificationServiceExtension */, 06EE1FCF26843E9300586708 /* BarkTests */, + 066048082700550600938904 /* Intent */, ); }; /* End PBXProject section */ @@ -665,6 +723,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 066048072700550600938904 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 0661A53D204FDA4100965E4E /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -799,6 +864,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 066048052700550600938904 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0660480E2700550600938904 /* IntentHandler.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 0661A53B204FDA4100965E4E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -883,6 +956,11 @@ target = 0632CE1D20EC9098003FDF46 /* NotificationContentExtension */; targetProxy = 0632CE2820EC9098003FDF46 /* PBXContainerItemProxy */; }; + 066048112700550600938904 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 066048082700550600938904 /* Intent */; + targetProxy = 066048102700550600938904 /* PBXContainerItemProxy */; + }; 06CF784621C7A50300A052D7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 06CF783F21C7A50300A052D7 /* NotificationServiceExtension */; @@ -928,7 +1006,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5U8LBRXG3A; @@ -938,7 +1016,7 @@ MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark.NotificationContent; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark.NotificationContent"; + PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark.NotificationContent"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; @@ -949,7 +1027,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5U8LBRXG3A; @@ -959,13 +1037,68 @@ MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark.NotificationContent; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark.NotificationContent"; + PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark.NotificationContent"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; + 066048142700550600938904 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5U8LBRXG3A; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Intent/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Intent; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Fin. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark.Intent; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 066048152700550600938904 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5U8LBRXG3A; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Intent/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Intent; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Fin. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark.Intent; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 0661A54F204FDA4100965E4E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1086,7 +1219,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Bark/Bark.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5U8LBRXG3A; @@ -1096,7 +1229,7 @@ MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark"; + PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; @@ -1109,7 +1242,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Bark/Bark.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5U8LBRXG3A; @@ -1119,7 +1252,7 @@ MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark"; + PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; @@ -1131,7 +1264,7 @@ buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; CODE_SIGN_ENTITLEMENTS = NotificationServiceExtension/NotificationServiceExtension.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5U8LBRXG3A; @@ -1143,7 +1276,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark.NotificationServiceExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark.NotificationServiceExtension"; + PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark.NotificationServiceExtension"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1156,7 +1289,7 @@ buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; CODE_SIGN_ENTITLEMENTS = NotificationServiceExtension/NotificationServiceExtension.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5U8LBRXG3A; @@ -1167,7 +1300,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark.NotificationServiceExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark.NotificationServiceExtension"; + PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark.NotificationServiceExtension"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1235,6 +1368,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 066048132700550600938904 /* Build configuration list for PBXNativeTarget "Intent" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 066048142700550600938904 /* Debug */, + 066048152700550600938904 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 0661A53A204FDA4100965E4E /* Build configuration list for PBXProject "Bark" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Bark/Assets.xcassets/icon.imageset/Contents.json b/Bark/Assets.xcassets/icon.imageset/Contents.json new file mode 100644 index 0000000..a5682b9 --- /dev/null +++ b/Bark/Assets.xcassets/icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "IMG_1116 2.jpg", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Bark/Assets.xcassets/icon.imageset/IMG_1116 2.jpg b/Bark/Assets.xcassets/icon.imageset/IMG_1116 2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a63445ebd10f5977976fe48d993ce6ec39acb1f0 GIT binary patch literal 43276 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 j?mesb<@N;ye&7Au + + + + NSExtension + + NSExtensionAttributes + + IntentsRestrictedWhileLocked + + IntentsSupported + + INSendMessageIntent + + + NSExtensionPointIdentifier + com.apple.intents-service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).IntentHandler + + + diff --git a/Intent/IntentHandler.swift b/Intent/IntentHandler.swift new file mode 100644 index 0000000..35c2e86 --- /dev/null +++ b/Intent/IntentHandler.swift @@ -0,0 +1,125 @@ +// +// IntentHandler.swift +// Intent +// +// Created by huangfeng on 2021/9/26. +// Copyright © 2021 Fin. All rights reserved. +// + +import Intents + +// As an example, this class is set up to handle Message intents. +// You will want to replace this or add other intents as appropriate. +// The intents you wish to handle must be declared in the extension's Info.plist. + +// You can test your example integration by saying things to Siri like: +// "Send a message using " +// " John saying hello" +// "Search for messages in " + +class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling { + + override func handler(for intent: INIntent) -> Any { + // This is the default implementation. If you want different objects to handle different intents, + // you can override this and return the handler you want for that particular intent. + + return self + } + + // MARK: - INSendMessageIntentHandling + + // Implement resolution methods to provide additional information about your intent (optional). + func resolveRecipients(for intent: INSendMessageIntent, with completion: @escaping ([INSendMessageRecipientResolutionResult]) -> Void) { + if let recipients = intent.recipients { + + // If no recipients were provided we'll need to prompt for a value. + if recipients.count == 0 { + completion([INSendMessageRecipientResolutionResult.needsValue()]) + return + } + + var resolutionResults = [INSendMessageRecipientResolutionResult]() + for recipient in recipients { + let matchingContacts = [recipient] // Implement your contact matching logic here to create an array of matching contacts + switch matchingContacts.count { + case 2 ... Int.max: + // We need Siri's help to ask user to pick one from the matches. + resolutionResults += [INSendMessageRecipientResolutionResult.disambiguation(with: matchingContacts)] + + case 1: + // We have exactly one matching contact + resolutionResults += [INSendMessageRecipientResolutionResult.success(with: recipient)] + + case 0: + // We have no contacts matching the description provided + resolutionResults += [INSendMessageRecipientResolutionResult.unsupported()] + + default: + break + + } + } + completion(resolutionResults) + } else { + completion([INSendMessageRecipientResolutionResult.needsValue()]) + } + } + + func resolveContent(for intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) { + if let text = intent.content, !text.isEmpty { + completion(INStringResolutionResult.success(with: text)) + } else { + completion(INStringResolutionResult.needsValue()) + } + } + + // Once resolution is completed, perform validation on the intent and provide confirmation (optional). + + func confirm(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { + // Verify user is authenticated and your app is ready to send a message. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) + let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity) + completion(response) + } + + // Handle the completed intent (required). + + func handle(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { + // Implement your application logic to send a message here. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) + let response = INSendMessageIntentResponse(code: .success, userActivity: userActivity) + completion(response) + } + + // Implement handlers for each intent you wish to handle. As an example for messages, you may wish to also handle searchForMessages and setMessageAttributes. + + // MARK: - INSearchForMessagesIntentHandling + + func handle(intent: INSearchForMessagesIntent, completion: @escaping (INSearchForMessagesIntentResponse) -> Void) { + // Implement your application logic to find a message that matches the information in the intent. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self)) + let response = INSearchForMessagesIntentResponse(code: .success, userActivity: userActivity) + // Initialize with found message's attributes + response.messages = [INMessage( + identifier: "identifier", + content: "I am so excited about SiriKit!", + dateSent: Date(), + sender: INPerson(personHandle: INPersonHandle(value: "sarah@example.com", type: .emailAddress), nameComponents: nil, displayName: "Sarah", image: nil, contactIdentifier: nil, customIdentifier: nil), + recipients: [INPerson(personHandle: INPersonHandle(value: "+1-415-555-5555", type: .phoneNumber), nameComponents: nil, displayName: "John", image: nil, contactIdentifier: nil, customIdentifier: nil)] + )] + completion(response) + } + + // MARK: - INSetMessageAttributeIntentHandling + + func handle(intent: INSetMessageAttributeIntent, completion: @escaping (INSetMessageAttributeIntentResponse) -> Void) { + // Implement your application logic to set the message attribute here. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSetMessageAttributeIntent.self)) + let response = INSetMessageAttributeIntentResponse(code: .success, userActivity: userActivity) + completion(response) + } +} diff --git a/NotificationServiceExtension/Info.plist b/NotificationServiceExtension/Info.plist index 92c4aa8..d8fc4ad 100644 --- a/NotificationServiceExtension/Info.plist +++ b/NotificationServiceExtension/Info.plist @@ -22,6 +22,13 @@ $(CURRENT_PROJECT_VERSION) NSExtension + NSExtensionAttributes + + IntentsSupported + + INSendMessageIntent + + NSExtensionPointIdentifier com.apple.usernotifications.service NSExtensionPrincipalClass diff --git a/NotificationServiceExtension/NotificationService.swift b/NotificationServiceExtension/NotificationService.swift index 2668640..8239c31 100644 --- a/NotificationServiceExtension/NotificationService.swift +++ b/NotificationServiceExtension/NotificationService.swift @@ -11,6 +11,7 @@ import UserNotifications import RealmSwift import Kingfisher import MobileCoreServices +import Intents class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? @@ -94,17 +95,56 @@ class NotificationService: UNNotificationServiceExtension { /// - userInfo: 推送参数 /// - bestAttemptContent: 推送content /// - complection: 下载图片完毕后的回调函数 - fileprivate func downloadImage(_ userInfo: [AnyHashable : Any], content bestAttemptContent: UNMutableNotificationContent, complection: @escaping () -> () ) { - - guard let imageUrl = userInfo["image"] as? String, - let groupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.bark"), - let cache = try? ImageCache(name: "shared",cacheDirectoryURL: groupUrl) + fileprivate func downloadImage(_ imageUrl:String, complection: @escaping (_ imageFileUrl:String?) -> () ) { + guard let groupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.bark"), + let cache = try? ImageCache(name: "shared",cacheDirectoryURL: groupUrl), + let imageResource = URL(string: imageUrl) else { + complection(nil) + return + } + + func downloadFinished(){ + let cacheFileUrl = cache.cachePath(forKey: imageResource.cacheKey) + complection(cacheFileUrl) + } + + // 先查看图片缓存 + if cache.diskStorage.isCached(forKey: imageResource.cacheKey) { + downloadFinished() + return + } + + // 下载图片 + Kingfisher.ImageDownloader.default.downloadImage(with: imageResource, options: nil) { result in + guard let result = try? result.get() else { + complection(nil) + return + } + // 缓存图片 + cache.storeToDisk(result.originalData, forKey: imageResource.cacheKey, expiration: StorageExpiration.never) { r in + downloadFinished() + } + } + } + + /// 下载推送图片 + /// - Parameters: + /// - userInfo: 推送参数 + /// - bestAttemptContent: 推送content + /// - complection: 下载图片完毕后的回调函数 + fileprivate func setImage(_ userInfo: [AnyHashable : Any], content bestAttemptContent: UNMutableNotificationContent, complection: @escaping () -> () ) { + + guard let imageUrl = userInfo["image"] as? String else { complection() return } - func finished(imageFileUrl: String){ + func finished(_ imageFileUrl: String?){ + guard let imageFileUrl = imageFileUrl else { + complection() + return + } let copyDestUrl = URL(fileURLWithPath: imageFileUrl).appendingPathExtension(".tmp") // 将图片缓存复制一份,推送使用完后会自动删除,但图片缓存需要留着以后在历史记录里查看 try? FileManager.default.copyItem( @@ -120,33 +160,78 @@ class NotificationService: UNNotificationServiceExtension { complection() } - // 远程图片 - guard let imageResource = URL(string: imageUrl) else { - complection() - return - } - - func downloadFinished(){ - let cacheFileUrl = cache.cachePath(forKey: imageResource.cacheKey) - finished(imageFileUrl: cacheFileUrl) - } - - // 先查看图片缓存 - if cache.diskStorage.isCached(forKey: imageResource.cacheKey) { - downloadFinished() - return - } - - // 下载图片 - Kingfisher.ImageDownloader.default.downloadImage(with: imageResource, options: nil) { result in - guard let result = try? result.get() else { + downloadImage(imageUrl, complection: finished) + } + + fileprivate func setIcon(_ userInfo: [AnyHashable : Any], content bestAttemptContent: UNMutableNotificationContent, complection: @escaping () -> () ) { + if #available(iOSApplicationExtension 15.0, *) { + guard let imageUrl = userInfo["icon"] as? String else { complection() return } - // 缓存图片 - cache.storeToDisk(result.originalData, forKey: imageResource.cacheKey, expiration: StorageExpiration.never) { r in - downloadFinished() + + func finished(_ imageFileUrl: String?){ + guard let imageFileUrl = imageFileUrl else { + complection() + return + } + var personNameComponents = PersonNameComponents() + personNameComponents.nickname = bestAttemptContent.title + + let avatar = INImage(imageData: NSData(contentsOfFile: imageFileUrl)! as Data) + let senderPerson = INPerson( + personHandle: INPersonHandle(value: "", type: .unknown), + nameComponents: personNameComponents, + displayName: personNameComponents.nickname, + image: avatar, + contactIdentifier: nil, + customIdentifier: nil, + isMe: false, + suggestionType: .none + ) + let mePerson = INPerson( + personHandle: INPersonHandle(value: "", type: .unknown), + nameComponents: nil, + displayName: nil, + image: nil, + contactIdentifier: nil, + customIdentifier: nil, + isMe: true, + suggestionType: .none + ) + + let intent = INSendMessageIntent( + recipients: [mePerson], + outgoingMessageType: .outgoingMessageText, + content: bestAttemptContent.body, + speakableGroupName: INSpeakableString(spokenPhrase: personNameComponents.nickname ?? ""), + conversationIdentifier: "sampleConversationIdentifier", + serviceName: nil, + sender: senderPerson, + attachments: nil + ) + + intent.setImage(avatar, forParameterNamed: \.sender) + + let interaction = INInteraction(intent: intent, response: nil) + interaction.direction = .incoming + + interaction.donate(completion: nil) + + do { + let content = try self.bestAttemptContent!.updating(from: intent) as! UNMutableNotificationContent + self.bestAttemptContent = content + } catch { + // Handle error + } + + complection() } + + downloadImage(imageUrl, complection: finished) + } + else{ + complection() } } @@ -162,10 +247,14 @@ class NotificationService: UNNotificationServiceExtension { autoCopy(userInfo, defaultCopy: bestAttemptContent.body) // 保存推送 archive(userInfo) - // 下载图片,设置到推送中 - downloadImage(userInfo, content: bestAttemptContent) { - contentHandler(bestAttemptContent) + // 设置推送图标 + setIcon(userInfo, content: self.bestAttemptContent!) { + // 设置推送图片 + self.setImage(userInfo, content: self.bestAttemptContent!) { + contentHandler(self.bestAttemptContent!) + } } + } else{ contentHandler(bestAttemptContent!)