def test_primitive_list_property(self): class PrimitiveListContainer(NSObject): data = objc_property() @objc_method def init(self): self.data = [1, 2, 3] return self @objc_method def initWithList_(self, data): self.data = data return self obj1 = PrimitiveListContainer.alloc().init() self.assertIsInstance(obj1.data, ObjCListInstance) self.assertEqual(py_from_ns(obj1.data), [1, 2, 3]) obj2 = PrimitiveListContainer.alloc().initWithList_([4, 5, 6]) self.assertIsInstance(obj2.data, ObjCListInstance) self.assertEqual(py_from_ns(obj2.data), [4, 5, 6]) obj2.data = [7, 8, 9] self.assertIsInstance(obj2.data, ObjCListInstance) self.assertEqual(py_from_ns(obj2.data), [7, 8, 9])
def userNotificationCenter_didReceiveNotificationResponse_withCompletionHandler_( self, center, response, completion_handler: objc_block) -> None: # Get the notification which was clicked from the platform ID. internal_nid = py_from_ns( response.notification.request.content.userInfo["internal_nid"]) notification = self.interface.current_notifications[internal_nid] # Get and call the callback which corresponds to the user interaction. if response.actionIdentifier == UNNotificationDefaultActionIdentifier: callback = notification.action if callback: callback() elif response.actionIdentifier != UNNotificationDismissActionIdentifier: action_id_str = py_from_ns(response.actionIdentifier) callback = notification.buttons.get(action_id_str) if callback: callback() completion_handler()
def completion_handler(res: objc_id, error: objc_id) -> None: if error: error = py_from_ns(error) exc = RuntimeError(str(error)) future.set_exception(exc) else: future.set_result(py_from_ns(res))
def test_number_return(self): "If a method or field returns a NSNumber, it is not automatically converted to a Python number." Example = ObjCClass('Example') example = Example.alloc().init() answer = example.theAnswer() self.assertIsInstance(answer, ObjCInstance) self.assertEqual(py_from_ns(answer), 42) tau = example.twopi() self.assertIsInstance(tau, ObjCInstance) self.assertAlmostEqual(py_from_ns(tau), 2.0 * math.pi, 5)
async def _create_category_for_notification( self, notification: Notification) -> Optional[str]: """ Registers a new notification category with UNNotificationCenter for the given notification or retrieves an existing one if it exists for our set of buttons. :param notification: Notification instance. :returns: The identifier of the existing or created notification category. """ if not (notification.buttons or notification.reply_field): return None button_titles = tuple(notification.buttons) ui_repr = f"buttons={button_titles}, reply_field={notification.reply_field}" category_id = f"desktop-notifier: {ui_repr}" # Retrieve existing categories. We do not cache this value because it may be # modified by other Python processes using desktop-notifier. categories = await self._get_notification_categories() category_ids = set( py_from_ns(c.identifier) for c in categories.allObjects()) # type: ignore # Register new category if necessary. if category_id not in category_ids: # Create action for each button. actions = [] if notification.reply_field: action = UNTextInputNotificationAction.actionWithIdentifier( ReplyActionIdentifier, title=notification.reply_field.title, options=UNNotificationActionOptionNone, textInputButtonTitle=notification.reply_field.button_title, textInputPlaceholder="", ) actions.append(action) for n, button in enumerate(notification.buttons): action = UNNotificationAction.actionWithIdentifier( str(n), title=button.title, options=UNNotificationActionOptionNone) actions.append(action) # Add category for new set of buttons. new_categories = categories.setByAddingObject( # type: ignore UNNotificationCategory.categoryWithIdentifier( category_id, actions=actions, intentIdentifiers=[], options=UNNotificationCategoryOptionNone, )) self.nc.setNotificationCategories(new_categories) return category_id
def test_primitive_list_attribute(self): class PrimitiveListAttrContainer(NSObject): @objc_method def init(self): self.data = [1, 2, 3] return self @objc_method def initWithList_(self, data): self.data = data return self obj1 = PrimitiveListAttrContainer.alloc().init() self.assertEqual(obj1.data, [1, 2, 3]) self.assertIsInstance(obj1.data, list) # If it's set through a method call, it becomes an objc instance obj2 = PrimitiveListAttrContainer.alloc().initWithList_([4, 5, 6]) self.assertIsInstance(obj2.data, ObjCListInstance) self.assertEqual(py_from_ns(obj2.data), [4, 5, 6]) # If it's set by direct attribute access, it becomes a Python object. obj2.data = [7, 8, 9] self.assertIsInstance(obj2.data, list) self.assertEqual(obj2.data, [7, 8, 9])
def test_decimal_method(self): "A method with a NSDecimalNumber arguments can be handled." Example = ObjCClass('Example') example = Example.alloc().init() result = example.areaOfTriangleWithWidth_andHeight_(Decimal('3.0'), Decimal('4.0')) self.assertIsInstance(result, ObjCClass('NSDecimalNumber')) self.assertEqual(py_from_ns(result), Decimal('6.0'))
def test_str_nsstring_conversion(self): """Python str and NSString can be converted to each other manually.""" for pystr in type(self).TEST_STRINGS: with self.subTest(pystr=pystr): nsstr = ns_from_py(pystr) self.assertIsInstance(nsstr, NSString) self.assertEqual(str(nsstr), pystr) self.assertEqual(py_from_ns(nsstr), pystr)
def _on_auth_completed(granted: bool, error: objc_id) -> None: if granted: logger.debug( "UNUserNotificationCenter: authorisation granted") else: logger.debug( "UNUserNotificationCenter: authorisation denied") if error: error = py_from_ns(error) logger.warning("UNUserNotificationCenter: %s", str(error))
def userNotificationCenter_didActivateNotification_( self, center, notification) -> None: internal_nid = py_from_ns(notification.userInfo["internal_nid"]) notification_info = self.interface.current_notifications[ internal_nid] if (notification.activationType == NSUserNotificationActivationTypeContentsClicked): if notification_info.action: notification_info.action() elif (notification.activationType == NSUserNotificationActivationTypeActionButtonClicked): button_title = py_from_ns(notification.actionButtonTitle) callback = notification_info.buttons.get(button_title) if callback: callback()
def test_multitype_list_property(self): class MultitypeListContainer(NSObject): data = objc_property() Example = ObjCClass('Example') example = Example.alloc().init() # All types can be stored in a list. obj = MultitypeListContainer.alloc().init() obj.data = [4, True, 'Hello', example] self.assertIsInstance(obj.data, ObjCListInstance) self.assertEqual(py_from_ns(obj.data), [4, True, 'Hello', example])
def userNotificationCenter_didReceiveNotificationResponse_withCompletionHandler_( self, center, response, completion_handler: objc_block) -> None: # Get the notification which was clicked from the platform ID. platform_nid = py_from_ns(response.notification.request.identifier) py_notification = self.interface._notification_for_nid[platform_nid] py_notification = cast(Notification, py_notification) self.interface._clear_notification_from_cache(py_notification) # Invoke the callback which corresponds to the user interaction. if response.actionIdentifier == UNNotificationDefaultActionIdentifier: if py_notification.on_clicked: py_notification.on_clicked() elif response.actionIdentifier == UNNotificationDismissActionIdentifier: if py_notification.on_dismissed: py_notification.on_dismissed() elif response.actionIdentifier == ReplyActionIdentifier: if py_notification.reply_field.on_replied: reply_text = py_from_ns(response.userText) py_notification.reply_field.on_replied(reply_text) else: button_number = int(py_from_ns(response.actionIdentifier)) callback = py_notification.buttons[button_number].on_pressed if callback: callback() completion_handler()
def userNotificationCenter_didActivateNotification_( self, center, notification) -> None: internal_nid = py_from_ns(notification.userInfo["internal_nid"]) notification_info = self.interface.current_notifications[ internal_nid] if Version(macos_version) == Version("11.0.0"): # macOS Big Sur has a 'Show' button by default condition = NSUserNotificationActivationTypeActionButtonClicked else: # macOS Catalina and lower doesn't show a button by default condition = NSUserNotificationActivationTypeContentsClicked if notification.activationType == condition: if notification_info.action: notification_info.action()
def userNotificationCenter_didReceiveNotificationResponse_withCompletionHandler_( self, center, response, completion_handler) -> None: internal_nid = py_from_ns( response.notification.request.content.userInfo["internal_nid"]) notification = self.interface.current_notifications[internal_nid] if response.actionIdentifier == UNNotificationDefaultActionIdentifier: callback = notification.action if callback: callback() elif response.actionIdentifier != UNNotificationDismissActionIdentifier: callback = notification.buttons.get(response.actionIdentifier) if callback: callback() completion_handler()
def userNotificationCenter_didActivateNotification_( self, center, notification) -> None: platform_nid = py_from_ns(notification.identifier) py_notification = self.interface._notification_for_nid[platform_nid] py_notification = cast(Notification, py_notification) self.interface._clear_notification_from_cache(py_notification) if (notification.activationType == NSUserNotificationActivationTypeContentsClicked): if py_notification.on_clicked: py_notification.on_clicked() elif (notification.activationType == NSUserNotificationActivationTypeActionButtonClicked): callback = py_notification.buttons[0].on_pressed if callback: callback()
def initWithValue_(self, value): self.value = py_from_ns(value) return self
def handler(categories: objc_id) -> None: categories = py_from_ns(categories) categories.retain() future.set_result(categories)
def handler(error: objc_id) -> None: ns_error = py_from_ns(error) if ns_error: ns_error.retain() future.set_result(ns_error)
def handler(settings: objc_id) -> None: settings = py_from_ns(settings) settings.retain() future.set_result(settings)
def on_auth_completed(granted: bool, error: objc_id) -> None: ns_error = py_from_ns(error) error_str = str(ns_error.localizedDescription) if ns_error else "" future.set_result((granted, error_str))