Key Value Observing は優れた機能ですが、この特定の問題を (直接的に) 解決することはできません。彼が言及しているクラスに慣れていない人のために説明すると、これは 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;
ivar を名前で取得するヘルパー:
#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 信号強度がいつ変化したかを判断しようとしている場合は、すべてフックの候補のように見えます。しかし、私はそれらの経験がなく、あなたの側で試行錯誤するでしょう. 幸運を!
二次的な質問に関するいくつかの参考文献:
クラスダンプ
Obj-C ランタイム API に関する Apple ドキュメント