Skip to content

Commit

Permalink
[APN] Added badge number. Added single services container for user no…
Browse files Browse the repository at this point in the history
…tifications.
  • Loading branch information
naithar committed Feb 5, 2021
1 parent e7cfadd commit 1e8c302
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 6 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file.

## 2021-02-05

## Added

- `badge_number` property, `set_badge_number`, `get_badge_number` methods to `PushNotifications` plugin.
- `GodotUserNotificationDelegate` and `UserNotificationService` can be used by as a single interface to process incoming notifications (both remote and local).

## 2021-02-03

## Added
Expand Down
8 changes: 6 additions & 2 deletions plugins/apn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ func _ready():

## Enum

Type: `PushOptions`
Values: `PUSH_ALERT`, `PUSH_BADGE`, `PUSH_SOUND`
Type: `PushOptions`
Values: `PUSH_ALERT`, `PUSH_BADGE`, `PUSH_SOUND`, `PUSH_SETTINGS`

## Methods

`register_push_notifications(PushOptions options)` - Registers device to receive remote notifications through Apple Push Notification service.
`set_badge_number(int value)` - Sets the badge value of the app icon on the Home screen.
`get_badge_number()` - Returns the badge value of the app icon on the Home screen.

## Properties

`badge_number: int` - The number represents the badge of the app icon on the Home screen.

## Signals

`device_address_changed(String token)` - Called whenever iOS device updates remote notification token value.
4 changes: 4 additions & 0 deletions plugins/apn/apn.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,17 @@ class APNPlugin : public Object {
PUSH_ALERT = 1 << 0,
PUSH_BADGE = 1 << 1,
PUSH_SOUND = 1 << 2,
PUSH_SETTINGS = 1 << 3,
};

static APNPlugin *get_singleton();

void register_push_notifications(PushOptions options);
void update_device_token(String token);

void set_badge_number(int value);
int get_badge_number();

APNPlugin();
~APNPlugin();
};
Expand Down
15 changes: 14 additions & 1 deletion plugins/apn/apn.mm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "core/class_db.h"
#include "core/project_settings.h"

#import "apn_implementation.h"
#import "godot_apn_delegate.h"

static APNPlugin *singleton;

Expand All @@ -46,11 +46,16 @@
void APNPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("register_push_notifications", "options"), &APNPlugin::register_push_notifications);

ClassDB::bind_method(D_METHOD("set_badge_number", "value"), &APNPlugin::set_badge_number);
ClassDB::bind_method(D_METHOD("get_badge_number"), &APNPlugin::get_badge_number);
ADD_PROPERTY(PropertyInfo(Variant::INT, "badge_number"), "set_badge_number", "get_badge_number");

ADD_SIGNAL(MethodInfo("device_address_changed", PropertyInfo(Variant::STRING, "id")));

BIND_ENUM_CONSTANT(PUSH_ALERT);
BIND_ENUM_CONSTANT(PUSH_BADGE);
BIND_ENUM_CONSTANT(PUSH_SOUND);
BIND_ENUM_CONSTANT(PUSH_SETTINGS);
}

void APNPlugin::register_push_notifications(PushOptions options) {
Expand All @@ -75,6 +80,14 @@
emit_signal("device_address_changed", token);
}

void APNPlugin::set_badge_number(int value) {
UIApplication.sharedApplication.applicationIconBadgeNumber = (long)value;
}

int APNPlugin::get_badge_number() {
return (int)UIApplication.sharedApplication.applicationIconBadgeNumber;
}

APNPlugin::APNPlugin() {
singleton = this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*************************************************************************/
/* apn_implementation.h */
/* godot_apn_delegate.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*************************************************************************/
/* apn_implementation.mm */
/* godot_apn_delegate.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
Expand Down Expand Up @@ -28,10 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/

#import "apn_implementation.h"
#import "godot_apn_delegate.h"

#include "apn.h"

#import "godot_user_notification_delegate.h"
#import "platform/iphone/godot_app_delegate.h"

struct APNSInitializer {
Expand All @@ -51,6 +52,10 @@ @implementation GodotAPNAppDelegate
- (instancetype)init {
self = [super init];

if (self) {
UNUserNotificationCenter.currentNotificationCenter.delegate = [GodotUserNotificationDelegate shared];
}

return self;
}

Expand Down
43 changes: 43 additions & 0 deletions plugins/apn/godot_user_notification_delegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*************************************************************************/
/* godot_user_notification_delegate.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/

#import <UserNotifications/UserNotifications.h>

typedef NSObject<UNUserNotificationCenterDelegate> UserNotificationService;

@interface GodotUserNotificationDelegate : NSObject <UNUserNotificationCenterDelegate>

@property(class, readonly, strong) NSArray<UserNotificationService *> *services;

+ (instancetype)shared;

+ (void)addService:(UserNotificationService *)service;

@end
102 changes: 102 additions & 0 deletions plugins/apn/godot_user_notification_delegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*************************************************************************/
/* godot_user_notification_delegate.m */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/

#import "godot_user_notification_delegate.h"

@interface GodotUserNotificationDelegate ()

@end

@implementation GodotUserNotificationDelegate

static NSMutableArray<UserNotificationService *> *services = nil;

+ (NSArray<UserNotificationService *> *)services {
return services;
}

+ (void)load {
services = [NSMutableArray new];
}

+ (instancetype)shared {
static GodotUserNotificationDelegate *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[GodotUserNotificationDelegate alloc] init];
});
return sharedInstance;
}

+ (void)addService:(UserNotificationService *)service {
if (!services || !service) {
return;
}
[services addObject:service];
}

// MARK: Delegate

// The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
for (UserNotificationService *service in services) {
if (![service respondsToSelector:_cmd]) {
continue;
}

[service userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}
}

// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
for (UserNotificationService *service in services) {
if (![service respondsToSelector:_cmd]) {
continue;
}

[service userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
}

// The method will be called on the delegate when the application is launched in response to the user's request to view in-app notification settings.
// Add UNAuthorizationOptionProvidesAppNotificationSettings as an option in requestAuthorizationWithOptions:completionHandler: to add a button to inline notification settings view and the notification settings view in Settings.
// The notification will be nil when opened from Settings.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(nullable UNNotification *)notification __API_AVAILABLE(macos(10.14), ios(12.0))__API_UNAVAILABLE(watchos, tvos) {
for (UserNotificationService *service in services) {
if (![service respondsToSelector:_cmd]) {
continue;
}

[service userNotificationCenter:center openSettingsForNotification:notification];
}
}

@end

0 comments on commit 1e8c302

Please sign in to comment.