我正在保存從一個社交網站獲得的AccessToken
。當我保存這個時,我知道我們不能直接在iOS SDK中保存非屬性值。如何使用NSUserDefaults在iOS中保存非屬性值?
然後從教程中我開始知道我應該實現NSCoding
類。然後我做到了。
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:self.accessToken];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:@"myEncodedObjectKey"];
[defaults synchronize];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [defaults objectForKey:@"myEncodedObjectKey"];
LOAToken *obj = (LOAToken *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
我實現了NSCoding
代表,但我不知道如何實現delegate methods
。然後當我運行此代碼時出現錯誤
`"-[LOAToken encodeWithCoder:]: unrecognized selector sent to instance 0xa2bb970"
我無法實現NSCoding
以及我的代碼。有什麼建議麼?還有沒有其他方式來存儲非屬性值,如AccessToken
供進一步使用。
編輯:
我正在LinkedIn的這種訪問令牌和希望存儲這樣的:
self.accessToken = [[LOAToken alloc] initWithHTTPResponseBody:responseBody];
// The accessToken Printed....Here I have the AccessToken Value.
NSLog(@"Access===%@",self.accessToken);
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:self.accessToken];
NSLog(@"myEncodedObject===%@",myEncodedObject);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:@"myEncodedObjectKey"];
[defaults synchronize];
這是越來越墜毀,因爲我沒有使用過NSCoding
實現我在LOAToken
做你建議的班級。
我在LAToken
類中做了一個變量值並實現了這兩個方法。
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:value forKey:@"Value"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self.value = [decoder decodeObjectForKey:@"Value"];
return self;
}
然後,當檢索我使用這個。
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [defaults objectForKey:@"myEncodedObjectKey"];
LOAToken *obj = (OAToken *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
當我在兩個歸檔和取消存檔的時間,然後打印數據打印的數據是一樣。這可能是由於兩個原因。
我已經取消存檔的數據是正確的,檢索的方式是錯誤的,您可以通過我上面的代碼建議。
我在歸檔時保存的數據爲空。因此保存了空值。
保存訪問令牌是否有任何限制。可能是這可能是空輸出的原因。
這我得到的輸出是這樣的:
oauth_token "(null)" oauth_token_secret "(null)" oauth_verifier "(null)"
文本"oauth_token"
"oauth_token_secret"
"oauth_verifier"
從未來的accessToken但它們的值是零。
編輯2:這是LinkedIn的OAToken類哪裏我得到我傳遞的編碼方法
OAToken訪問Token.The同樣的道理。^ h
#import <Foundation/Foundation.h>
@interface OAToken : NSObject {
@protected
NSString *key;
NSString *secret;
NSString *session;
NSString *verifier;
NSNumber *duration;
NSMutableDictionary *attributes;
NSDate *created;
BOOL renewable;
BOOL forRenewal;
OAToken *value;
}
@property(retain, readwrite) NSString *key;
@property(retain, readwrite) NSString *secret;
@property(retain, readwrite) NSString *session;
@property(retain, readwrite) NSString *verifier;
@property(retain, readwrite) NSNumber *duration;
@property(retain, readwrite) NSMutableDictionary *attributes;
@property(readwrite, getter=isForRenewal) BOOL forRenewal;
@property (nonatomic,retain) OAToken *value;
- (id)initWithKey:(NSString *)aKey secret:(NSString *)aSecret;
- (id)initWithKey:(NSString *)aKey
secret:(NSString *)aSecret
session:(NSString *)aSession
verifier:(NSString *)aVerifier
duration:(NSNumber *)aDuration
attributes:(NSMutableDictionary *)theAttributes
created:(NSDate *)creation
renewable:(BOOL)renew;
- (id)initWithHTTPResponseBody:(NSString *)body;
- (id)initWithUserDefaultsUsingServiceProviderName:(NSString *)provider prefix:(NSString *)prefix;
- (int)storeInUserDefaultsWithServiceProviderName:(NSString *)provider prefix:(NSString *)prefix;
- (BOOL)isValid;
- (void)setAttribute:(NSString *)aKey value:(NSString *)aValue;
- (NSString *)attribute:(NSString *)aKey;
- (void)setAttributesWithString:(NSString *)aAttributes;
- (NSString *)attributeString;
- (BOOL)hasExpired;
- (BOOL)isRenewable;
- (void)setDurationWithString:(NSString *)aDuration;
- (void)setVerifierWithUrl:(NSURL *)aURL;
- (BOOL)hasAttributes;
- (NSMutableDictionary *)parameters;
- (BOOL)isEqualToToken:(OAToken *)aToken;
+ (void)removeFromUserDefaultsWithServiceProviderName:(const NSString *)provider prefix:(const NSString *)prefix;
@end
OAToken.m
#import "NSString+URLEncoding.h"
#import "OAToken.h"
@interface OAToken (Private)
+ (NSString *)settingsKey:(const NSString *)name provider:(const NSString *)provider prefix:(const NSString *)prefix;
+ (id)loadSetting:(const NSString *)name provider:(const NSString *)provider prefix:(const NSString *)prefix;
+ (void)saveSetting:(NSString *)name object:(id)object provider:(const NSString *)provider prefix:(const NSString *)prefix;
+ (NSNumber *)durationWithString:(NSString *)aDuration;
+ (NSMutableDictionary *)attributesWithString:(NSString *)theAttributes;
@end
@implementation OAToken
@synthesize key, secret, session, verifier, duration, attributes, forRenewal;
@synthesize value;
#pragma mark Encode
-(void)encodeWithCoder:(NSCoder *)encoder
{
// This prints the value....
NSLog(@"value===%@",self.value);
[encoder encodeObject:self.value forKey:@"Value"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
OAToken *hell= [decoder decodeObjectForKey:@"Value"];
// This don't have the value.It is null.
NSLog(@"hell===%@",hell);
return self;
}
#pragma mark init
- (id)init {
return [self initWithKey:nil secret:nil];
}
- (id)initWithKey:(NSString *)aKey secret:(NSString *)aSecret {
return [self initWithKey:aKey secret:aSecret session:nil verifier:nil duration:nil
attributes:nil created:nil renewable:NO];
}
- (id)initWithKey:(NSString *)aKey
secret:(NSString *)aSecret
session:(NSString *)aSession
verifier:(NSString *)aVerifier
duration:(NSNumber *)aDuration
attributes:(NSMutableDictionary *)theAttributes
created:(NSDate *)creation
renewable:(BOOL)renew
{
[super init];
self.key = aKey;
self.secret = aSecret;
self.session = aSession;
self.verifier = aVerifier;
self.duration = aDuration;
self.attributes = theAttributes;
created = [creation retain];
renewable = renew;
forRenewal = NO;
return self;
}
- (void)setVerifierWithUrl:(NSURL *)aURL
{
NSString *query = [aURL query];
NSArray *pairs = [query componentsSeparatedByString:@"&"];
for (NSString *pair in pairs)
{
NSArray *elements = [pair componentsSeparatedByString:@"="];
if ([[elements objectAtIndex:0] isEqualToString:@"oauth_verifier"])
{
self.verifier = [elements objectAtIndex:1];
}
}
}
- (id)initWithHTTPResponseBody:(const NSString *)body
{
NSString *aKey = nil;
NSString *aSecret = nil;
NSString *aSession = nil;
NSString *aVerifier = nil;
NSNumber *aDuration = nil;
NSDate *creationDate = nil;
NSMutableDictionary *attrs = nil;
BOOL renew = NO;
NSArray *pairs = [body componentsSeparatedByString:@"&"];
for (NSString *pair in pairs)
{
NSArray *elements = [pair componentsSeparatedByString:@"="];
if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token"])
{
aKey = [elements objectAtIndex:1];
}
else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_secret"])
{
aSecret = [elements objectAtIndex:1];
}
else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_verifier"])
{
aVerifier = [elements objectAtIndex:1];
}
else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_session_handle"])
{
aSession = [elements objectAtIndex:1];
}
else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_duration"])
{
aDuration = [[self class] durationWithString:[elements objectAtIndex:1]];
creationDate = [NSDate date];
}
else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_attributes"])
{
attrs = [[self class] attributesWithString:[[elements objectAtIndex:1] decodedURLString]];
}
else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_renewable"])
{
NSString *lowerCase = [[elements objectAtIndex:1] lowercaseString];
if ([lowerCase isEqualToString:@"true"] || [lowerCase isEqualToString:@"t"]) {
renew = YES;
}
}
}
value=[self initWithKey:aKey
secret:aSecret
session:aSession
verifier:aVerifier
duration:aDuration
attributes:attrs
created:creationDate
renewable:renew];
return [self initWithKey:aKey
secret:aSecret
session:aSession
verifier:aVerifier
duration:aDuration
attributes:attrs
created:creationDate
renewable:renew];
}
- (id)initWithUserDefaultsUsingServiceProviderName:(const NSString *)provider prefix:(const NSString *)prefix {
[super init];
self.key = [OAToken loadSetting:@"key" provider:provider prefix:prefix];
self.secret = [OAToken loadSetting:@"secret" provider:provider prefix:prefix];
self.session = [OAToken loadSetting:@"session" provider:provider prefix:prefix];
self.verifier = [OAToken loadSetting:@"verifier" provider:provider prefix:prefix];
self.duration = [OAToken loadSetting:@"duration" provider:provider prefix:prefix];
self.attributes = [OAToken loadSetting:@"attributes" provider:provider prefix:prefix];
created = [OAToken loadSetting:@"created" provider:provider prefix:prefix];
renewable = [[OAToken loadSetting:@"renewable" provider:provider prefix:prefix] boolValue];
if (![self isValid]) {
[self autorelease];
return nil;
}
return self;
}
#pragma mark dealloc
- (void)dealloc {
self.key = nil;
self.secret = nil;
self.duration = nil;
self.attributes = nil;
[super dealloc];
}
#pragma mark settings
- (BOOL)isValid {
return (key != nil && ![key isEqualToString:@""] && secret != nil && ![secret isEqualToString:@""]);
}
- (int)storeInUserDefaultsWithServiceProviderName:(const NSString *)provider prefix:(const NSString *)prefix {
[OAToken saveSetting:@"key" object:key provider:provider prefix:prefix];
[OAToken saveSetting:@"secret" object:secret provider:provider prefix:prefix];
[OAToken saveSetting:@"created" object:created provider:provider prefix:prefix];
[OAToken saveSetting:@"duration" object:duration provider:provider prefix:prefix];
[OAToken saveSetting:@"session" object:session provider:provider prefix:prefix];
[OAToken saveSetting:@"verifier" object:verifier provider:provider prefix:prefix];
[OAToken saveSetting:@"attributes" object:attributes provider:provider prefix:prefix];
[OAToken saveSetting:@"renewable" object:renewable ? @"t" : @"f" provider:provider prefix:prefix];
[[NSUserDefaults standardUserDefaults] synchronize];
return(0);
}
#pragma mark duration
- (void)setDurationWithString:(NSString *)aDuration {
self.duration = [[self class] durationWithString:aDuration];
}
- (BOOL)hasExpired
{
return created && [created timeIntervalSinceNow] > [duration intValue];
}
- (BOOL)isRenewable
{
return session && renewable && created && [created timeIntervalSinceNow] < (2 * [duration intValue]);
}
#pragma mark attributes
- (void)setAttribute:(const NSString *)aKey value:(const NSString *)aAttribute {
if (!attributes) {
attributes = [[NSMutableDictionary alloc] init];
}
[attributes setObject: aAttribute forKey: aKey];
}
- (void)setAttributes:(NSMutableDictionary *)theAttributes {
[attributes release];
if (theAttributes) {
attributes = [[NSMutableDictionary alloc] initWithDictionary:theAttributes];
}else {
attributes = nil;
}
}
- (BOOL)hasAttributes {
return (attributes && [attributes count] > 0);
}
- (NSString *)attributeString {
if (![self hasAttributes]) {
return @"";
}
NSMutableArray *chunks = [[NSMutableArray alloc] init];
for(NSString *aKey in self->attributes) {
[chunks addObject:[NSString stringWithFormat:@"%@:%@", aKey, [attributes objectForKey:aKey]]];
}
NSString *attrs = [chunks componentsJoinedByString:@";"];
[chunks release];
return attrs;
}
- (NSString *)attribute:(NSString *)aKey
{
return [attributes objectForKey:aKey];
}
- (void)setAttributesWithString:(NSString *)theAttributes
{
self.attributes = [[self class] attributesWithString:theAttributes];
}
- (NSMutableDictionary *)parameters
{
NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease];
if (key)
{
[params setObject:key forKey:@"oauth_token"];
if ([self isForRenewal])
{
[params setObject:session forKey:@"oauth_session_handle"];
}
}
else
{
if (duration)
{
[params setObject:[duration stringValue] forKey: @"oauth_token_duration"];
}
if ([attributes count])
{
[params setObject:[self attributeString] forKey:@"oauth_token_attributes"];
}
}
if (verifier)
{
[params setObject:verifier forKey:@"oauth_verifier"];
}
return params;
}
#pragma mark comparisions
- (BOOL)isEqual:(id)object {
if([object isKindOfClass:[self class]]) {
return [self isEqualToToken:(OAToken *)object];
}
return NO;
}
- (BOOL)isEqualToToken:(OAToken *)aToken {
/* Since ScalableOAuth determines that the token may be
renewed using the same key and secret, we must also
check the creation date */
if ([self.key isEqualToString:aToken.key] &&
[self.secret isEqualToString:aToken.secret]) {
/* May be nil */
if (created == aToken->created || [created isEqualToDate:aToken->created]) {
return YES;
}
}
return NO;
}
#pragma mark class_functions
+ (NSString *)settingsKey:(NSString *)name provider:(NSString *)provider prefix:(NSString *)prefix {
return [NSString stringWithFormat:@"OAUTH_%@_%@_%@", provider, prefix, [name uppercaseString]];
}
+ (id)loadSetting:(NSString *)name provider:(NSString *)provider prefix:(NSString *)prefix {
return [[NSUserDefaults standardUserDefaults] objectForKey:[self settingsKey:name
provider:provider
prefix:prefix]];
}
+ (void)saveSetting:(NSString *)name object:(id)object provider:(NSString *)provider prefix:(NSString *)prefix {
[[NSUserDefaults standardUserDefaults] setObject:object forKey:[self settingsKey:name
provider:provider
prefix:prefix]];
}
+ (void)removeFromUserDefaultsWithServiceProviderName:(NSString *)provider prefix:(NSString *)prefix {
NSArray *keys = [NSArray arrayWithObjects:@"key", @"secret", @"created", @"duration", @"session", @"verifier", @"attributes", @"renewable", nil];
for(NSString *name in keys) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:[OAToken settingsKey:name provider:provider prefix:prefix]];
}
}
+ (NSNumber *)durationWithString:(NSString *)aDuration {
NSUInteger length = [aDuration length];
unichar c = toupper([aDuration characterAtIndex:length - 1]);
int mult;
if (c >= '0' && c <= '9') {
return [NSNumber numberWithInt:[aDuration intValue]];
}
if (c == 'S') {
mult = 1;
} else if (c == 'H') {
mult = 60 * 60;
} else if (c == 'D') {
mult = 60 * 60 * 24;
} else if (c == 'W') {
mult = 60 * 60 * 24 * 7;
} else if (c == 'M') {
mult = 60 * 60 * 24 * 30;
} else if (c == 'Y') {
mult = 60 * 60 * 365;
} else {
mult = 1;
}
return [NSNumber numberWithInt: mult * [[aDuration substringToIndex:length - 1] intValue]];
}
+ (NSMutableDictionary *)attributesWithString:(NSString *)theAttributes {
NSArray *attrs = [theAttributes componentsSeparatedByString:@";"];
NSMutableDictionary *dct = [[NSMutableDictionary alloc] init];
for (NSString *pair in attrs) {
NSArray *elements = [pair componentsSeparatedByString:@":"];
[dct setObject:[elements objectAtIndex:1] forKey:[elements objectAtIndex:0]];
}
return [dct autorelease];
}
#pragma mark description
- (NSString *)description {
return [NSString stringWithFormat:@"oauth_token \"%@\" oauth_token_secret \"%@\" oauth_verifier \"%@\"", key, secret, verifier];
}
@end
你的類必須支持NSCoding協議。那麼只有你可以使用的NSKeyedArchiver – Exploring