Это код Xamarin C# (различный синтаксис и капитализация, чем Objective-C, но я думаю, что он переводится по строкам в Objective-C).
Протестировано как для iOS 9.3, так и для iOS 10.2.
Для инициализации «местных» и «удаленные» уведомления:
// "UIApplicationDelegate" is for "local" notifications,
// "IUNUserNotificationCenterDelegate, IMessagingDelegate" for "remote" notifications.
public class AppDelegate : UIApplicationDelegate,
IUNUserNotificationCenterDelegate, IMessagingDelegate
{
...
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
...
RegisterForOurRemoteNotifications(this);
RegisterForOurLocalNotifications();
...
}
...
// --- Comment out if not using Google FCM. ---
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
//base.RegisteredForRemoteNotifications(application, deviceToken);
Firebase.InstanceID.InstanceId.SharedInstance.SetApnsToken(deviceToken,
Firebase.InstanceID.ApnsTokenType.Sandbox);
}
...
// ----- "static"; Could be in another class. -----
// These flags are for our convenience, so we know initialization was done.
static bool IsRegisteredForNotifications;
static bool IsRegisteredForRemoteNotifications;
// Optional - true when we are using Google "Firebase Cloud Messaging".
static bool HasFCM;
public static void RegisterForOurRemoteNotifications(AppDelegate del)
{
// Google "Firebase Cloud Messaging" (FCM) Monitor token generation
// (Uncomment, if you are using FCM for notifications.)
//InstanceId.Notifications.ObserveTokenRefresh(TokenRefreshNotification);
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)) {
// iOS 10 or later
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => {
Console.WriteLine(granted);
});
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = del;
// For iOS 10 data message (sent via Google FCM).
// (Uncomment, if you are using FCM for notifications.)
// TBD: If NOT using FCM, you may need some other lines of code here.
//Messaging.SharedInstance.RemoteMessageDelegate = del;
} else {
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
IsRegisteredForRemoteNotifications = true;
// Uncomment if using Google "Firebase Cloud Messaging" (FCM).
//TokenRefreshNotification(null, null);
//if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0)) // Needed to call this twice on iOS 9 for some reason.
// TokenRefreshNotification(null, null);
UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(UIApplication.BackgroundFetchIntervalMinimum);
}
public static void RegisterForOurLocalNotifications()
{
// --- Our app's notification actions. ---
UNNotificationAction followAction = UNNotificationAction.FromIdentifier("follow", PS.LocalizedString("Follow"), UNNotificationActionOptions.None);
UNNotificationAction likeAction = UNNotificationAction.FromIdentifier("like", PS.LocalizedString("Like"), UNNotificationActionOptions.None);
// ...
// --- Our app's notification categories ---
UNNotificationCategory followCategory = UNNotificationCategory.FromIdentifier("followCategory", new UNNotificationAction[] { followAction, likeAction },
new string[] { }, UNNotificationCategoryOptions.None);
// ...
// --- All of the app's categories from above ---
var categories = new UNNotificationCategory[] { followCategory /*, ...*/ };
// --- Same for all apps ---
UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert |
UIUserNotificationType.Badge |
UIUserNotificationType.Sound
, new NSSet(categories));
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)) {
UNUserNotificationCenter.Current.SetNotificationCategories(new NSSet<UNNotificationCategory>(categories));
UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Badge,
(result, err) => {
Console.WriteLine(result.ToString());
});
}
IsRegisteredForNotifications = true;
}
}
// -------------------------------------------------------
// --- These are for Google "Firebase Cloud Messaging" ---
// (Comment out if not using FCM.)
public static string Token;
static void TokenRefreshNotification(object sender, NSNotificationEventArgs e)
{
// This method will be fired every time a new token is generated, including the first
// time. So if you need to retrieve the token as soon as it is available this is where that
// should be done.
//var refreshedToken = InstanceId.SharedInstance.Token;
ConnectToFCM(UIApplication.SharedApplication.KeyWindow.RootViewController);
// TODO: If necessary send token to application server.
}
public static void ConnectToFCM(UIViewController fromViewController)
{
Messaging.SharedInstance.Connect(error => {
if (error != null) {
Helper.logD("Unable to connect to FCM", error.LocalizedDescription);
} else {
//var options = new NSDictionary();
//options.SetValueForKey(DeviceToken, Constants.RegisterAPNSOption);
//options.SetValueForKey(new NSNumber(true), Constants.APNSServerTypeSandboxOption);
//InstanceId.SharedInstance.GetToken("", InstanceId.ScopeFirebaseMessaging
Token = InstanceId.SharedInstance.Token;
Console.WriteLine($"Token: {InstanceId.SharedInstance.Token}");
HasFCM = true;
}
});
}
// ------------------ End Google FCM ---------------------
// -------------------------------------------------------
}
Приведенный выше код инициализирует ваше приложение таким образом, что он может получать уведомления.
ВАЖНО: Вам также необходимо установить соответствующие разрешения для своего приложения; см. документы Apple или ссылки, упомянутые в вопросе.И вам нужен этот файл:
Entitlements.plist:
<?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>aps-environment</key>
<string>development</string>
</dict>
</plist>
<string>
выше, должны содержать либо "развитие" или "производства". (Я не знаю, что значение нашего приложения все еще говорит о «развитии» здесь: я не изучил, что построено, чтобы увидеть, будет ли оно автоматически изменено на «производство» Xcode перед отправкой в Apple. Согласно https://stackoverflow.com/a/40857877/199364, он делает это.)
Затем вам нужно код отправить [например, ваше приложение сообщает вашему серверу, чтобы уведомить устройства ваших друзей о том, что вы сейчас делаете] и получите локальное или удаленное уведомление. Этот код в нашем приложении сочетается с нашими конкретными действиями и категориями уведомлений; У меня нет времени для получения краткой версии для публикации здесь. Подробные сведения см. В документах Apple или ссылках, упомянутых в исходном вопросе.
Вот основные методы (Добавить в class AppDelegate
выше), чтобы получить уведомления:
public override void ReceivedLocalNotification(UIApplication application, UILocalNotification notification)
{
...
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
...
}
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
...
}
Другие методы, которые вы можете/нужно переопределить или реализовать (также см интерфейсы объявлены class AppDelegate
выше) ; некоторые из них могут быть специфическими для FCM:
ApplicationReceivedRemoteMessage
ReceivedRemoteNotification
WillPresentNotification
PerformFetch (for background notifications)
HandleAction
ToolmakerSteve, вы хотите локальное уведомление или удаленное устройство? если вы используете дистанционное управление, вы должны использовать реальное устройство для тестирования. – aircraft
@aircraft Как локальный, так и удаленный. У моей компании есть приложение в магазине приложений, которое работает на устройствах iOS 10, но падает на устройствах iOS 9.3. Так что да, он был протестирован на реальных устройствах. [К сожалению, протестирован жесткий путь ...] Не знаю, был ли это локальный или удаленный сбой, к сожалению, я не писал этот код, я просто узнаю обо всем этом, поэтому я могу исправить приложение. – ToolmakerSteve
@aircraft .. и просто узнал, что больше не возможно вернуться к версиям до iOS 10 без джейлбрейка моего iPhone. Не желая этого делать, чтобы как можно больше тестировать эмулятор, вы отправите версию TestFlight кому-то с iOS 9.3 – ToolmakerSteve