2011-07-14 17 views
11

私のiPhoneアプリでは、Contactというクラスがあり、特定の連絡先への参照として役立つABRecordRefで構成されています。NSUserDefaultsにデータを保存する

これらの連絡先のグループをNSUserDefaultsに保存する必要がありますが、Contactはカスタムクラスなので、うまく機能しません。

この場合、何をすべきか考えてください。

答えて

29

カスタムクラスにNSUserDefaultsを使用することはできません。ドキュメントから:

NSUserDefaultsクラスには、山車、ダブルス、整数、ブール値、およびURLなど 一般的な種類にアクセスするための便利なメソッドを提供します。 デフォルトのオブジェクトは、プロパティリストである必要があり、それは、(のインスタンスの組み合わせまたはコレクションの )のインスタンスである:NSDataNSStringNSNumberNSDateNSArray、又はNSDictionary。 他の種類のオブジェクトを保存する場合は、通常、それをアーカイブして のインスタンスをNSDataに作成する必要があります。

NSDataを試してください。

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"]; 

これは長い間、カスタムオブジェクトがNSCodingプロトコルに準拠して、すべての作業は以下となります。たとえば、配列にカスタムオブジェクトをロードするために、あなたはデータ、使用をアーカイブするには

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults]; 
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"]; 
if (dataRepresentingSavedArray != nil) 
{ 
     NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray]; 
     if (oldSavedArray != nil) 
       objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray]; 
     else 
       objectArray = [[NSMutableArray alloc] init]; 
} 

を行うことができます:

- (void)encodeWithCoder:(NSCoder *)coder; 
{ 
    [coder encodeObject:label forKey:@"label"]; 
    [coder encodeInteger:numberID forKey:@"numberID"]; 
} 

- (id)initWithCoder:(NSCoder *)coder; 
{ 
    self = [[CustomObject alloc] init]; 
    if (self != nil) 
    { 
     label = [coder decodeObjectForKey:@"label"]; 
     numberID = [coder decodeIntegerForKey:@"numberID"]; 
    } 
    return self; 
} 

ABRecord不透明C型であるので、Objective-Cの意味でのオブジェクトではありません。つまり、それを拡張することはできません。カテゴリを追加することはできません。メッセージを送ることはできません。あなたが行うことができるのは、ABRecordをパラメータとしてABRecordリファレンスに記載されているコール関数です。

あなたは周りABRecordが参照する情報を保持できるようにするには2つのことを行うことができます:

  1. ABRecordGetRecordID()によってABRecordidを取得します。 ABRecordIDはint32_tとして定義されていますので、NSIntegerにキャストして好きな場所に保存できます。後でそのレコードをABAddressBookGetPersonWithRecordID()またはABAddressBookGetGroupWithRecordID()から戻すことができます。ただし、その間にユーザーや他のアプリによってレコードが変更または削除される可能性があります。

  2. レコード内のすべての値を標準NSObjectサブクラスにコピーし、上記のようにNSCodingを使用して格納します。もちろん、ユーザーが作成したレコードの変更や追加の恩恵を受けることはありません。

+0

しかし、オブジェクトではないので、私はABRecordRefをエンコードできません。 – CodeGuy

+0

そう、私はすべてそれをしました。しかし、私はどのようにABRecordRefをエンコードするのですか? – CodeGuy

+0

@ reising1:上記を参照してください。 – PengOne

1

ABRecordRefはconst void *も、そうNSUserDefaultsに保管するように見える、あなたはNSDataでそれをラップする必要があります:NSData *d = [[NSData alloc] initWithBytes:thePointer length:sizeof(ABRecordRef)];

+0

はい、しかし、それは明らかにオブジェクトではないので、ABRecordRefをどのように保存しますか? – CodeGuy

+0

あなたは少なくともそれが何であるか知っていますか?オブジェクト、構造体、基本型? –

2

まあ、Apple's recommendationは、レコード識別子、名、姓を格納します。アドレス帳から識別子で連絡先を取得し、レコードが見つからない場合、または適切な人物でない場合は、氏名で検索してみてください(レコード識別子はあなたのソースアドレス帳データ)。

これは、データを保存する理由によって、必要な場合とそうでない場合があります。しかし、あなたはかなり簡単にこれらの3つの値をNSDictionaryに入れ、辞書をNSUserDefaultsに書き込むことができます。

0

実際には、NSStringとして簡単に使用できるvCard表現(CFStringRef)への変換を使用して格納することができます。

関連する問題