Наблюдението на ключовите стойности е страхотна функция, но не ви помага (директно) с този конкретен проблем. За тези, които не са запознати с класа, който той има предвид, това е частен клас в самия iOS SpringBoard. Така че той няма контрол върху това как публикува данните, от които се интересува.
Не можете да наблюдавате само стари данни. Той трябва да бъде кодиран, за да бъде съвместим с Key Value Observing (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 сигнала. Но аз нямам опит с тях и това ще бъде метод проба-грешка от ваша страна. Късмет!
Няколко препратки, отнасящи се до вашия Вторичен въпрос:
class-dump
Документи на Apple относно API за изпълнение на Obj-C
person
Nate
schedule
29.07.2012