Key Value Observing — отличная функция, но она не поможет вам (напрямую) решить эту конкретную проблему. Для тех, кто не знаком с классом, о котором он говорит, это закрытый класс в самом iOS SpringBoard. Таким образом, он не может контролировать то, как он публикует интересующие его данные.
Вы не можете наблюдать просто любые старые данные. Он должен быть закодирован, чтобы соответствовать принципу наблюдения за ключевыми значениями (KVO). Если вы посмотрите на SBStatusBarDataManager.h (это версия iOS 4... сгенерируйте нужную вам с помощью class-dump
)... вы увидите, что она не закодирована таким образом :(
Но вы все равно можете использовать некоторые динамические функции времени выполнения Objective-C, чтобы получить данные. См. здесь о непосредственном доступе к закрытым/защищенным переменным экземпляра.
Затем просто локально объявите структуру, соответствующую тому, что находится в заголовке трамплина, и сделайте следующее:
// this was coded to match the iOS 5.0 header, but of course, this may
// change with each iOS version
typedef struct {
char itemIsEnabled[23];
char timeString[64];
int gsmSignalStrengthRaw;
int gsmSignalStrengthBars;
char serviceString[100];
char serviceCrossfadeString[100];
char serviceImages[3][100];
char operatorDirectory[1024];
unsigned int serviceContentType;
int wifiSignalStrengthRaw;
int wifiSignalStrengthBars;
unsigned int dataNetworkType;
int batteryCapacity;
unsigned int batteryState;
char notChargingString[150];
int bluetoothBatteryCapacity;
int thermalColor;
unsigned int thermalSunlightMode:1;
unsigned int slowActivity:1;
unsigned int syncActivity:1;
char activityDisplayId[256];
unsigned int bluetoothConnected:1;
unsigned int displayRawGSMSignal:1;
unsigned int displayRawWifiSignal:1;
} SbStatusBarDataType;
помощник для получения ivars по имени:
#import <objc/runtime.h>
- (void *) instanceVariableForObject: (id)obj andKey: (NSString *)key {
if (key != nil) {
Ivar ivar = object_getInstanceVariable(obj, [key UTF8String], NULL);
if (ivar) {
return (void *)((char *)obj + ivar_getOffset(ivar));
}
}
return NULL;
}
и, наконец, получить данные следующим образом:
// get an instance to the data manager this way, or however you're
// doing it via Mobile Substrate
SBStatusBarDataManager* mgr = [SBStatusBarDataManager sharedDataManager];
SbStatusBarDataType data = *(SbStatusBarDataType*)[self instanceVariableForObject: mgr andKey: @"_data"];
int signalStrength = data.wifiSignalStrengthRaw;
Затем вы можете просто повторно запрашивать эти данные с некоторым интервалом, который вы считаете достаточно быстрым.
В противном случае попробуйте просмотреть методы в SBStatusBarDataManager.h. Похоже, что некоторые из них могут быть вызваны именно в то время, когда изменяется уровень сигнала. Если вы подключите эти методы, вы сможете отправить уведомление об изменении данных, чтобы вам не приходилось постоянно запрашивать данные.
Например:
- (void)_dataChanged;
- (void)_updateSignalStrengthItem;
- (void)_signalStrengthChange;
все выглядят как хорошие кандидаты на перехват, если вы пытаетесь определить, когда произошло изменение мощности сигнала WiFi. Но у меня нет опыта с ними, и это будет методом проб и ошибок с вашей стороны. Удачи!
Несколько ссылок, относящихся к вашему дополнительному вопросу:
дамп класса
Документация Apple по API среды выполнения Obj-C< /а>
person
Nate
schedule
29.07.2012