2013-08-09 1 views
2

У меня есть крюк SpringBoard, который слушает распределенные уведомления. В других приложениях я подключил уведомление по почте, которое получено в SpringBoard.iOS MobileSubstrate CFNotificationCenterPostNotification - не работает

Если я передаю 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; 
} 
+0

Пожалуйста, разместите код, который вы используете для отправки уведомлений, и код, который вы используете для их прослушивания. – Nate

+0

@Nate - я добавил код. Надеюсь, поможет. – Jailbroken

+0

Хммм. Я не вижу ничего плохого. Я бы начал с более простого примера. Во-первых, убедитесь, что когда у вас есть ** ** ** словарь ('userInfo'), уведомление всегда выполняется успешно. Затем добавьте простой словарь с одним строковым ключом и одним строковым значением. Постройте сложность оттуда. Посмотрите причину сбоя. Вы можете попробовать начать с другого примера (например, [этот для OSX] (http://skype4pidgin.googlecode.com/svn/trunk/skype_messaging_carbon2.c)). Процесс устранения :( – Nate

ответ

0

Проблема, кажется, что userInfo игнорируется (и, таким образом, NULL) при использовании Центра уведомлений Darwin, как center. Source

См. Также this thread.