Skip to content

Commit 5e33b81

Browse files
committed
iOS Apple Push Notifications plugin.
1 parent 1c120a8 commit 5e33b81

File tree

11 files changed

+507
-1
lines changed

11 files changed

+507
-1
lines changed

SConstruct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ opts.Add(EnumVariable('arch', "Compilation Architecture", '', ['', 'arm64', 'arm
2424
opts.Add(BoolVariable('simulator', "Compilation platform", 'no'))
2525
opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no'))
2626
opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'bin/'))
27-
opts.Add(EnumVariable('plugin', 'Plugin to build', '', ['', 'arkit', 'camera', 'icloud', 'gamecenter', 'inappstore']))
27+
opts.Add(EnumVariable('plugin', 'Plugin to build', '', ['', 'apn', 'arkit', 'camera', 'icloud', 'gamecenter', 'inappstore']))
2828
opts.Add(EnumVariable('version', 'Godot version to target', '', ['', '3.2', '4.0']))
2929

3030
# Updates the environment with the option variables.

plugins/apn/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Godot iOS Apple Push Notifications plugin
2+
3+
Requires `-ObjC` value added to the `Other Linker Flags` in Xcode project.
4+
5+
Example:
6+
7+
```
8+
var _apn = null
9+
10+
func _apn_device(value):
11+
print("device string: " + value);
12+
13+
...
14+
15+
func _ready():
16+
if Engine.has_singleton("APN"):
17+
var _apn = Engine.get_singleton("APN");
18+
_apn.connect("device_address_changed", self, "_apn_device");
19+
20+
_apn.register_push_notifications(_apn.PUSH_SOUND | _apn.PUSH_BADGE | _apn.PUSH_ALERT);
21+
```
22+
23+
## Enum
24+
25+
Type: `PushOptions`
26+
Values: `PUSH_ALERT`, `PUSH_BADGE`, `PUSH_SOUND`
27+
28+
## Methods
29+
30+
`register_push_notifications(PushOptions options)` - Registers device to receive remote notifications through Apple Push Notification service.
31+
32+
## Properties
33+
34+
## Signals
35+
36+
`device_address_changed(String token)` - Called whenever iOS device updates remote notification token value.

plugins/apn/apn.gdip

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[config]
2+
name="Push Notifications"
3+
binary="apn.xcframework"
4+
5+
initialization="godot_apn_init"
6+
deinitialization="godot_apn_deinit"
7+
8+
[dependencies]
9+
linked=[]
10+
embedded=[]
11+
system=[]
12+
13+
capabilities=[]
14+
15+
files=[]
16+
17+
# linker_flags=["-ObjC"]
18+
19+
[plist]

plugins/apn/apn.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*************************************************************************/
2+
/* apn.h */
3+
/*************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/*************************************************************************/
8+
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
9+
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/*************************************************************************/
30+
31+
#ifndef godot_apn_implementation_h
32+
#define godot_apn_implementation_h
33+
34+
#include "core/object.h"
35+
36+
class APNPlugin : public Object {
37+
GDCLASS(APNPlugin, Object);
38+
39+
static void _bind_methods();
40+
41+
public:
42+
enum PushOptions {
43+
PUSH_ALERT = 1,
44+
PUSH_BADGE,
45+
PUSH_SOUND
46+
};
47+
48+
static APNPlugin *get_singleton();
49+
50+
void register_push_notifications(PushOptions options);
51+
void update_device_token(String token);
52+
53+
APNPlugin();
54+
~APNPlugin();
55+
};
56+
57+
VARIANT_ENUM_CAST(APNPlugin::PushOptions)
58+
59+
#endif /* godot_apn_implementation_h */

plugins/apn/apn.mm

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*************************************************************************/
2+
/* apn.mm */
3+
/*************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/*************************************************************************/
8+
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
9+
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/*************************************************************************/
30+
31+
#include "apn.h"
32+
33+
#import <Foundation/Foundation.h>
34+
35+
#include "core/class_db.h"
36+
#include "core/project_settings.h"
37+
38+
#import "apn_implementation.h"
39+
40+
static APNPlugin *singleton;
41+
42+
APNPlugin *APNPlugin::get_singleton() {
43+
return singleton;
44+
}
45+
46+
void APNPlugin::_bind_methods() {
47+
ClassDB::bind_method(D_METHOD("register_push_notifications", "options"), &APNPlugin::register_push_notifications);
48+
49+
ADD_SIGNAL(MethodInfo("device_address_changed", PropertyInfo(Variant::STRING, "id")));
50+
51+
BIND_ENUM_CONSTANT(PUSH_ALERT);
52+
BIND_ENUM_CONSTANT(PUSH_BADGE);
53+
BIND_ENUM_CONSTANT(PUSH_SOUND);
54+
}
55+
56+
void APNPlugin::register_push_notifications(PushOptions options) {
57+
UNAuthorizationOptions notificationsOptions = 0;
58+
59+
if (options & PUSH_ALERT) {
60+
notificationsOptions |= UNAuthorizationOptionAlert;
61+
}
62+
63+
if (options & PUSH_BADGE) {
64+
notificationsOptions |= UNAuthorizationOptionBadge;
65+
}
66+
67+
if (options & PUSH_SOUND) {
68+
notificationsOptions |= UNAuthorizationOptionSound;
69+
}
70+
71+
[[GodotAPNAppDelegate shared] registerPushNotificationsWithOptions:options];
72+
}
73+
74+
void APNPlugin::update_device_token(String token) {
75+
emit_signal("device_address_changed", token);
76+
}
77+
78+
APNPlugin::APNPlugin() {
79+
singleton = this;
80+
}
81+
82+
APNPlugin::~APNPlugin() {
83+
singleton = NULL;
84+
}

plugins/apn/apn_implementation.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*************************************************************************/
2+
/* apn_implementation.h */
3+
/*************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/*************************************************************************/
8+
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
9+
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/*************************************************************************/
30+
31+
#import <UIKit/UIKit.h>
32+
#import <UserNotifications/UserNotifications.h>
33+
34+
@interface GodotAPNAppDelegate : NSObject <UIApplicationDelegate>
35+
36+
+ (instancetype)shared;
37+
- (void)registerPushNotificationsWithOptions:(UNAuthorizationOptions)options;
38+
39+
@end

plugins/apn/apn_implementation.mm

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*************************************************************************/
2+
/* apn_implementation.mm */
3+
/*************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/*************************************************************************/
8+
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
9+
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/*************************************************************************/
30+
31+
#import "apn_implementation.h"
32+
33+
#include "apn.h"
34+
35+
#import "platform/iphone/godot_app_delegate.h"
36+
37+
struct APNSInitializer {
38+
39+
APNSInitializer() {
40+
[GodotApplicalitionDelegate addService:[GodotAPNAppDelegate shared]];
41+
}
42+
};
43+
static APNSInitializer initializer;
44+
45+
@interface GodotAPNAppDelegate ()
46+
47+
@end
48+
49+
@implementation GodotAPNAppDelegate
50+
51+
- (instancetype)init {
52+
self = [super init];
53+
54+
return self;
55+
}
56+
57+
+ (instancetype)shared {
58+
static GodotAPNAppDelegate *sharedInstance = nil;
59+
static dispatch_once_t onceToken;
60+
dispatch_once(&onceToken, ^{
61+
sharedInstance = [[GodotAPNAppDelegate alloc] init];
62+
});
63+
return sharedInstance;
64+
}
65+
66+
- (void)registerPushNotificationsWithOptions:(UNAuthorizationOptions)options {
67+
[UNUserNotificationCenter.currentNotificationCenter requestAuthorizationWithOptions:options
68+
completionHandler:^(BOOL granted, NSError *_Nullable error) {
69+
NSLog(@"Push notifications access: %@, error: %@", @(granted), error);
70+
}];
71+
[UIApplication.sharedApplication registerForRemoteNotifications];
72+
}
73+
74+
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
75+
const char *data = (const char *)[deviceToken bytes];
76+
NSMutableString *token = [NSMutableString string];
77+
78+
for (NSUInteger i = 0; i < [deviceToken length]; i++) {
79+
[token appendFormat:@"%02.2hhX", data[i]];
80+
}
81+
82+
String device_token;
83+
device_token.parse_utf8([[token copy] UTF8String]);
84+
85+
APNPlugin::get_singleton()->update_device_token(device_token);
86+
}
87+
88+
@end

plugins/apn/apn_plugin.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*************************************************************************/
2+
/* apn_plugin.cpp */
3+
/*************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/*************************************************************************/
8+
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
9+
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/*************************************************************************/
30+
31+
#import "apn_plugin.h"
32+
#import "apn.h"
33+
34+
#import "core/engine.h"
35+
36+
APNPlugin *plugin;
37+
38+
void godot_apn_init() {
39+
plugin = memnew(APNPlugin);
40+
Engine::get_singleton()->add_singleton(Engine::Singleton("APN", plugin));
41+
}
42+
43+
void godot_apn_deinit() {
44+
if (plugin) {
45+
memdelete(plugin);
46+
}
47+
}

0 commit comments

Comments
 (0)