У меня есть крючок SpringBoard, который прослушивает распределенные уведомления. Различные другие приложения, которые я зацепил почтовыми уведомлениями, которые получены в SpringBoard.
Если я передам userInfo как null, SpringBoard будет получать уведомления от всех приложений. Если я передам CFDictionaryRef как userInfo, SpringBoard получит уведомления только от SpringBoard и SystemApps. Однако пользовательские приложения не могут отправлять уведомления. (Вернее, не получено Springboard).
CFDictionaryRef невиновен, а не виновник, потому что я могу передать его, когда отправитель и получатель являются системными приложениями.
Есть ли ограничение, согласно которому пользовательские приложения не могут отправлять объект userInfo в системные приложения?
EDIT: Прикрепление кода. Я компилирую его с помощью iOSOpenDev. Положитесь на NSLog для отладки. Сценарий 1. Если вы коснетесь SpringBoard, вы увидите 2 журнала отправки и получения уведомлений. Сценарий 2. Запустите любое системное приложение, например часы, и вы увидите оба журнала. Сценарий 3. Любое приложение из магазина приложений, например SketchBookX и т. д., и только один журнал будет распечатан для отправки уведомления. Его не получили.
Я пробовал все разновидности CFNotificationCenterPostNotification, но ничего не работает.
#import <UIKit/UIKit.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFNotificationCenter.h>
#include "GraphicsServices/GSEvent.h"
#define GS_EVENT_TYPE_OFFSET 2
#define HOME_DOWN 1000
#define HOME_UP 1001
#define VOL_DOWN_KEY_DOWN 1008
#define VOL_DOWN_KEY_UP 1009
extern "C" CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
void LogEvent(CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo)
{
NSString *str = [[NSString alloc]initWithFormat:@"%@,%@,%d,%d,%d,%d,%d\r\n",
(NSString*)CFDictionaryGetValue(userInfo,@"strWindow"),
(NSString*)CFDictionaryGetValue(userInfo,@"strView"),
[(NSNumber*)CFDictionaryGetValue(userInfo,@"phase") intValue],
[(NSNumber*)CFDictionaryGetValue(userInfo,@"xInView") intValue],
[(NSNumber*)CFDictionaryGetValue(userInfo,@"yInView") intValue],
[(NSNumber*)CFDictionaryGetValue(userInfo,@"xInWindow") intValue],
[(NSNumber*)CFDictionaryGetValue(userInfo,@"yInWindow") intValue]];
NSLog(@"Area51 Notification Received: %@",str);
}
%hook UIApplication
-(void) sendEvent:(UIEvent*)event
{
if( [NSStringFromClass([event class]) isEqualToString:@"UITouchesEvent"] )
{
NSSet *touches = [event allTouches];
NSEnumerator *enumerator = [touches objectEnumerator];
id value;
while ((value = [enumerator nextObject])) {
UITouch *touch = value;
NSString *strViewClassName;
if(!touch.view)
strViewClassName = @" ";
else
strViewClassName = [NSString stringWithString:NSStringFromClass([[touch view] class])];
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(dictionary, @"phase", [NSNumber numberWithInt:[touch phase]] );
CFDictionaryAddValue(dictionary, @"strWindow", NSStringFromClass([[touch window] class]) );
CFDictionaryAddValue(dictionary, @"strView", strViewClassName);
CFDictionaryAddValue(dictionary, @"xInView", [NSNumber numberWithInt:[touch locationInView:touch.view].x]) ;
CFDictionaryAddValue(dictionary, @"yInView", [NSNumber numberWithInt:[touch locationInView:touch.view].y]) ;
CFDictionaryAddValue(dictionary, @"xInWindow", [NSNumber numberWithInt:[touch locationInView:nil].x]) ;
CFDictionaryAddValue(dictionary, @"yInWindow", [NSNumber numberWithInt:[touch locationInView:nil].y]) ;
CFNotificationCenterPostNotificationWithOptions(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)@"RecordTouch",
NULL,
dictionary,
kCFNotificationDeliverImmediately|kCFNotificationPostToAllSessions);
NSLog(@"Area 51: Notification Send for App: %@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] );
}
}
%orig;
}
%end
%hook SpringBoard
-(void)applicationDidFinishLaunching:(UIApplication*) application
{
CFNotificationCenterAddObserver(
CFNotificationCenterGetDistributedCenter(),
NULL,
LogEvent,
NULL,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
NSLog(@"Area51: ObserverAdded");
%orig;
}
%end
__attribute__((constructor)) void area51init() {
%init;
}
userInfo
), уведомление всегда проходит успешно. Затем добавьте простой словарь с одним строковым ключом и одним строковым значением. Стройте сложность оттуда. Посмотрите, из-за чего он выходит из строя. Вы можете попробовать начать с другого примера (например, этот для OSX). Процесс ликвидации :( - person Nate   schedule 17.08.2013