iOS
Powiadomienia push
Szukaj…
Składnia
- UIUserNotificationSettings.types: UIUserNotificationType // Maska bitowa typów powiadomień, których może używać Twoja aplikacja
- UIUserNotificationSettings.categories: Set // Zarejestrowane grupy działań aplikacji
Parametry
Parametr | Opis |
---|---|
Informacje użytkownika | Słownik zawierający informacje o zdalnym powiadomieniu, w tym potencjalnie numer identyfikacyjny ikony aplikacji, dźwięk ostrzeżenia, komunikat ostrzeżenia, identyfikator powiadomienia i dane niestandardowe. |
Rejestracja urządzenia do powiadomień push
Aby zarejestrować urządzenie w celu wysyłania powiadomień wypychanych, dodaj następujący kod do pliku AppDelegate w metodzie didFinishLaunchingWithOptions
:
Szybki
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
if UIDevice.currentDevice().systemVersion.compare(v, options: .NumericSearch) == NSOrderedAscending {
// Register for Push Notitications, if running iOS < 8
if application.respondsToSelector("registerUserNotificationSettings:") {
let types:UIUserNotificationType = (.Alert | .Badge | .Sound)
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
// Register for Push Notifications before iOS 8
application.registerForRemoteNotificationTypes(.Alert | .Badge | .Sound)
}
} else {
var center = UNUserNotificationCenter.currentNotificationCenter()
center.delegate = self
center.requestAuthorizationWithOptions((UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)) {(granted: Bool, error: NSError) -> Void in
if !error {
UIApplication.sharedApplication().registerForRemoteNotifications()
// required to get the app to do anything at all about push notifications
print("Push registration success.")
} else {
print("Push registration FAILED")
print("ERROR: \(error.localizedFailureReason!) - \(error.localizedDescription)")
print("SUGGESTIONS: \(error.localizedRecoveryOptions) - \(error.localizedRecoverySuggestion!)")
})
}
return true
}
Cel C
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
if( SYSTEM_VERSION_LESS_THAN( @"10.0" ) )
{
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
{
// iOS 8 Notifications
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
}
else
{
// iOS < 8 Notifications
[application registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
}
else
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if( !error )
{
[[UIApplication sharedApplication] registerForRemoteNotifications]; // required to get the app to do anything at all about push notifications
NSLog( @"Push registration success." );
}
else
{
NSLog( @"Push registration FAILED" );
NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription );
NSLog( @"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
}
}];
}
//to check if your App lunch from Push notification
//---------------------------------------------------
//Handel Push notification
if (launchOptions != nil)
{
// Here app will open from pushnotification
//RemoteNotification
NSDictionary* dictionary1 = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
//LocalNotification
NSDictionary* dictionary2 = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (dictionary1 != nil)
{
//RemoteNotification Payload
NSLog(@"Launched from push notification: %@", dictionary1);
//here handle your push notification
}
if (dictionary2 != nil)
{
NSLog(@"Launched from dictionary2dictionary2dictionary2 notification: %@", dictionary2);
double delayInSeconds = 7;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// [self addMessageFromRemoteNotification:dictionary2 updateUI:NO];
});
}
}
else
{}
//------------------------------------------------
Powyższy kod będzie próbował komunikować się z serwerem APN, aby uzyskać token urządzenia (warunkiem jest, że masz włączone APN w swoim profilu informacyjnym iOS).
Po ustanowieniu niezawodnego połączenia z serwerem APN serwer zapewnia token urządzenia.
Po dodaniu powyższego kodu dodaj te metody do klasy AppDelegate
:
Szybki
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print("DEVICE TOKEN = \(deviceToken)")
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}
Cel C
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString * deviceTokenString = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
NSLog(@"The generated device token string is : %@",deviceTokenString);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error.description);
}
Powyższe metody są wywoływane zgodnie ze scenariuszem powodzenia lub niepowodzenia rejestracji.
Wywołanie scenariusza sukcesu:
Szybki
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print("DEVICE TOKEN = \(deviceToken)")
}
W Swift3:
@objc(userNotificationCenter:willPresentNotification:withCompletionHandler:) @available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
//To show notifications in foreground.
print("Userinfo2 \(notification.request.content.userInfo)")
}
Cel C
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
if(application.applicationState == UIApplicationStateInactive) {
NSLog(@"Inactive - the user has tapped in the notification when app was closed or in background");
//do some tasks
[self handelPushNotification:userInfo];
}
else if (application.applicationState == UIApplicationStateBackground) {
NSLog(@"application Background - notification has arrived when app was in background");
[self handelPushNotification:userInfo];
}
else {
NSLog(@"application Active - notication has arrived while app was opened");
//Show an in-app banner
//do tasks
}
}
Wywołania scenariusza awarii:
Szybki
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}
Cel C
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
Uwaga
Jeśli żadna z powyższych metod nie zostanie wywołana, urządzenie nie może nawiązać niezawodnego połączenia z serwerem APN, co może być spowodowane problemami z dostępem do Internetu.
Sprawdzanie, czy Twoja aplikacja jest już zarejestrowana w powiadomieniu push
Szybki
let isPushEnabled = UIApplication.sharedApplication().isRegisteredForRemoteNotifications()
Rejestracja powiadomienia (nieinteraktywnego) Push
Zaleca się dodanie logiki rejestracji do powiadomienia wypychanego w AppDelegate.swift
ponieważ funkcje wywołania zwrotnego (sukces, niepowodzenie) zostaną nazwane ich. Aby się zarejestrować, wykonaj następujące czynności:
let application = UIApplication.sharedApplication()
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
Następnie zostanie didRegisterUserNotificationSettings
funkcja zwrotna didRegisterUserNotificationSettings
, w takim przypadku wystarczy wywołać rejestr w następujący sposób:
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
application.registerForRemoteNotifications()
}
W takim przypadku zostanie wyświetlony alert systemowy z prośbą o perswazję, aby otrzymać powiadomienie push. Wywołana zostanie jedna z następujących funkcji wywołania zwrotnego:
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
var tokenString = ""
for i in 0..<deviceToken.length {
tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
print("Push token: \(tokenString)")
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("didFailToRegisterForRemoteNotificationsWithError: \(error)")
}
W bardzo rzadkich przypadkach nie są wywoływane funkcje zwrotne powodzenia ani niepowodzenia. Dzieje się tak, gdy masz problemy z połączeniem internetowym lub piaskownica APNS jest wyłączona. System wykonuje wywołanie API do APNS w celu przeprowadzenia weryfikacji, w przeciwnym razie żadna z dwóch funkcji wywołania zwrotnego nie zostanie wywołana. Sprawdź status systemu Apple, aby upewnić się, że jest w porządku.
Obsługa powiadomień push
Gdy użytkownik kliknie powiadomienie push, zostanie wywołana następująca funkcja oddzwaniania. Możesz przeanalizować JSON, aby uzyskać określone informacje wysłane z backendu, które pomogą ci w głębokim linkowaniu:
Szybki
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Received notification: \(userInfo)")
}
Cel C
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo
{
NSLog(@"Received notification: %@", userInfo);
}
iOS 10
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
// iOS 10 will handle notifications through other methods
NSLog(@"Received notification: %@", userInfo);
if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( @"10.0" ) )
{
NSLog( @"iOS version >= 10. Let NotificationCenter handle this one." );
// set a member variable to tell the new delegate that this is background
return;
}
NSLog( @"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo );
// custom code to handle notification content
if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )
{
NSLog( @"INACTIVE" );
completionHandler( UIBackgroundFetchResultNewData );
}
else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )
{
NSLog( @"BACKGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
}
else
{
NSLog( @"FOREGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
}
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSLog( @"Handle push from foreground" );
// custom code to handle push while app is in the foreground
NSLog(@"%@", notification.request.content.userInfo);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler
{
NSLog( @"Handle push from background or closed" );
// if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background
NSLog(@"%@", response.notification.request.content.userInfo);
}
Rejestrowanie identyfikatora aplikacji do użytku z powiadomieniami push
Rzeczy, których potrzebujesz
- Płatne członkostwo w programie dla programistów Apple
- Prawidłowy identyfikator i identyfikator aplikacji (np. Com.example.MyApp), który nie był wcześniej używany
- Dostęp do developer.apple.com i Centrum użytkowników
- Urządzenie z systemem iOS do testowania (ponieważ powiadomienia push nie działają na symulatorze)
Włączanie dostępu do APN dla identyfikatora aplikacji w Apple Developer Center
1- Zaloguj się do developer.apple.com Member Center (link do konta na stronie głównej)
2– Idź do „Certyfikatów”
3- Wybierz „Identyfikator aplikacji” z lewego panelu
4- Kliknij „+” w prawym górnym rogu
5- Dodaj identyfikator aplikacji z zaznaczoną opcją Powiadomienia push
6- Kliknij utworzony identyfikator aplikacji i wybierz Edytuj
7- Kliknij Konfiguruj w panelu powiadomień push
8- Otwórz aplikację Keychain Access na komputerze Mac
9- W menu Dostęp do pęku kluczy kliknij Asystent certyfikatu -> Poproś o certyfikat od urzędu certyfikacji
10 - Wpisz swoją pocztę w pierwszym polu tekstowym
11- Wpisz swoje imię i nazwisko w drugim polu tekstowym
12 - Pozostaw adres e-mail urzędu certyfikacji pusty
13 - Wybierz opcję Zapisane na dysku zamiast Wysyłane pocztą e-mail do urzędu certyfikacji
14- Kliknij Kontynuuj i prześlij wygenerowany plik
15- Pobierz wygenerowany plik przez Apple i otwórz go, gdy Keychain Access jest otwarty
Włączanie dostępu do APN w Xcode
1- Wybierz swój projekt
2- Otwórz zakładkę Możliwości
3- Znajdź powiadomienia push i włącz je
4-Znajdź tryby tła, włącz je i zaznacz Zdalne powiadomienia
Wyrejestrowywanie z powiadomień wypychanych
Aby programowo wyrejestrować się ze zdalnych powiadomień, możesz użyć
Cel C
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
Szybki
UIApplication.sharedApplication().unregisterForRemoteNotifications()
jest to podobne do wchodzenia w ustawienia telefonu i ręcznego wyłączania Powiadomień dla aplikacji.
UWAGA: Mogą być rzadkie przypadki, w których będziesz tego potrzebować (np .: gdy Twoja aplikacja nie obsługuje już powiadomień push)
Jeśli chcesz tylko zezwolić użytkownikowi na tymczasowe wyłączenie Powiadomień. Należy wdrożyć metodę usuwania tokena urządzenia z bazy danych na serwerze. w przeciwnym razie, jeśli wyłączysz Powiadomienie tylko lokalnie na swoim urządzeniu, twój serwer będzie nadal wysyłał wiadomości.
Ustawienie numeru identyfikacyjnego ikony aplikacji
Użyj następującego fragmentu kodu, aby ustawić numer identyfikatora w aplikacji (załóżmy, że someNumber
został już wcześniej zadeklarowany):
Cel C
[UIApplication sharedApplication].applicationIconBadgeNumber = someNumber;
Szybki
UIApplication.shared.applicationIconBadgeNumber = someNumber
Aby całkowicie usunąć znaczek, wystarczy ustawić someNumber = 0
.
Testowanie powiadomień push
Dobrą praktyką jest zawsze sprawdzanie, jak działają powiadomienia wypychane, zanim przygotujesz je po stronie serwera, aby upewnić się, że wszystko jest ustawione poprawnie po twojej stronie. Wysyłanie sobie powiadomień wypychanych przy użyciu następującego skryptu PHP jest dość łatwe.
- Zapisz skrypt jako plik (na przykład send_push.php) w tym samym folderze co twój certyfikat (programistyczny lub produkcyjny)
- Edytuj go, aby umieścić token urządzenia, hasło z certyfikatu
- Wybierz poprawną ścieżkę do otwierania połączenia, dev_path lub prod_path (w tym miejscu w skrypcie dzieje się „Otwórz połączenie z serwerem APNS”)
- cd do folderu w Terminalu i uruchom polecenie „php send_push”
- Otrzymuj powiadomienia na swoim urządzeniu
<?php
// Put your device token here (without spaces):
$deviceToken = '20128697f872d7d39e48c4a61f50cb11d77789b39e6fc6b4cd7ec80582ed5229';
// Put your final pem cert name here. it is supposed to be in the same folder as this script
$cert_name = 'final_cert.pem';
// Put your private key's passphrase here:
$passphrase = '1234';
// sample point
$alert = 'Hello world!';
$event = 'new_incoming_message';
// You can choose either of the paths, depending on what kind of certificate you are using
$dev_path = 'ssl://gateway.sandbox.push.apple.com:2195';
$prod_path = 'ssl://gateway.push.apple.com:2195';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $cert_name);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
$dev_path, $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
// it should be as short as possible
// if the notification doesnt get delivered that is most likely
// because the generated message is too long
$body['aps'] = array(
'alert' => $alert,
'sound' => 'default',
'event' => $event
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Generowanie certyfikatu .pem z pliku .cer w celu przekazania go twórcy serwera
Zapisz aps.cer w folderze
Otwórz „Dostęp do pęku kluczy” i wyeksportuj klucz znajdujący się pod tym certyfikatem do pliku .p12 (nazwij go klucz.p12). Aby to zrobić, kliknij go prawym przyciskiem myszy i wybierz polecenie Eksportuj. Zapisz go w tym samym folderze, co w kroku 1. Podczas eksportu pojawi się monit o podanie hasła. Wymyśl coś i zapamiętaj.
cd do tego folderu w terminalu i wykonaj następujące polecenia:
Konwertuj .cer na certyfikat .pem
openssl x509 -in aps.cer -inform der -out aps.pem
- Konwertuj swój klucz na format .pem. Aby otworzyć klucz, wprowadź hasło, za pomocą którego wyeksportowałeś go z pęku kluczy, w kroku 2. Następnie wprowadź inne hasło, które będzie chronić eksportowany plik. Zostaniesz poproszony o podanie go dwukrotnie w celu potwierdzenia.
openssl pkcs12 -nocerts -out key.pem -in key.p12
- Scal pliki w jeden plik końcowy
cat key.pem aps.pem > final_cert.pem
- Końcowy wynik to wynik końcowy. Przekaż go twórcom serwerów z hasłem z kroku 5, aby mogli oni korzystać z chronionego certyfikatu.