-
Notifications
You must be signed in to change notification settings - Fork 3.5k
/
SUUserManager.m
176 lines (140 loc) · 6.3 KB
/
SUUserManager.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
* Copyright 2012 Facebook
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "SUUserManager.h"
#import <FacebookSDK/FBSessionTokenCachingStrategy.h>
#import <FacebookSDK/FacebookSDK.h>
NSString *const SUInvalidSlotNumber = @"com.facebook.SwitchUserSample:InvalidSlotNumber";
static NSString *const SUUserIDKeyFormat = @"SUUserID%d";
static NSString *const SUUserNameKeyFormat = @"SUUserName%d";
@implementation SUUserManager
@synthesize currentSession = _currentSession;
@synthesize currentUserSlot = _currentUserSlot;
- (id)init {
self = [super init];
if (self) {
_currentUserSlot = -1;
}
return self;
}
- (void)sendNotification {
[[NSNotificationCenter defaultCenter] postNotificationName:@"SUUserManagerUserChanged"
object:nil];
}
- (void)validateSlotNumber:(int)slot {
if (slot < 0 || slot >= [self maximumUserSlots]) {
[[NSException exceptionWithName:SUInvalidSlotNumber
reason:[NSString stringWithFormat:@"Invalid slot number %d specified", slot]
userInfo:nil]
raise];
}
}
- (int)maximumUserSlots {
return 4;
}
- (FBSessionTokenCachingStrategy*)createCachingStrategyForSlot:(int)slot {
// FBSample logic
// Token caching strategies are an advanced feature of the SDK; by creating one and passing it to
// FBSession at instantiation time, the SUUserManager class takes control of the token caching
// behavior of session instances; this is useful to do in this application, because there may be up
// to four users whose tokens are remembered by the application at one time; and so the names in
// NSUserDefaults used to store these values need to reflect the user whose data is being cached
// Note: an application with more advanced token caching needs (beyond NSUserDefaults) can derive
// from FBSessionTokenCachingStrategy, and implement any store for the token cache that it needs,
// including storing and retrieving tokens on an application-specific server, filesystem, etc.
FBSessionTokenCachingStrategy *tokenCachingStrategy = [[FBSessionTokenCachingStrategy alloc]
initWithUserDefaultTokenInformationKeyName:[NSString stringWithFormat:@"SUUserTokenInfo%d", slot]];
return tokenCachingStrategy;
}
- (BOOL)isSlotEmpty:(int)slot {
return [self getUserIDInSlot:slot] == nil;
}
- (BOOL)areAllSlotsEmpty {
int numSlots = [self maximumUserSlots];
for (int i = 0; i < numSlots; ++i) {
if ([self isSlotEmpty:i] == NO) {
return NO;
}
}
return YES;
}
- (FBSession*)createSessionForSlot:(int)slot {
// FBSample logic
// Getting the right strategy instance for the right slot matters for this application
FBSessionTokenCachingStrategy *tokenCachingStrategy = [self createCachingStrategyForSlot:slot];
// create a session object, with defaults accross the board, except that we provide a custom
// instance of FBSessionTokenCachingStrategy
FBSession *session = [[FBSession alloc] initWithAppID:nil
permissions:nil
urlSchemeSuffix:nil
tokenCacheStrategy:tokenCachingStrategy];
return session;
}
- (NSString*)getUserNameInSlot:(int)slot {
[self validateSlotNumber:slot];
NSString *key = [NSString stringWithFormat:SUUserNameKeyFormat, slot];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Don't assume we have a full FBGraphObject -- builds compiled with earlier versions of SDK
// may have saved only a plain NSDictionary.
return [defaults objectForKey:key];
}
- (NSString*)getUserIDInSlot:(int)slot {
[self validateSlotNumber:slot];
NSString *key = [NSString stringWithFormat:SUUserIDKeyFormat, slot];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Don't assume we have a full FBGraphObject -- builds compiled with earlier versions of SDK
// may have saved only a plain NSDictionary.
return [defaults objectForKey:key];
}
- (void)updateUser:(NSDictionary<FBGraphUser> *)user inSlot:(int)slot {
[self validateSlotNumber:slot];
NSString *idKey = [NSString stringWithFormat:SUUserIDKeyFormat, slot];
NSString *nameKey = [NSString stringWithFormat:SUUserNameKeyFormat, slot];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (user != nil ) {
NSLog(@"SUUserManager updating slot %d: fbid = %@, name = %@", slot, user.id, user.name);
[defaults setObject:user.id forKey:idKey];
[defaults setObject:user.name forKey:nameKey];
} else {
NSLog(@"SUUserManager clearing slot %d", slot);
// Can't be current user anymore
if (slot == _currentUserSlot) {
[self switchToNoActiveUser];
}
// FBSample logic
// Also need to tell the token cache to forget the tokens for this user
FBSessionTokenCachingStrategy *tokenCachingStrategy = [self createCachingStrategyForSlot:slot];
[tokenCachingStrategy clearToken];
[defaults removeObjectForKey:idKey];
[defaults removeObjectForKey:nameKey];
}
[defaults synchronize];
[self sendNotification];
}
- (void)switchToNoActiveUser {
NSLog(@"SUUserManager switching to no active user");
_currentSession = nil;
_currentUserSlot = -1;
[self sendNotification];
}
- (FBSession *)switchToUserInSlot:(int)slot {
[self validateSlotNumber:slot];
NSLog(@"SUUserManager switching to slot %d", slot);
FBSession *session = [self createSessionForSlot:slot];
_currentSession = session;
_currentUserSlot = slot;
[self sendNotification];
return session;
}
@end