Я реализую push-уведомление Apple в своем приложении, оно реализовано успешно, но я столкнулся с проблемой, когда мое приложение завершило работу: мы не получаем никаких уведомлений, но если мое приложение открывается, мы успешно получаем уведомление с изображением.< /p>
Я также реализую расширение службы уведомлений и расширение контента уведомлений.
Вот мой код AppDelegate:
import UIKit
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Request notification permission
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if let error = error {
print("Error requesting notification authorization: \(error)")
}
if granted {
DispatchQueue.main.async {
self.registerForPushNotifications(application)
}
}
}
UNUserNotificationCenter.current().delegate = self
window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewControllerIdentifier = Helper.getCurrentAuthentication().authenticationMeta != nil ? "HomeVC" : "LoginVc"
let viewController = storyboard.instantiateViewController(withIdentifier: viewControllerIdentifier)
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { String(format: "%02.2hhx", $0) }
let deviceTokenString = tokenParts.joined()
print("Device Token: \(deviceTokenString)")
Helper.setFCMToken(fcmToken: deviceTokenString)
}
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]
) {
print("Received remote notification: \(userInfo)")
// Extract the title and body from userInfo
var title = "Default Title"
var body = "Default Body"
if let aps = userInfo["aps"] as? [String: Any],
let alert = aps["alert"] as? [String: Any] {
title = alert["title"] as? String ?? title
body = alert["body"] as? String ?? body
}
// Extract the media URL from userInfo
if let mediaUrl = userInfo["notificationMediaUrl"] as? String {
print("Media URL: \(mediaUrl)")
Helper.setImageUrl(username: mediaUrl)
// Download the image data
if let url = URL(string: mediaUrl) {
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error downloading image: \(error.localizedDescription)")
return
}
guard let data = data, let image = UIImage(data: data) else {
print("Could not convert data to image.")
return
}
// Create a temporary file URL for the image
let temporaryDirectory = FileManager.default.temporaryDirectory
let imageURL = temporaryDirectory.appendingPathComponent(UUID().uuidString + ".jpg")
// Write the image data to the temporary file
do {
try data.write(to: imageURL)
// Create the attachment
let attachment = try UNNotificationAttachment(identifier: "imageAttachment", url: imageURL, options: nil)
// Create the notification content
let content = UNMutableNotificationContent()
content.title = title // Use the extracted title
content.body = body // Use the extracted body
content.sound = UNNotificationSound.default
content.categoryIdentifier = "notificationWithMedia"
content.attachments = [attachment]
// Create a trigger for the notification (immediate in this case)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
// Create the request
let request = UNNotificationRequest(identifier: UUID().uuidString,
content: content,
trigger: trigger)
// Add the notification request to the notification center
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error adding notification: \(error.localizedDescription)")
}
}
} catch {
print("Error saving image data: \(error.localizedDescription)")
}
}.resume()
}
} else {
print("Media URL not found.")
}
}
private func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) async {
print("Received remote notification: \(userInfo)")
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
processNotificationContent(userInfo: userInfo, completionHandler: completionHandler)
}
private func processNotificationContent(userInfo: [AnyHashable: Any], completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let content = UNMutableNotificationContent()
if let aps = userInfo["aps"] as? [String: Any] {
if let alert = aps["alert"] as? [String: Any] {
content.title = alert["title"] as? String ?? "Default Title"
content.body = alert["body"] as? String ?? "Default Body"
} else {
content.title = "Default Title"
content.body = "Default Body"
}
} else {
content.title = "Default Title"
content.body = "Default Body"
}
content.sound = UNNotificationSound.default
if let mediaUrlString = userInfo["notificationMediaUrl"] as? String, let mediaUrl = URL(string: mediaUrlString) {
URLSession.shared.dataTask(with: mediaUrl) { data, response, error in
guard error == nil, let data = data else {
DispatchQueue.main.async {
// completionHandler([.alert, .sound])
}
return
}
// Create a temporary file URL for the image
let imageTempUrl = FileManager.default.temporaryDirectory.appendingPathComponent("image.jpg")
do {
try data.write(to: imageTempUrl)
let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: imageTempUrl, options: nil)
content.attachments = [attachment]
} catch {
print("Error creating attachment: \(error)")
}
// Create a request with a unique identifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error adding notification: \(error)")
}
DispatchQueue.main.async {
//completionHandler([.alert, .sound])
}
}
}.resume()
} else {
DispatchQueue.main.async {
completionHandler([.alert, .sound])
}
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let urlString = userInfo["url"] as? String, let url = URL(string: urlString) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
if(!Helper.getImageUrl().isEmpty) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewControllerIdentifier = "HomeVC"
let viewController = storyboard.instantiateViewController(withIdentifier: viewControllerIdentifier)
window?.rootViewController = viewController
window?.makeKeyAndVisible()
}
completionHandler()
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("APNs registration failed: \(error)")
}
private func registerForPushNotifications(_ application: UIApplication) {
if #available(iOS 10, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
if granted {
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
} else {
// Define your custom actions
let viewAction = UNNotificationAction(identifier: "VIEW_ACTION",
title: "View",
options: [])
let category = UNNotificationCategory(identifier: "notificationWithMedia",
actions: [viewAction],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
}
}
Вот мое расширение NotificationServiceExtension: -
import UserNotifications
import MobileCoreServices
import UniformTypeIdentifiers
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
let bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
// Check for media URL
if let mediaUrlString = bestAttemptContent?.userInfo["notificationMediaUrl"] as? String,
let mediaUrl = URL(string: mediaUrlString) {
downloadImage(from: mediaUrl) { attachment in
if let attachment = attachment {
bestAttemptContent?.attachments = [attachment]
}
contentHandler(bestAttemptContent!)
}
} else {
contentHandler(bestAttemptContent!)
}
}
private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
completion(nil)
return
}
let temporaryDirectory = FileManager.default.temporaryDirectory
let fileURL = temporaryDirectory.appendingPathComponent(UUID().uuidString + ".jpg")
do {
try data.write(to: fileURL)
let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: fileURL, options: nil)
completion(attachment)
} catch {
print("Error creating attachment: \(error)")
completion(nil)
}
}.resume()
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... os-swift-5
Удаленное уведомление с изображением во время завершения работы приложения iOS Swift 5 ⇐ IOS
Программируем под IOS
1729968718
Anonymous
Я реализую push-уведомление Apple в своем приложении, оно реализовано успешно, но я столкнулся с проблемой, когда мое приложение завершило работу: мы не получаем никаких уведомлений, но если мое приложение открывается, мы успешно получаем уведомление с изображением.< /p>
Я также реализую расширение службы уведомлений и расширение контента уведомлений.
Вот мой код AppDelegate:
import UIKit
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Request notification permission
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if let error = error {
print("Error requesting notification authorization: \(error)")
}
if granted {
DispatchQueue.main.async {
self.registerForPushNotifications(application)
}
}
}
UNUserNotificationCenter.current().delegate = self
window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewControllerIdentifier = Helper.getCurrentAuthentication().authenticationMeta != nil ? "HomeVC" : "LoginVc"
let viewController = storyboard.instantiateViewController(withIdentifier: viewControllerIdentifier)
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { String(format: "%02.2hhx", $0) }
let deviceTokenString = tokenParts.joined()
print("Device Token: \(deviceTokenString)")
Helper.setFCMToken(fcmToken: deviceTokenString)
}
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]
) {
print("Received remote notification: \(userInfo)")
// Extract the title and body from userInfo
var title = "Default Title"
var body = "Default Body"
if let aps = userInfo["aps"] as? [String: Any],
let alert = aps["alert"] as? [String: Any] {
title = alert["title"] as? String ?? title
body = alert["body"] as? String ?? body
}
// Extract the media URL from userInfo
if let mediaUrl = userInfo["notificationMediaUrl"] as? String {
print("Media URL: \(mediaUrl)")
Helper.setImageUrl(username: mediaUrl)
// Download the image data
if let url = URL(string: mediaUrl) {
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error downloading image: \(error.localizedDescription)")
return
}
guard let data = data, let image = UIImage(data: data) else {
print("Could not convert data to image.")
return
}
// Create a temporary file URL for the image
let temporaryDirectory = FileManager.default.temporaryDirectory
let imageURL = temporaryDirectory.appendingPathComponent(UUID().uuidString + ".jpg")
// Write the image data to the temporary file
do {
try data.write(to: imageURL)
// Create the attachment
let attachment = try UNNotificationAttachment(identifier: "imageAttachment", url: imageURL, options: nil)
// Create the notification content
let content = UNMutableNotificationContent()
content.title = title // Use the extracted title
content.body = body // Use the extracted body
content.sound = UNNotificationSound.default
content.categoryIdentifier = "notificationWithMedia"
content.attachments = [attachment]
// Create a trigger for the notification (immediate in this case)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
// Create the request
let request = UNNotificationRequest(identifier: UUID().uuidString,
content: content,
trigger: trigger)
// Add the notification request to the notification center
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error adding notification: \(error.localizedDescription)")
}
}
} catch {
print("Error saving image data: \(error.localizedDescription)")
}
}.resume()
}
} else {
print("Media URL not found.")
}
}
private func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) async {
print("Received remote notification: \(userInfo)")
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
processNotificationContent(userInfo: userInfo, completionHandler: completionHandler)
}
private func processNotificationContent(userInfo: [AnyHashable: Any], completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let content = UNMutableNotificationContent()
if let aps = userInfo["aps"] as? [String: Any] {
if let alert = aps["alert"] as? [String: Any] {
content.title = alert["title"] as? String ?? "Default Title"
content.body = alert["body"] as? String ?? "Default Body"
} else {
content.title = "Default Title"
content.body = "Default Body"
}
} else {
content.title = "Default Title"
content.body = "Default Body"
}
content.sound = UNNotificationSound.default
if let mediaUrlString = userInfo["notificationMediaUrl"] as? String, let mediaUrl = URL(string: mediaUrlString) {
URLSession.shared.dataTask(with: mediaUrl) { data, response, error in
guard error == nil, let data = data else {
DispatchQueue.main.async {
// completionHandler([.alert, .sound])
}
return
}
// Create a temporary file URL for the image
let imageTempUrl = FileManager.default.temporaryDirectory.appendingPathComponent("image.jpg")
do {
try data.write(to: imageTempUrl)
let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: imageTempUrl, options: nil)
content.attachments = [attachment]
} catch {
print("Error creating attachment: \(error)")
}
// Create a request with a unique identifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error adding notification: \(error)")
}
DispatchQueue.main.async {
//completionHandler([.alert, .sound])
}
}
}.resume()
} else {
DispatchQueue.main.async {
completionHandler([.alert, .sound])
}
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let urlString = userInfo["url"] as? String, let url = URL(string: urlString) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
if(!Helper.getImageUrl().isEmpty) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewControllerIdentifier = "HomeVC"
let viewController = storyboard.instantiateViewController(withIdentifier: viewControllerIdentifier)
window?.rootViewController = viewController
window?.makeKeyAndVisible()
}
completionHandler()
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("APNs registration failed: \(error)")
}
private func registerForPushNotifications(_ application: UIApplication) {
if #available(iOS 10, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
if granted {
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
} else {
// Define your custom actions
let viewAction = UNNotificationAction(identifier: "VIEW_ACTION",
title: "View",
options: [])
let category = UNNotificationCategory(identifier: "notificationWithMedia",
actions: [viewAction],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
}
}
Вот мое расширение NotificationServiceExtension: -
import UserNotifications
import MobileCoreServices
import UniformTypeIdentifiers
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
let bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
// Check for media URL
if let mediaUrlString = bestAttemptContent?.userInfo["notificationMediaUrl"] as? String,
let mediaUrl = URL(string: mediaUrlString) {
downloadImage(from: mediaUrl) { attachment in
if let attachment = attachment {
bestAttemptContent?.attachments = [attachment]
}
contentHandler(bestAttemptContent!)
}
} else {
contentHandler(bestAttemptContent!)
}
}
private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
completion(nil)
return
}
let temporaryDirectory = FileManager.default.temporaryDirectory
let fileURL = temporaryDirectory.appendingPathComponent(UUID().uuidString + ".jpg")
do {
try data.write(to: fileURL)
let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: fileURL, options: nil)
completion(attachment)
} catch {
print("Error creating attachment: \(error)")
completion(nil)
}
}.resume()
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79124422/remote-notification-with-image-while-app-terminate-ios-swift-5[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия