diff --git a/Cargo.toml b/Cargo.toml index 012e91da0d..5435d429b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,6 +113,8 @@ features = [ "dispatch", "Foundation", "Foundation_NSArray", + "Foundation_NSData", + "Foundation_NSError", "Foundation_NSString", "Foundation_NSProcessInfo", "Foundation_NSThread", diff --git a/src/event.rs b/src/event.rs index 4ed67406ec..f3cf4c3f0c 100644 --- a/src/event.rs +++ b/src/event.rs @@ -52,6 +52,16 @@ use crate::{ window::{ActivationToken, Theme, WindowId}, }; +/// iOS specific event sent when UIApplication delegate receives the response upon registering for remote notifications +#[derive(Debug, Clone, PartialEq)] +pub enum IosRemoteRegistration { + Failed { + code: isize, + localized_description: String, + }, + DeviceToken(Vec), +} + /// Describes a generic event. /// /// See the module-level docs for more information on the event loop manages each event. @@ -251,6 +261,9 @@ pub enum Event { /// /// - **macOS / Wayland / Windows / Orbital:** Unsupported. MemoryWarning, + + /// TODO + IosRemoteRegistration(IosRemoteRegistration), } impl Event { @@ -267,6 +280,7 @@ impl Event { Suspended => Ok(Suspended), Resumed => Ok(Resumed), MemoryWarning => Ok(MemoryWarning), + IosRemoteRegistration(v) => Ok(IosRemoteRegistration(v)), } } } diff --git a/src/platform_impl/ios/view.rs b/src/platform_impl/ios/view.rs index 17fb3c0e08..a4ab15faa8 100644 --- a/src/platform_impl/ios/view.rs +++ b/src/platform_impl/ios/view.rs @@ -2,7 +2,9 @@ use std::cell::Cell; use std::ptr::NonNull; -use icrate::Foundation::{CGFloat, CGRect, MainThreadMarker, NSObject, NSObjectProtocol, NSSet}; +use icrate::Foundation::{ + CGFloat, CGRect, MainThreadMarker, NSData, NSError, NSObject, NSObjectProtocol, NSSet, +}; use objc2::declare::{Ivar, IvarDrop}; use objc2::rc::Id; use objc2::runtime::AnyClass; @@ -15,9 +17,13 @@ use super::uikit::{ UIViewController, UIWindow, }; use super::window::WindowId; + use crate::{ dpi::PhysicalPosition, - event::{DeviceId as RootDeviceId, Event, Force, Touch, TouchPhase, WindowEvent}, + event::{ + DeviceId as RootDeviceId, Event, Force, IosRemoteRegistration, Touch, TouchPhase, + WindowEvent, + }, platform::ios::ValidOrientations, platform_impl::platform::{ ffi::{UIRectEdge, UIUserInterfaceIdiom}, @@ -526,6 +532,47 @@ declare_class!( true } + #[method(application:didRegisterForRemoteNotificationsWithDeviceToken:)] + fn did_register_for_remote_notifications_with_device_token( + &self, + _application: &UIApplication, + token_data: *mut NSData, + ) { + let slice: &[u8] = unsafe { token_data.as_ref() }.unwrap().bytes(); + + let mtm = MainThreadMarker::new().unwrap(); + app_state::handle_nonuser_event( + mtm, + EventWrapper::StaticEvent(Event::IosRemoteRegistration( + IosRemoteRegistration::DeviceToken(slice.to_vec()), + )), + ) + } + + #[method(application:didFailToRegisterForRemoteNotificationsWithError:)] + fn did_fail_to_register_for_remote_notifications( + &self, + _application: &UIApplication, + error: *mut NSError, + ) { + let code = unsafe { error.as_ref() }.unwrap().code(); + let localized_description: String = unsafe { error.as_ref() } + .unwrap() + .localizedDescription() + .to_string(); + + let mtm = MainThreadMarker::new().unwrap(); + app_state::handle_nonuser_event( + mtm, + EventWrapper::StaticEvent(Event::IosRemoteRegistration( + IosRemoteRegistration::Failed { + code, + localized_description, + }, + )), + ) + } + #[method(applicationDidBecomeActive:)] fn did_become_active(&self, _application: &UIApplication) { let mtm = MainThreadMarker::new().unwrap();