消息通知接入

This commit is contained in:
zeng 2025-06-26 15:15:03 +08:00
parent 6e4051494e
commit 0043d3de2d
5 changed files with 244 additions and 13 deletions

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,69 @@
//
// NotificationService.swift
// NotificationService
//
// Created by on 2025/6/26.
//
import UserNotifications
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
guard let bestAttemptContent = bestAttemptContent else {
contentHandler(request.content)
return
}
if let options = request.content.userInfo["fcm_options"] as? [String : Any],
let imageURLString = options["image"] as? String,
let imageURL = URL(string: imageURLString) {
downloadImage(from: imageURL) { attachment in
if let attachment = attachment {
bestAttemptContent.attachments = [attachment]
}
contentHandler(bestAttemptContent)
}
} else {
contentHandler(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) {
let task = URLSession.shared.downloadTask(with: url) { (downloadedUrl, _, error) in
guard let downloadedUrl = downloadedUrl else {
completion(nil)
return
}
let tmpDir = FileManager.default.temporaryDirectory
let tmpFile = tmpDir.appendingPathComponent(url.lastPathComponent)
do {
try FileManager.default.moveItem(at: downloadedUrl, to: tmpFile)
let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: tmpFile, options: nil)
completion(attachment)
} catch {
completion(nil)
}
}
task.resume()
}
}

View File

