푸시 알림에서 앱이 시작/열렸는지 탐지
푸시 알림에서 앱이 실행/열렸는지 알 수 있습니까?
런칭 이벤트는 여기서 확인할 수 있을 것 같습니다.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}
하지만 앱이 백그라운드에 있을 때 푸시 알림에서 열렸음을 감지하려면 어떻게 해야 합니까?
자세한 내용은 다음 코드를 참조하십시오.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//opened from a push notification when the app was on background
}
}
와 같은
-(void)application:(UIApplication *)application didReceiveLocalNotification (UILocalNotification *)notification
늦었지만 유용할 수도 있습니다.
앱이 실행되지 않을 때
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
라고 합니다.
푸시 알림을 확인해야 하는 위치
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
NSLog(@"app recieved notification from remote%@",notification);
[self application:application didReceiveRemoteNotification:notification];
} else {
NSLog(@"app did not recieve notification");
}
앱이 실행된 후 보기를 잘못 업데이트한 것이 문제였습니다.여기에는 혼란스러운 복잡한 라이프사이클 방법의 순서가 있습니다.
라이프사이클 방법
iOS 10에 대한 테스트를 통해 다양한 사례에 대한 다음과 같은 라이프사이클 방법을 확인했습니다.
DELEGATE METHODS CALLED WHEN OPENING APP
Opening app when system killed or user killed
didFinishLaunchingWithOptions
applicationDidBecomeActive
Opening app when backgrounded
applicationWillEnterForeground
applicationDidBecomeActive
DELEGATE METHODS CALLED WHEN OPENING PUSH
Opening push when system killed
[receiving push causes didFinishLaunchingWithOptions (with options) and didReceiveRemoteNotification:background]
applicationWillEnterForeground
didReceiveRemoteNotification:inactive
applicationDidBecomeActive
Opening push when user killed
didFinishLaunchingWithOptions (with options)
didReceiveRemoteNotification:inactive [only completionHandler version]
applicationDidBecomeActive
Opening push when backgrounded
[receiving push causes didReceiveRemoteNotification:background]
applicationWillEnterForeground
didReceiveRemoteNotification:inactive
applicationDidBecomeActive
그 문제는
자, 이제 우리는 다음을 해야 합니다.
- 사용자가 푸시에서 앱을 열 것인지 확인
- 푸시 상태를 기준으로 보기 업데이트
- 이후에 열리면 사용자가 같은 위치로 돌아가지 않도록 상태를 지웁니다.
까다로운 점은 애플리케이션이 실제로 활성화될 때 보기를 업데이트해야 한다는 것입니다. 이는 모든 경우에 동일한 라이프사이클 방법입니다.
솔루션 개요
NAT 솔루션의 주요 구성 요소는 다음과 같습니다.
- a 장a
notificationUserInfo인스턴스 변수가 AppDelegate에 있습니다. - 트
notificationUserInfo = nil두applicationWillEnterForeground그리고.didFinishLaunchingWithOptions. - 트
notificationUserInfo = userInfodidReceiveRemoteNotification:inactive applicationDidBecomeActive방법을 상항사지정메서호출드자라고 .openViewFromNotification그리고 패스self.notificationUserInfo.한다면self.notificationUserInfo을 선택한 일찍 합니다. nil에 있는 . 그렇지 않으면 에서 발견된 알림 상태를 기준으로 보기를 엽니다.self.notificationUserInfo.
설명.
에서 열 때 시에서열때푸때▁from열▁when▁opening.didFinishLaunchingWithOptions또는applicationWillEnterForeground 항상직호니다출됩에 앞에 됩니다.didReceiveRemoteNotification:inactive따라서 먼저 이러한 방법으로 notificationUserInfo를 재설정하여 오래된 상태가 발생하지 않도록 합니다.그럼, 만약에didReceiveRemoteNotification:inactive 우는우밀여는것을알기때우설문리다정는니습했에리어리가서▁is다▁set설니▁we▁called정습▁we했우▁so리우▁we.self.notificationUserInfo그 다음에 에 의해 픽업됩니다.applicationDidBecomeActive오른쪽 보기로 사용자를 전달합니다.
마지막 사례는 사용자가 앱 전환기 내에서 앱을 연 다음(즉, 앱이 전경에 있는 동안 홈 버튼을 두 번 두드리면) 푸시 알림을 받는 경우입니다.에는 이경에만만didReceiveRemoteNotification:inactive이 호출되고 WillEnterForground도 FinishLaunching도 호출되지 않으므로 이 경우를 처리하려면 특수 상태가 필요합니다.
이게 도움이 되길 바랍니다.
이 포스트는 잘 닳아서...그러나 다양한 의견에서 지적된 바와 같이 문제에 대한 실제 해결책은 여전히 누락되어 있습니다.
원래 질문은 푸시 알림에서 앱이 시작/열린 시기를 감지하는 것입니다(예: 사용자가 알림을 탭하는 경우).이 사건을 다루는 답은 하나도 없습니다.
했을 때 할 수 .application:didReceiveRemoteNotification...
알림이 수신되면 호출되고 사용자가 알림을 탭하면 다시 호출됩니다.이것 때문에, 당신은 단지 보기만 해도 알 수 없습니다.UIApplicationState사용자가 그것을 두드렸는지 여부.
한콜앱 '드스타트상다없'에서 스타트'을 더 .application:didFinishLaunchingWithOptions...~하듯이application:didReceiveRemoteNotification...iOS 9+에서 실행된 후 다시 호출됩니다(아마도 8).
그렇다면, 사용자 탭이 일련의 이벤트를 시작했는지 어떻게 알 수 있을까요? 또는 콜드 해당 입니다.application:didReceiveRemoteNotification...할 수 .0.1초부터 시작합니다.
스위프트 2.x
class AppDelegate: UIResponder, UIApplicationDelegate {
var wakeTime : NSDate = NSDate() // when did our application wake up most recently?
func applicationWillEnterForeground(application: UIApplication) {
// time stamp the entering of foreground so we can tell how we got here
wakeTime = NSDate()
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// ensure the userInfo dictionary has the data you expect
if let type = userInfo["type"] as? String where type == "status" {
// IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
if application.applicationState != UIApplicationState.Background && NSDate().timeIntervalSinceDate(wakeTime) < 0.1 {
// User Tap on notification Started the App
}
else {
// DO stuff here if you ONLY want it to happen when the push arrives
}
completionHandler(.NewData)
}
else {
completionHandler(.NoData)
}
}
}
스위프트 3
class AppDelegate: UIResponder, UIApplicationDelegate {
var wakeTime : Date = Date() // when did our application wake up most recently?
func applicationWillEnterForeground(_ application: UIApplication) {
// time stamp the entering of foreground so we can tell how we got here
wakeTime = Date()
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// ensure the userInfo dictionary has the data you expect
if let type = userInfo["type"] as? String, type == "status" {
// IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
if application.applicationState != UIApplicationState.background && Date().timeIntervalSince(wakeTime) < 0.1 {
// User Tap on notification Started the App
}
else {
// DO stuff here if you ONLY want it to happen when the push arrives
}
completionHandler(.newData)
}
else {
completionHandler(.noData)
}
}
}
iOS 9+에서 두 가지 경우(배경 앱, 실행 중이지 않는 앱) 모두 테스트해봤는데 매력적으로 작동합니다. 0.1s도 꽤 보수적이고 실제 값은 ~0.002s이므로 0.01도 괜찮습니다.
앱이 종료되고 사용자가 푸시 알림을 탭하는 경우
public func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] != nil {
print("from push")
}
}
앱이 백그라운드에 있고 사용자가 푸시 알림을 탭하는 경우
사용자가 시스템에 표시된 경고에서 앱을 열면 앱이 포그라운드에 진입하려고 할 때 시스템이 이 메서드를 다시 호출하여 사용자 인터페이스를 업데이트하고 알림과 관련된 정보를 표시할 수 있습니다.
public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
if application.applicationState == .inactive {
print("from push")
}
}
앱에 따라 자동 푸시 기능도 제공됩니다.content-available東京의 aps그러니 이것도 알아두세요 :) https://stackoverflow.com/a/33778990/1418457 을 참조하세요.
Swift 2.0 '실행되지 않음' 상태(로컬 및 원격 알림)
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Handle notification
if (launchOptions != nil) {
// For local Notification
if let localNotificationInfo = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
if let something = localNotificationInfo.userInfo!["yourKey"] as? String {
self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something))
}
} else
// For remote Notification
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as! [NSObject : AnyObject]? {
if let something = remoteNotification["yourKey"] as? String {
self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something))
}
}
}
return true
}
application:didReceiveRemoteNotification:앱이 포그라운드 또는 백그라운드에 있을 때 알림을 받았는지 확인합니다.
백그라운드에서 수신된 경우 알림에서 앱을 실행합니다.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
NSLog(@"Notification received by running app");
} else {
NSLog(@"App opened from Notification");
}
}
신속한 작업:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background {
//opened from a push notification when the app was in the background
}
}
Xamarin 사용자를 위해 이 글을 게시합니다.
할 수 은 푸시알통해앱지여감핵지입니다.AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options)방법 및 옵션 사전이 제공됩니다.
알림인 경우 에 이 되어 있습니다.UIApplication.LaunchOptionsLocalNotificationKey.
원격 통보인 경우에는 다음과 같습니다.UIApplication.LaunchOptionsRemoteNotificationKey.
가 가다음일때키일 때.LaunchOptionsLocalNotificationKey이 그물는유형다니입니다.UILocalNotification그런 다음 통지를 확인하고 특정 통지를 확인할 수 있습니다.
설명:UILocalNotification로.UNNotificationRequest 테스트 시 requestId를 수 있도록 .UILocalNotification논리에 기반을 둔 특정 requestId를 사용할 수 있습니다.
10+를 하여 위치 할 때 알림을 생성하는 했습니다.UNUserNotificationCenter의AddNotificationRequest&UNMutableNotificationContent 때), 알림에서 알림을 이실내고있때않을지앱다죽였알때다그탭서림있니실습을하될포행여고다하함에여을음리히터림알센전사고전은행되을것그가▁the▁stillary▁contains▁that▁when▁is▁diction▁the▁the다▁that▁by니내▁app(,▁thei있습▁tapping▁the▁it▁is▁and▁launched▁not고하▁running포▁in▁not앱ification▁killed함다이을▁center음),▁not사여ification.UILocalNotificaiton물건.
즉, 알림 기반 실행을 확인하는 내 코드가 iOS8 및 iOS10+ 기기에서 작동합니다.
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
_logger.InfoFormat("FinishedLaunching");
if(options != null)
{
if (options.ContainsKey(UIApplication.LaunchOptionsLocalNotificationKey))
{
//was started by tapping a local notification when app wasn't previously running.
//works if using UNUserNotificationCenter.Current.AddNotificationRequest OR UIApplication.SharedApplication.PresentLocalNotificationNow);
var localNotification = options[UIApplication.LaunchOptionsLocalNotificationKey] as UILocalNotification;
//I would recommended a key such as this :
var requestId = localNotification.UserInfo["RequestId"].ToString();
}
}
return true;
}
예, 다음 방법으로 appDelegate에서 탐지할 수 있습니다.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
/* your Code*/
}
로컬 알림의 경우:
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
/* your Code*/
}
누군가가 신속한 3번의 답을 원한다면,
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
switch application.applicationState {
case .active:
//app is currently active, can update badges count here
break
case .inactive:
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
break
case .background:
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
break
default:
break
}
}
iOS 13 이상을 실행 중인 경우 SceneDelegate에서 다음 코드를 사용합니다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let notificationResponse = connectionOptions.notificationResponse else { return }
let pushTitle = notificationResponse.notification.request.content.title
let pushSubtitle = notificationResponse.notification.request.content.subtitle
let pushBody = notificationResponse.notification.request.content.body
// do your staff here
}
가지고 계신다면,SceneDelegate앱에서 아래 코드를 사용하여 로컬/원격 알림을 관리해야 합니다. 앱이 종료/종료되고 알림을 탭하지 않고 응용 프로그램을 열 수 있습니다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//Handle Notification Response
guard let notifiResponse = connectionOptions.notificationResponse else { return }
if notifiResponse.notification.request.trigger is UNTimeIntervalNotificationTrigger { //Local Notification
Messaging.messaging().appDidReceiveMessage(notifiResponse.notification.request.content.userInfo)
print("Receive Local Notifications")
}
else if notifiResponse.notification.request.trigger is UNPushNotificationTrigger{ //Remote Notification
print("Receive Remote Notifications")
}
}
다음을 사용합니다.AppDelegate응용 프로그램이 백그라운드/포그라운드 상태일 때 로컬/원격 알림을 관리합니다.
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.notification.request.trigger is UNTimeIntervalNotificationTrigger{
print("Receive Local Notifications")
}
else if response.notification.request.trigger is UNPushNotificationTrigger{
print("Receive Remote Notifications")
}
let userInfo = response.notification.request.content.userInfo
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("willPresent Notifications")
if notification.request.trigger is UNTimeIntervalNotificationTrigger{
print("Receive Local Notifications")
}
else {
print("Receive Remote Notifications")
}
completionHandler([.banner, .list, .sound])
}
}
다음에 대한 설명서에서 직접 확인할 수 있습니다.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo:nil
앱이 실행 중이고 원격 알림을 받으면 앱은 이 메서드를 호출하여 알림을 처리합니다.
이 방법을 구현하려면 알림을 사용하여 적절한 조치를 취해야 합니다.
그리고 조금 후에
푸시 알림이 도착했을 때 앱이 실행되지 않으면 메소드는 앱을 실행하고 실행 옵션 사전에 적절한 정보를 제공합니다.
앱은 푸시 알림을 처리하기 위해 이 메서드를 호출하지 않습니다.
대신에, 당신의 구현은
application:willFinishLaunchingWithOptions:
또는
application:didFinishLaunchingWithOptions:
메서드는 푸시 알림 페이로드 데이터를 가져오고 적절하게 응답해야 합니다.
먼저 제가 직접 작성한 상태 차트를 사용하여 보다 정확하게 시각화하고 다른 모든 상태를 고려해 보겠습니다. https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASlT6ZkU3iLdZnOZoevkMzOeng7gs31IFhD-L/pubhtml?gid=0&single=true
이 차트를 사용하면 가능한 거의 모든 사용 사례에서 작동하는 강력한 알림 처리 시스템을 개발하기 위해 실제로 무엇이 필요한지 알 수 있습니다.
완전한 솔루션 ↓
- didReceiveRemoteNotification에 알림 페이로드 저장
- 응용 프로그램에서 저장된 알림 지우기WillEnterForground 및 did LaunchingWithOptions
- Control Center/Notification Center가 풀된 경우를 처리하려면 willResignActiveCalled 플래그를 사용하여 처음에 false로 설정하고, applicationWillResignActive 메서드에서 이를 true로 설정합니다.
- receiveRemoteNotification 메서드에서 willResignActiveCalled가 false일 때만 알림(userInfo)을 저장합니다.
- applicationDidEnterBackground 및 applicationDidBecomeActive 메서드에서 ResignActiveCalled가 false로 재설정됩니다.
참고: Eric의 답변에 대한 코멘트에도 유사한 답변이 제안되지만, 상태 시트는 제가 앱에서 했던 것처럼 가능한 모든 시나리오를 찾는 데 도움이 됩니다.
아래에서 전체 코드를 찾고 특정 사례가 처리되지 않을 경우 아래에서 의견을 제시하십시오.
앱 대표자
class AppDelegate: UIResponder, UIApplicationDelegate {
private var willResignActiveCalled = false
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
NotificationUtils.shared.notification = nil
return true
}
func applicationWillResignActive(_ application: UIApplication) {
willResignActiveCalled = true
}
func applicationDidEnterBackground(_ application: UIApplication) {
willResignActiveCalled = false
}
func applicationWillEnterForeground(_ application: UIApplication) {
NotificationUtils.shared.notification = nil
}
func applicationDidBecomeActive(_ application: UIApplication) {
willResignActiveCalled = false
NotificationUtils.shared.performActionOnNotification()
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if !willResignActiveCalled { // Check if app is in inactive by app switcher, control center, or notification center
NotificationUtils.shared.handleNotification(userInfo: userInfo)
}
}
}
NotificationUtils : 응용 프로그램의 다른 부분으로 이동하여 데이터베이스(CoreData/Realm)를 처리하고 알림을 수신할 때 수행해야 하는 모든 작업을 수행할 수 있는 모든 코드를 작성할 수 있습니다.
class NotificationUtils {
static let shared = NotificationUtils()
private init() {}
var notification : [AnyHashable: Any]?
func handleNotification(userInfo : [AnyHashable: Any]){
if UIApplication.shared.applicationState == UIApplicationState.active {
self.notification = userInfo //Save Payload
//Show inApp Alert/Banner/Action etc
// perform immediate action on notification
}
else if UIApplication.shared.applicationState == UIApplicationState.inactive{
self.notification = userInfo
}
else if UIApplication.shared.applicationState == UIApplicationState.background{
//Process notification in background,
// Update badges, save some data received from notification payload in Databases (CoreData/Realm)
}
}
func performActionOnNotification(){
// Do all the stuffs like navigating to ViewControllers, updating Badges etc
defer {
notification = nil
}
}
}
M.오스만의 대답은 장면 위임이 포함되지 않은 앱의 경우 정답입니다 장면 위임 앱의 경우 iOS 13에서 작동했습니다.
여기 윌 연결 장면에 기록되어야 할 코드가 있습니다.
if connectionOptions.notificationResponse == nil {
//Not opened from push notification
} else {
//Opened from push notification
}
이전 버전을 지원하기 위한 앱 대리자의 코드가 실행을 완료했습니다(옵션 포함).
let notification = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification]
if (notification != nil) {
//Launched from push notification
} else {
//Launch from other source
}
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
print("Push notification received: \(data)")
if let info = data["aps"] as? Dictionary<String, AnyObject> {
let alertMsg = info["alert"] as! String
print(alertMsg)
switch application.applicationState {
case .active:
print("do stuff in case App is active")
case .background:
print("do stuff in case App is in background")
// navigateToChatDetailViewControler(pushdata: data)
case .inactive:
print("do stuff in case App is inactive")
// navigateToChatDetailViewControler(pushdata: data)
}
}
}
신뢰할 수 있는 방법은 단 한 가지이며 iOS 10+에서만 작동합니다.
용사를 합니다.UNUserNotificationCenterUNUserNotificationCenterDelegate방법:
- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
//Here you can get your original push if you need to
NSDictionary* pusDict = response.notification.request.content.userInfo;
if ([response.actionIdentifier isEqualToString: UNNotificationDefaultActionIdentifier]) {
//User tapped the notification
} else if ([response.actionIdentifier isEqualToString: UNNotificationDismissActionIdentifier]) {
//User dismissed the notification
} else if ([response.actionIdentifier isEqualToString: MYCustomActionId]) {
//User chose my custom defined action
}
...
}
2021, Swift 5, 로컬 알림만:
UNUserNotificationCenter.current().delegate = self
extension YourClass: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let notificationIdentifier = response.notification.request.identifier
// If this is called, then your app was opened from a local notification with this identifier
}
}
// shanegao's code in Swift 2.0
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
{
if ( application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background ){
print("opened from a push notification when the app was on background")
}else{
print("opened from a push notification when the app was on foreground")
}
}
이 질문의 문제는 앱을 "오픈"하는 것이 잘 정의되지 않았다는 것입니다.앱이 실행되지 않는 상태에서 콜드 런칭되거나 비활성 상태(예: 다른 앱에서 다시 전환)에서 다시 활성화됩니다.다음은 가능한 모든 상태를 구분하는 솔루션입니다.
typedef NS_ENUM(NSInteger, MXAppState) {
MXAppStateActive = 0,
MXAppStateReactivated = 1,
MXAppStateLaunched = 2
};
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ... your custom launch stuff
[[MXDefaults instance] setDateOfLastLaunch:[NSDate date]];
// ... more custom launch stuff
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// Through a lot of trial and error (by showing alerts), I can confirm that on iOS 10
// this method is only called when the app has been launched from a push notification
// or when the app is already in the Active state. When you receive a push
// and then launch the app from the icon or apps view, this method is _not_ called.
// So with 99% confidence, it means this method is called in one of the 3 mutually exclusive cases
// 1) we are active in the foreground, no action was taken by the user
// 2) we were 'launched' from an inactive state (so we may already be in the main section) by a tap
// on a push notification
// 3) we were truly launched from a not running state by a tap on a push notification
// Beware that cases (2) and (3) may both show UIApplicationStateInactive and cant be easily distinguished.
// We check the last launch date to distinguish (2) and (3).
MXAppState appState = [self mxAppStateFromApplicationState:[application applicationState]];
//... your app's logic
}
- (MXAppState)mxAppStateFromApplicationState:(UIApplicationState)state {
if (state == UIApplicationStateActive) {
return MXAppStateActive;
} else {
NSDate* lastLaunchDate = [[MXDefaults instance] dateOfLastLaunch];
if (lastLaunchDate && [[NSDate date] timeIntervalSinceDate:lastLaunchDate] < 0.5f) {
return MXAppStateLaunched;
} else {
return MXAppStateReactivated;
}
}
return MXAppStateActive;
}
그리고.MXDefaults에 대한 작은 포장지일 뿐입니다.NSUserDefaults.
Xcode 10 Swift 4.2
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let state : UIApplicationState = application.applicationState
if (state == .Inactive || state == .Background) {
// coming from background
} else {
// App is running in foreground
}
}
스위프트 5에 대한 M.오스만의 답변. (NSLog 사용은 더 이상 권장되지 않습니다.
표시에 필요한 모든 항목을 설정한 후 다음을 추가합니다.RootViewController의 신의에서.application(_:didReceiveRemoteNotification)첫 번째 시작과 시작의 배경 유형을 구별할 수 있는 논리를 추가해야 합니다.
if let launchOptions = launchOptions,
let notification = launchOptions[UIApplicationLaunchOptionsKey.remoteNotification]
as? [AnyHashable : Any] {
NSLog("app recieved notification from remote \(notification)")
self.application(application, didReceiveRemoteNotification: notification)
} else {
NSLog("app did not recieve notification")
}
이 문제를 해결하기 위한 Swift의 다른 구체적인 답변은 다음에서 확인할 수 있습니다: 알림이 탭될 때 Swift 3의 시작 옵션을 처리하는 방법은 무엇입니까? 구문 문제를 가져오는 중
사용할 수 있는 항목:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
원격 푸시 알림을 처리합니다.
설명서를 확인하십시오.
아직 시도해보지는 않았지만 직접 알림을 보내주실 수 있나요?http://nshipster.com/nsnotification-and-nsnotificationcenter/
Swift 사용자의 경우:
를 열 때 에서 해야 합니다.didFinishLaunchingWithOptions 예:
let directVc: directVC! = directVC(nibName:"directVC", bundle: nil)
let pushVc: pushVC! = pushVC(nibName:"pushVC", bundle: nil)
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
self.navigationController = UINavigationController(rootViewController: pushVc!)
} else {
self.navigationController = UINavigationController(rootViewController: directVc!)
}
self.window!.rootViewController = self.navigationController
위해서swift
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){
++notificationNumber
application.applicationIconBadgeNumber = notificationNumber;
if let aps = userInfo["aps"] as? NSDictionary {
var message = aps["alert"]
println("my messages : \(message)")
}
}
앱이 셰인가오로 백그라운드에 있을 때 사용할 수 있습니다.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//opened from a push notification when the app was on background
}
}
그러나 응용 프로그램을 시작하고 앱이 닫히고 응용 프로그램을 디버그하려면 Edit Scheme(편집)으로 이동하여 왼쪽 메뉴에서 Run(실행)을 선택한 다음 실행 파일이 시작될 때까지 기다렸다가 응용 프로그램 실행을 선택하면 푸시 알림을 클릭할 수 있습니다.
구성표 편집 > 실행 > 실행 파일이 시작될 때까지 기다립니다.
빠른 속도:
푸시 알림(배경 가져오기 포함)을 실행하고 있습니다.앱이 백그라운드에서 푸시 알림을 받으면 appDelegate에서 didReceiveRemoteNotification이 두 번 호출된다는 것을 알게 되었습니다. 알림을 받았을 때와 사용자가 알림 알림을 클릭했을 때입니다.
알림 알림이 클릭되었는지 여부를 감지하려면 applicationState 원시 값 == 1 inside가 appDelegate에서 RemoteNotification을 받았는지 확인하십시오.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject: AnyObject]) {
// If not from alert click applicationState(1)
if (application.applicationState.rawValue != 1) {
// Run your code here
}
}
이것이 도움이 되길 바랍니다.
언급URL : https://stackoverflow.com/questions/16393673/detect-if-the-app-was-launched-opened-from-a-push-notification
'programing' 카테고리의 다른 글
| 오류: mongodb를 연결하는 윈도우즈에서 유닉스 소켓을 지원하지 않습니다. (0) | 2023.07.09 |
|---|---|
| 콘다 명령을 찾을 수 없습니다. (0) | 2023.07.09 |
| Git가 향후 파일 수정사항을 무시하도록 하려면 어떻게 해야 합니까? (0) | 2023.07.09 |
| 두 개의 열을 기준으로 두 개의 데이터 프레임을 결합하려면 어떻게 해야 합니까? (0) | 2023.07.09 |
| 결합된 ggplot에 대한 공통 범례 추가 (0) | 2023.07.09 |