ios - alerta - swift popup
Mostrar una alerta cuando la aplicación iOS está en segundo plano (3)
A su pregunta se le escapó la parte más importante relacionada con la aplicación "Uber Partner" que haría las cosas mucho más claras. La aplicación "Uber Partner" es una aplicación Enterprise y no está restringida a las líneas de guía de AppStore.
no obtuvo ningún permiso especial como otras respuestas sugeridas.
Es posible mostrar una vista de alerta usando SBAlertItem
independientemente de la configuración de Sound / Notification, pero si su objetivo final es llegar a la tienda de aplicaciones, desafortunadamente, su aplicación será rechazada por usar API privada.
Quiero mostrar una vista de alerta cuando mi aplicación iOS está en segundo plano (y está usando la ubicación).
Por ejemplo, la aplicación Uber Partner (controlador) muestra una alerta y reproduce un sonido incluso cuando:
- ¡He desactivado las notificaciones!
- ¡Mi iPhone está en modo silencioso!
Soy consciente del enfoque de las notificaciones locales y no funciona si el usuario desactiva / cambia las notificaciones en la configuración. Estoy buscando algo diferente.
Acciones realizadas para alcanzar el estado anterior:
- Conéctese en línea con la aplicación Uber Partner (usted es el conductor)
- Deshabilitar las notificaciones de la aplicación en Configuración
- Mueve la aplicación a segundo plano y espera una solicitud de viaje
- Después de un tiempo, aparece una Solicitud de viaje como una vista de Alerta y se reproduce un sonido en el fondo.
Por supuesto, la aplicación didReceiveRemoteNotification: fetchCompletionHandler:
API puede acceder a las notificaciones remotas silenciosas , incluso si el usuario desactiva las notificaciones en la configuración. Pero, cómo surge la alerta, eso es lo que estoy tratando de descubrir.
Después de un análisis estático del binario, quedó claro que no están usando PKPushRegistry (VOIP), llamadas a NSNotificationCenter no documentadas o SBAlertItem.
Tomó un poco de tiempo encontrarlo, pero en realidad están usando CFUserNotification para las alertas. La clase está documented para Mac, pero privada para iOS.
Encontré el uso haciendo esto:
nm -u ~/Downloads/Payload/UberDriver.app/UberDriver | grep CFUserNotification
La salida es:
_CFUserNotificationCancel
_CFUserNotificationCreate
_CFUserNotificationCreateRunLoopSource
_kCFUserNotificationAlertHeaderKey
_kCFUserNotificationAlertMessageKey
_kCFUserNotificationAlertTopMostKey
_kCFUserNotificationAlternateButtonTitleKey
_kCFUserNotificationDefaultButtonTitleKey
_kCFUserNotificationSoundURLKey
Si grep para PKPushRegistry o para SBAlertItem, ambos devuelven ningún resultado.
Puede usar la clase importando este archivo a su proyecto.
ACTUALIZAR
Tengo un código ''de trabajo'', sin embargo, llama inmediatamente a la función de devolución de llamada (responseFlags configurado en kCFUserNotificationCancelResponse ) sin mostrar la alerta ...
Estoy usando las mismas teclas y llamadas que la aplicación Uber (compare el código a continuación con la lista de arriba), así que debe haber algo más. Seguiré buscando.
#import "CFUserNotification.h"
@interface AppDelegate ()
@property (nonatomic) CFRunLoopSourceRef runLoopSource;
@property (nonatomic) CFUserNotificationRef notification;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
SInt32 error;
NSDictionary *keys = @{(__bridge NSString*)kCFUserNotificationAlertHeaderKey: @"Hello",
(__bridge NSString*)kCFUserNotificationAlertMessageKey: @"World",
(__bridge NSString*)kCFUserNotificationAlertTopMostKey: @YES,
(__bridge NSString*)kCFUserNotificationDefaultButtonTitleKey: @"asdf",
(__bridge NSString*)kCFUserNotificationAlternateButtonTitleKey: @"asdf",
};
self.notification = CFUserNotificationCreate(NULL, 10, kCFUserNotificationPlainAlertLevel, &error, (__bridge CFDictionaryRef)keys);
self.runLoopSource = CFUserNotificationCreateRunLoopSource(NULL, self.notification, NotificationCallback, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), self.runLoopSource, kCFRunLoopCommonModes);
return YES;
}
void NotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) {
NSLog(@"got response: %lu", responseFlags);
}
Me imagino que Uber tiene algunos permisos especiales o utiliza alguna API privada que les permite lograr este comportamiento sin usar notificaciones locales. Aunque no sé cómo Uber implementó esto en su aplicación asociada, puedo hablar un poco sobre cómo funcionan las alertas en la pantalla de inicio.
SpringBoard es la clase de singleton que administra la aplicación SpringBoard (SpringBoard.app), el iniciador de aplicaciones para el iPhone. SpringBoard no usa las UIAlertView
estándar UIAlertView
/ UIAlertController
, ya que no participan en el sistema de alerta de SpringBoard. iOS 5 introdujo SBAlertItem
que se usa para mostrar UIAlertViews en SpringBoard (alertas de notificación de batería, alerta de desbloqueo de Sim, etc.). Apple usa SBAlertItem
para sus alertas de bloqueo y pantalla de inicio, estaré trabajando en el supuesto de que Uber está usando un SBAlertItem
para esta respuesta.
SBAlertItem
tiene un ivar protegido UIAlertView *_alertSheet
. Suponiendo que esto actúe como un UIAlertView
normal, debería poder cambiar las propiedades de esta alerta para que se ajusten a sus necesidades. También leería el proyecto de sustrato Cydia de saurik, específicamente MobileSafety.mm para ver algunos casos de uso. También encontré noweibogoodsleep que proporciona un ejemplo del uso de SBAlertItem
en el SpringBoard.
También encontré SBUserNotificationAlert
, una subclase de SBAlertItem
. Esto parece tener más métodos para facilitar la personalización de alertas que pueden adaptarse a sus necesidades mejor que el SBAlertItem
estándar.
Me doy cuenta de que enganchar a las API privadas probablemente no sea lo que esperabas al hacer esta pregunta. Dado que no sé cómo funciona Uber, solo puedo proporcionar una respuesta a partir de mi experiencia personal al trabajar con dispositivos en tiempo de ejecución y con jailbreak.