@ -262,9 +262,11 @@
1BB91E0C2E04FD6A00A2C715 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1BB91CD52E04FD6A00A2C715 /* GoogleService-Info.plist */; };
1BB91E0E2E04FD6A00A2C715 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1BB91CD82E04FD6A00A2C715 /* LaunchScreen.storyboard */; };
1BB91E0F2E04FD6A00A2C715 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1BB91CDA2E04FD6A00A2C715 /* Localizable.strings */; };
1BC1F0D32E09389000B579A4 /* SPVerisionUpdateAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC1F0D22E09389000B579A4 /* SPVerisionUpdateAlertView.swift */; };
1BC1F0D32E09389000B579A4 /* SPVersionUpdateAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC1F0D22E09389000B579A4 /* SPVersionUpdateAlertView.swift */; };
1BC1F0D52E093E9900B579A4 /* SPVersionUpdateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC1F0D42E093E9900B579A4 /* SPVersionUpdateModel.swift */; };
1BC1F0D72E0A35EF00B579A4 /* SPVideoRevolutionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC1F0D62E0A35EF00B579A4 /* SPVideoRevolutionManager.swift */; };
1BC1F0E32E0D268400B579A4 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1BC1F0DC2E0D268400B579A4 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
1BC1F0EB2E0D268B00B579A4 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC1F0E92E0D268B00B579A4 /* NotificationService.swift */; };
1BE7892B2DCB0E530001A8F1 /* FacebookCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1BE7892A2DCB0E530001A8F1 /* FacebookCore */; };
1BE7892D2DCB0E530001A8F1 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 1BE7892C2DCB0E530001A8F1 /* FacebookLogin */; };
1BF22FD12DC2169B0082429A /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD02DC2169B0082429A /* FirebaseAnalytics */; };
@ -273,6 +275,16 @@
C3D1CE788CA03A1878493356 /* Pods_ThimraTV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64805795B479324EB764157 /* Pods_ThimraTV.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
1BC1F0E12E0D268400B579A4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1DBC40512DA4EDFC0093FCB0 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 1BC1F0DB2E0D268400B579A4;
remoteInfo = NotificationService;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
1BB9206E2E050B1A00A2C715 /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
@ -280,6 +292,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
1BC1F0E32E0D268400B579A4 /* NotificationService.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
@ -556,9 +569,12 @@
1BB91D0A2E04FD6A00A2C715 /* ZKCycleScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZKCycleScrollView.swift; sourceTree = "<group>"; };
1BB91D0B2E04FD6A00A2C715 /* ZKCycleScrollViewFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZKCycleScrollViewFlowLayout.swift; sourceTree = "<group>"; };
1BB91D0E2E04FD6A00A2C715 /* ThimraTV.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ThimraTV.entitlements; sourceTree = "<group>"; };
1BC1F0D22E09389000B579A4 /* SPVerisionUpdateAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPVerisionUpdateAlertView.swift; sourceTree = "<group>"; };
1BC1F0D22E09389000B579A4 /* SPVersionUpdateAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPVersionUpdateAlertView.swift; sourceTree = "<group>"; };
1BC1F0D42E093E9900B579A4 /* SPVersionUpdateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPVersionUpdateModel.swift; sourceTree = "<group>"; };
1BC1F0D62E0A35EF00B579A4 /* SPVideoRevolutionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPVideoRevolutionManager.swift; sourceTree = "<group>"; };
1BC1F0DC2E0D268400B579A4 /* NotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
1BC1F0E82E0D268B00B579A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1BC1F0E92E0D268B00B579A4 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
1DBC40592DA4EDFC0093FCB0 /* ThimraTV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThimraTV.app; sourceTree = BUILT_PRODUCTS_DIR; };
1F666DE0B12C863F26BE5027 /* Pods-MoviaBox.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MoviaBox.debug.xcconfig"; path = "Target Support Files/Pods-MoviaBox/Pods-MoviaBox.debug.xcconfig"; sourceTree = "<group>"; };
A1174E10BCF2C606F7818792 /* Pods-ThimraTV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ThimraTV.release.xcconfig"; path = "Target Support Files/Pods-ThimraTV/Pods-ThimraTV.release.xcconfig"; sourceTree = "<group>"; };
@ -568,6 +584,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1BC1F0D92E0D268400B579A4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
1DBC40562DA4EDFC0093FCB0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -1145,7 +1168,7 @@
children = (
1BB91CB02E04FD6A00A2C715 /* SPAlertView.swift */,
1BB91CB12E04FD6A00A2C715 /* SPAlertWindowManager.swift */,
1BC1F0D22E09389000B579A4 /* SPVerisionUpdateAlertView.swift */,
1BC1F0D22E09389000B579A4 /* SPVersionUpdateAlertView.swift */,
);
path = Alert;
sourceTree = "<group>";
@ -1426,10 +1449,20 @@
path = ThimraTV;
sourceTree = "<group>";
};
1BC1F0EA2E0D268B00B579A4 /* NotificationService */ = {
isa = PBXGroup;
children = (
1BC1F0E82E0D268B00B579A4 /* Info.plist */,
1BC1F0E92E0D268B00B579A4 /* NotificationService.swift */,
);
path = NotificationService;
sourceTree = "<group>";
};
1DBC40502DA4EDFC0093FCB0 = {
isa = PBXGroup;
children = (
1BB91D0F2E04FD6A00A2C715 /* ThimraTV */,
1BC1F0EA2E0D268B00B579A4 /* NotificationService */,
1DBC405A2DA4EDFC0093FCB0 /* Products */,
0061C3496D158807460301A9 /* Pods */,
B6C9E282BAC4C4B3E926A853 /* Frameworks */,
@ -1440,6 +1473,7 @@
isa = PBXGroup;
children = (
1DBC40592DA4EDFC0093FCB0 /* ThimraTV.app */,
1BC1F0DC2E0D268400B579A4 /* NotificationService.appex */,
);
name = Products;
sourceTree = "<group>";
@ -1455,6 +1489,25 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1BC1F0DB2E0D268400B579A4 /* NotificationService */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1BC1F0E52E0D268400B579A4 /* Build configuration list for PBXNativeTarget "NotificationService" */;
buildPhases = (
1BC1F0D82E0D268400B579A4 /* Sources */,
1BC1F0D92E0D268400B579A4 /* Frameworks */,
1BC1F0DA2E0D268400B579A4 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = NotificationService;
packageProductDependencies = (
);
productName = NotificationService;
productReference = 1BC1F0DC2E0D268400B579A4 /* NotificationService.appex */;
productType = "com.apple.product-type.app-extension";
};
1DBC40582DA4EDFC0093FCB0 /* ThimraTV */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DBC40822DA4EE010093FCB0 /* Build configuration list for PBXNativeTarget "ThimraTV" */;
@ -1469,6 +1522,7 @@
buildRules = (
);
dependencies = (
1BC1F0E22E0D268400B579A4 /* PBXTargetDependency */,
);
name = ThimraTV;
productName = ShortPlay;
@ -1485,6 +1539,9 @@
LastSwiftUpdateCheck = 1640;
LastUpgradeCheck = 1620;
TargetAttributes = {
1BC1F0DB2E0D268400B579A4 = {
CreatedOnToolsVersion = 16.4;
};
1DBC40582DA4EDFC0093FCB0 = {
CreatedOnToolsVersion = 16.2;
};
@ -1509,11 +1566,19 @@
projectRoot = "";
targets = (
1DBC40582DA4EDFC0093FCB0 /* ThimraTV */,
1BC1F0DB2E0D268400B579A4 /* NotificationService */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
1BC1F0DA2E0D268400B579A4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
1DBC40572DA4EDFC0093FCB0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1575,6 +1640,14 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1BC1F0D82E0D268400B579A4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1BC1F0EB2E0D268B00B579A4 /* NotificationService.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1DBC40552DA4EDFC0093FCB0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -1768,7 +1841,7 @@
1BB91DC92E04FD6A00A2C715 /* SPCoinOrderRecordCell.swift in Sources */,
1BB91DCA2E04FD6A00A2C715 /* SPCoinRechargeBigCell.swift in Sources */,
1BB91DCB2E04FD6A00A2C715 /* SPCoinRechargeCell.swift in Sources */,
1BC1F0D32E09389000B579A4 /* SPVerisionUpdateAlertView.swift in Sources */,
1BC1F0D32E09389000B579A4 /* SPVersionUpdateAlertView.swift in Sources */,
1BB91DCC2E04FD6A00A2C715 /* SPCoinRechargeSmallCell.swift in Sources */,
1BB91DCD2E04FD6A00A2C715 /* SPCoinRechargeView.swift in Sources */,
1BB91DCE2E04FD6A00A2C715 /* SPConsumptionRecordsCell.swift in Sources */,
@ -1837,6 +1910,14 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
1BC1F0E22E0D268400B579A4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 1BC1F0DB2E0D268400B579A4 /* NotificationService */;
targetProxy = 1BC1F0E12E0D268400B579A4 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
1BB91CD82E04FD6A00A2C715 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
@ -1857,6 +1938,60 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1BC1F0E62E0D268400B579A4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = TWDZ3MP9DV;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = NotificationService/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
1BC1F0E72E0D268400B579A4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = TWDZ3MP9DV;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = NotificationService/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
1DBC40832DA4EE010093FCB0 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 0538826A0638D33FEF3A2E38 /* Pods-ThimraTV.debug.xcconfig */;
@ -1867,7 +2002,7 @@
CODE_SIGN_ENTITLEMENTS = ThimraTV/ThimraTV.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = TWDZ3MP9DV;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES;
@ -1891,7 +2026,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.1;
MARKETING_VERSION = 1.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1915,7 +2050,7 @@
CODE_SIGN_ENTITLEMENTS = ThimraTV/ThimraTV.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = TWDZ3MP9DV;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES;
@ -1939,7 +2074,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.1;
MARKETING_VERSION = 1.1.2;
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -2077,6 +2212,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1BC1F0E52E0D268400B579A4 /* Build configuration list for PBXNativeTarget "NotificationService" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1BC1F0E62E0D268400B579A4 /* Debug */,
1BC1F0E72E0D268400B579A4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DBC40542DA4EDFC0093FCB0 /* Build configuration list for PBXProject "ThimraTV" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -127,7 +127,7 @@ extension SPAPPTool {
static func checkUpdates() {
#if !DEBUG
if let date = UserDefaults.standard.object(forKey: kSPVersionUpdateAlertDefaultsKey) as? Date {
if date.vp_isToday { return }
if date.sp_isToday { return }
}
UserDefaults.standard.set(Date(), forKey: kSPVersionUpdateAlertDefaultsKey)
#endif
@ -141,7 +141,7 @@ extension SPAPPTool {
}
static private func showVersionUpdateAlert(model: SPVersionUpdateModel) {
SPVerisionUpdateAlertView(model: model).show()
SPVersionUpdateAlertView(model: model).show()
}
}

View File

@ -1,5 +1,5 @@
//
// SPVerisionUpdateAlertView.swift
// SPVersionUpdateAlertView.swift
// ThimraTV
//
// Created by on 2025/6/23.
@ -7,7 +7,7 @@
import UIKit
class SPVerisionUpdateAlertView: SPAlertView {
class SPVersionUpdateAlertView: SPAlertView {
private var model: SPVersionUpdateModel
@ -101,7 +101,7 @@ class SPVerisionUpdateAlertView: SPAlertView {
}
extension SPVerisionUpdateAlertView {
extension SPVersionUpdateAlertView {
private func sp_setupUI() {
self.addSubview(contentView)