mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-24 04:46:01 +08:00
Found a nasty bug in object mapping with nil values vs missing key paths. Polished login and sign up patterns thoroughly. Login/Logout & sign up are functional again. Now to move through the rest of the app
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// DBLoginViewController.h
|
||||
// DBLoginOrSignUpViewController.h
|
||||
// DiscussionBoard
|
||||
//
|
||||
// Created by Jeremy Ellison on 1/10/11.
|
||||
@@ -9,8 +9,9 @@
|
||||
#import <Three20/Three20.h>
|
||||
#import <Three20/Three20+Additions.h>
|
||||
#import <RestKit/RestKit.h>
|
||||
#import "DBUser.h"
|
||||
|
||||
@interface DBLoginViewController : TTTableViewController <UITextFieldDelegate, RKObjectLoaderDelegate> {
|
||||
@interface DBLoginOrSignUpViewController : TTTableViewController <UITextFieldDelegate, DBUserAuthenticationDelegate> {
|
||||
UIBarButtonItem* _signupOrLoginButtonItem;
|
||||
BOOL _showingSignup;
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
//
|
||||
// DBLoginViewController.m
|
||||
// DBLoginOrSignUpViewController.m
|
||||
// DiscussionBoard
|
||||
//
|
||||
// Created by Jeremy Ellison on 1/10/11.
|
||||
// Copyright 2011 Two Toasters. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DBLoginViewController.h"
|
||||
#import "DBUser.h"
|
||||
#import "DBLoginOrSignUpViewController.h"
|
||||
|
||||
@implementation DBLoginViewController
|
||||
@implementation DBLoginOrSignUpViewController
|
||||
|
||||
- (id)initWithNavigatorURL:(NSURL *)URL query:(NSDictionary *)query {
|
||||
if (self = [super initWithNavigatorURL:URL query:query]) {
|
||||
@@ -21,6 +20,11 @@
|
||||
}
|
||||
|
||||
- (void)viewDidUnload {
|
||||
// Resign as the delegate
|
||||
if ([DBUser currentUser].delegate == self) {
|
||||
[DBUser currentUser].delegate = nil;
|
||||
}
|
||||
|
||||
TT_RELEASE_SAFELY(_signupOrLoginButtonItem);
|
||||
TT_RELEASE_SAFELY(_usernameField);
|
||||
TT_RELEASE_SAFELY(_passwordField);
|
||||
@@ -99,7 +103,6 @@
|
||||
[self invalidateModel];
|
||||
}
|
||||
|
||||
// TODO: Move login and sign-up into the model as higher level concepts
|
||||
- (void)loginOrSignup {
|
||||
if (_showingSignup) {
|
||||
// Signup
|
||||
@@ -108,14 +111,12 @@
|
||||
user.email = _emailField.text;
|
||||
user.password = _passwordField.text;
|
||||
user.passwordConfirmation = _passwordConfirmationField.text;
|
||||
|
||||
[[RKObjectManager sharedManager] postObject:user delegate:self];
|
||||
[user signUpWithDelegate:self];
|
||||
} else {
|
||||
// Login
|
||||
DBUser* user = [DBUser object];
|
||||
user.username = _usernameField.text;
|
||||
user.password = _passwordField.text;
|
||||
[[RKObjectManager sharedManager] putObject:user delegate:self];
|
||||
DBUser* user = [DBUser object];
|
||||
user.delegate = self;
|
||||
[user loginWithUsername:_usernameField.text andPassword:_passwordField.text delegate:self];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,15 +141,18 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
|
||||
assert([objects count] == 1);
|
||||
DBUser* user = [objects objectAtIndex:0];
|
||||
NSLog(@"Authentication Token: %@", user.singleAccessToken);
|
||||
#pragma mark DBUserAuthenticationDelegate methods
|
||||
|
||||
- (void)userDidLogin:(DBUser*)user {
|
||||
[self dismissModalViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
|
||||
// TODO: TTAlert???
|
||||
- (void)user:(DBUser*)user didFailSignUpWithError:(NSError*)error {
|
||||
TTAlert([error localizedDescription]);
|
||||
}
|
||||
|
||||
- (void)user:(DBUser*)user didFailLoginWithError:(NSError*)error {
|
||||
// TTAlert([error localizedDescription]);
|
||||
[[[[UIAlertView alloc] initWithTitle:@"Error"
|
||||
message:[error localizedDescription]
|
||||
delegate:nil
|
||||
@@ -27,6 +27,7 @@
|
||||
[super createModel];
|
||||
|
||||
UIBarButtonItem* item = nil;
|
||||
NSLog(@"Updating model for Topics table! Current User is: %@", [DBUser currentUser]);
|
||||
if ([[DBUser currentUser] isLoggedIn]) {
|
||||
item = [[[UIBarButtonItem alloc] initWithTitle:@"Logout" style:UIBarButtonItemStyleBordered target:self action:@selector(logoutButtonWasPressed:)] autorelease];
|
||||
}
|
||||
@@ -46,6 +47,7 @@
|
||||
}
|
||||
|
||||
- (void)logoutButtonWasPressed:(id)sender {
|
||||
NSLog(@"Current user is: %@", [DBUser currentUser]);
|
||||
[[DBUser currentUser] logout];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#import <RestKit/CoreData/CoreData.h>
|
||||
|
||||
// Declared here and defined below
|
||||
@protocol DBUserDelegate;
|
||||
@protocol DBUserAuthenticationDelegate;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
// Transient. Used for login & sign-up
|
||||
NSString* _password;
|
||||
NSString* _passwordConfirmation;
|
||||
NSObject<DBUserDelegate>* _delegate;
|
||||
NSObject<DBUserAuthenticationDelegate>* _delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* The delegate for the User. Will be informed of session life-cycle events
|
||||
*/
|
||||
@property (nonatomic, retain) NSObject<DBUserDelegate>* delegate;
|
||||
@property (nonatomic, assign) NSObject<DBUserAuthenticationDelegate>* delegate;
|
||||
|
||||
/**
|
||||
* The e-mail address of the User
|
||||
@@ -66,10 +66,15 @@
|
||||
*/
|
||||
+ (DBUser*)currentUser;
|
||||
|
||||
/**
|
||||
* Completes a sign up using the properties assigned to the object
|
||||
*/
|
||||
- (void)signUpWithDelegate:(NSObject<DBUserAuthenticationDelegate>*)delegate;
|
||||
|
||||
/**
|
||||
* Attempts to log a User into the system with a given username and password
|
||||
*/
|
||||
- (void)loginWithUsername:(NSString*)username andPassword:(NSString*)password;
|
||||
- (void)loginWithUsername:(NSString*)username andPassword:(NSString*)password delegate:(NSObject<DBUserAuthenticationDelegate>*)delegate;
|
||||
|
||||
/**
|
||||
* Returns YES when the User is logged in
|
||||
@@ -90,14 +95,26 @@
|
||||
* Notifications
|
||||
*/
|
||||
extern NSString* const DBUserDidLoginNotification; // Posted when the User logs in
|
||||
extern NSString* const DBUserDidFailLoginNotification; // Posted when the User fails login. userInfo contains NSError with reason
|
||||
extern NSString* const DBUserDidLogoutNotification; // Posted when the User logs out
|
||||
|
||||
/**
|
||||
* A protocol defining life-cycles events for a user logging in and out
|
||||
* of the application
|
||||
*/
|
||||
@protocol DBUserDelegate
|
||||
@protocol DBUserAuthenticationDelegate
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Sent to the delegate when sign up has completed successfully. Immediately
|
||||
* followed by an invocation of userDidLogin:
|
||||
*/
|
||||
- (void)userDidSignUp:(DBUser*)user;
|
||||
|
||||
/**
|
||||
* Sent to the delegate when sign up failed for a specific reason
|
||||
*/
|
||||
- (void)user:(DBUser*)user didFailSignUpWithError:(NSError*)error;
|
||||
|
||||
/**
|
||||
* Sent to the delegate when the User has successfully authenticated
|
||||
|
||||
@@ -16,6 +16,9 @@ NSString* const DBUserDidLoginNotification = @"DBUserDidLoginNotification";
|
||||
NSString* const DBUserDidFailLoginNotification = @"DBUserDidFailLoginNotification";
|
||||
NSString* const DBUserDidLogoutNotification = @"DBUserDidLogoutNotification";
|
||||
|
||||
// Current User singleton
|
||||
static DBUser* currentUser = nil;
|
||||
|
||||
@implementation DBUser
|
||||
|
||||
@dynamic email;
|
||||
@@ -34,7 +37,7 @@ NSString* const DBUserDidLogoutNotification = @"DBUserDidLogoutNotification";
|
||||
return [NSDictionary dictionaryWithKeysAndObjects:
|
||||
@"id", @"userID",
|
||||
@"email", @"email",
|
||||
@"username", @"login",
|
||||
@"username", @"username",
|
||||
@"single_access_token", @"singleAccessToken",
|
||||
@"password", @"password",
|
||||
@"password_confirmation", @"passwordConfirmation",
|
||||
@@ -54,24 +57,52 @@ NSString* const DBUserDidLogoutNotification = @"DBUserDidLogoutNotification";
|
||||
* are not sending messages to nil
|
||||
*/
|
||||
+ (DBUser*)currentUser {
|
||||
id userID = [[NSUserDefaults standardUserDefaults] objectForKey:kDBUserCurrentUserIDDefaultsKey];
|
||||
if (userID) {
|
||||
return [self objectWithPrimaryKeyValue:userID];
|
||||
} else {
|
||||
return [self object];
|
||||
if (nil == currentUser) {
|
||||
id userID = [[NSUserDefaults standardUserDefaults] objectForKey:kDBUserCurrentUserIDDefaultsKey];
|
||||
if (userID) {
|
||||
currentUser = [self objectWithPrimaryKeyValue:userID];
|
||||
} else {
|
||||
currentUser = [self object];
|
||||
}
|
||||
|
||||
[currentUser retain];
|
||||
}
|
||||
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
+ (void)setCurrentUser:(DBUser*)user {
|
||||
[user retain];
|
||||
[currentUser release];
|
||||
currentUser = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of a RESTful sign-up pattern. We are just relying on RestKit for
|
||||
* request/response processing and object mapping, but we have built a higher level
|
||||
* abstraction around Sign-Up as a concept and exposed notifications and delegate
|
||||
* methods that make it much more meaningful than a POST/parse/process cycle would be.
|
||||
*/
|
||||
- (void)signUpWithDelegate:(NSObject<DBUserAuthenticationDelegate>*)delegate {
|
||||
_delegate = delegate;
|
||||
[[RKObjectManager sharedManager] postObject:self delegate:self];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of a RESTful login pattern. We construct an object loader addressed to
|
||||
* the /login resource path and POST the credentials. The target of the object loader is
|
||||
* set so that the login request
|
||||
*
|
||||
* set so that the login response gets mapped back into this object, populating the
|
||||
* properties according to the mappings declared in elementToPropertyMappings.
|
||||
*/
|
||||
- (void)loginWithUsername:(NSString*)username andPassword:(NSString*)password {
|
||||
- (void)loginWithUsername:(NSString*)username andPassword:(NSString*)password delegate:(NSObject<DBUserAuthenticationDelegate>*)delegate {
|
||||
_delegate = delegate;
|
||||
|
||||
// TODO: Cleanup. Save the object store so that background threads can update this object
|
||||
[[RKObjectManager sharedManager] saveObjectStore];
|
||||
|
||||
RKObjectLoader* objectLoader = [[RKObjectManager sharedManager] objectLoaderWithResourcePath:@"/login" delegate:self];
|
||||
objectLoader.method = RKRequestMethodPOST;
|
||||
objectLoader.params = [NSDictionary dictionaryWithKeysAndObjects:@"username", username, @"password", password, nil];
|
||||
objectLoader.params = [NSDictionary dictionaryWithKeysAndObjects:@"user[username]", username, @"user[password]", password, nil];
|
||||
objectLoader.targetObject = self;
|
||||
[objectLoader send];
|
||||
}
|
||||
@@ -80,32 +111,43 @@ NSString* const DBUserDidLogoutNotification = @"DBUserDidLogoutNotification";
|
||||
* Implementation of a RESTful logout pattern. We POST an object loader to
|
||||
* the /logout resource path. This destroys the remote session
|
||||
*/
|
||||
- (void)logout {
|
||||
- (void)logout {
|
||||
RKObjectLoader* objectLoader = [[RKObjectManager sharedManager] objectLoaderWithResourcePath:@"/logout" delegate:self];
|
||||
objectLoader.method = RKRequestMethodPOST;
|
||||
objectLoader.targetObject = self; // TODO: Not sure I need this?
|
||||
objectLoader.targetObject = self;
|
||||
[objectLoader send];
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray *)objects {
|
||||
DBUser* user = [objects objectAtIndex:0];
|
||||
- (void)loginWasSuccessful {
|
||||
// Upon login, we become the current user
|
||||
[DBUser setCurrentUser:self];
|
||||
|
||||
// Persist the UserID for recovery later
|
||||
[[NSUserDefaults standardUserDefaults] setObject:self.userID forKey:kDBUserCurrentUserIDDefaultsKey];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
|
||||
// Inform the delegate
|
||||
if ([self.delegate respondsToSelector:@selector(userDidLogin:)]) {
|
||||
[self.delegate userDidLogin:self];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:DBUserDidLoginNotification object:self];
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray *)objects {
|
||||
// NOTE: We don't need objects because self is the target of the mapping operation
|
||||
|
||||
if ([objectLoader wasSentToResourcePath:@"/login"]) {
|
||||
// Login was successful
|
||||
|
||||
// Persist the UserID for recovery later
|
||||
[[NSUserDefaults standardUserDefaults] setObject:user.userID forKey:kDBUserCurrentUserIDDefaultsKey];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
|
||||
// Inform the delegate
|
||||
if ([self.delegate respondsToSelector:@selector(userDidLogin:)]) {
|
||||
[self.delegate userDidLogin:self];
|
||||
[self loginWasSuccessful];
|
||||
} else if ([objectLoader wasSentToResourcePath:@"/signup"]) {
|
||||
// Sign Up was successful
|
||||
if ([self.delegate respondsToSelector:@selector(userDidSignUp:)]) {
|
||||
[self.delegate userDidSignUp:self];
|
||||
}
|
||||
|
||||
RKObjectManager* objectManager = [RKObjectManager sharedManager];
|
||||
[objectManager.client setValue:[DBUser currentUser].singleAccessToken forHTTPHeaderField:kAccessTokenHeaderField];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:DBUserDidLoginNotification object:user];
|
||||
// Complete the login as well
|
||||
[self loginWasSuccessful];
|
||||
} else if ([objectLoader wasSentToResourcePath:@"/logout"]) {
|
||||
// Logout was successful
|
||||
|
||||
@@ -118,46 +160,30 @@ NSString* const DBUserDidLogoutNotification = @"DBUserDidLogoutNotification";
|
||||
[self.delegate userDidLogout:self];
|
||||
}
|
||||
|
||||
RKObjectManager* objectManager = [RKObjectManager sharedManager];
|
||||
[objectManager.client setValue:nil forHTTPHeaderField:kAccessTokenHeaderField];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:DBUserDidLogoutNotification object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError*)error {
|
||||
// Login failed
|
||||
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError*)error {
|
||||
if ([objectLoader wasSentToResourcePath:@"/login"]) {
|
||||
// Login failed
|
||||
if ([self.delegate respondsToSelector:@selector(user:didFailLoginWithError:)]) {
|
||||
[self.delegate user:self didFailLoginWithError:error];
|
||||
}
|
||||
} else if ([objectLoader wasSentToResourcePath:@"/signup"]) {
|
||||
// Sign Up failed
|
||||
if ([self.delegate respondsToSelector:@selector(user:didFailSignUpWithError:)]) {
|
||||
[self.delegate user:self didFailSignUpWithError:error];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Do I need this?
|
||||
- (void)reauthenticate {
|
||||
}
|
||||
|
||||
- (BOOL)isLoggedIn {
|
||||
return self.singleAccessToken != nil;
|
||||
}
|
||||
|
||||
// TODO: Do I need this?
|
||||
//- (NSObject<RKRequestSerializable>*)paramsForSerialization {
|
||||
// if (_passwordConfirmation) {
|
||||
// return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
// self.email, @"user[email]",
|
||||
// self.login, @"user[login]",
|
||||
// self.password, @"user[password]",
|
||||
// self.passwordConfirmation, @"user[password_confirmation]", nil];
|
||||
// } else {
|
||||
// return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
// self.login, @"user[login]",
|
||||
// self.password, @"user[password]", nil];
|
||||
// }
|
||||
//}
|
||||
|
||||
- (void)dealloc {
|
||||
_delegate = nil;
|
||||
[_password release];
|
||||
[_passwordConfirmation release];
|
||||
[super dealloc];
|
||||
|
||||
@@ -20,4 +20,14 @@ extern NSString* const DBRestKitBaseURL;
|
||||
// TODO: See if we can eliminate or abstract this further
|
||||
extern NSString* const kObjectCreatedUpdatedOrDestroyedNotificationName;
|
||||
|
||||
extern NSString* const kAccessTokenHeaderField;
|
||||
/**
|
||||
* Server Environments for conditional compilation
|
||||
*/
|
||||
#define DB_ENVIRONMENT_DEVELOPMENT 0
|
||||
#define DB_ENVIRONMENT_STAGING 1
|
||||
#define DB_ENVIRONMENT_PRODUCTION 2
|
||||
|
||||
// Use Production by default
|
||||
#ifndef DB_ENVIRONMENT
|
||||
#define DB_ENVIRONMENT DB_ENVIRONMENT_PRODUCTION
|
||||
#endif
|
||||
|
||||
@@ -8,9 +8,14 @@
|
||||
|
||||
#import "DBEnvironment.h"
|
||||
|
||||
// TODO: Add conditional compilation!
|
||||
NSString* const DBRestKitBaseURL = @"http://localhost:3000";
|
||||
//NSString* const kDBBaseURLString = @"http://discussionboard.heroku.com";
|
||||
NSString* const kObjectCreatedUpdatedOrDestroyedNotificationName = @"kObjectCreatedUpdatedOrDestroyedNotificationName";
|
||||
// Base URL
|
||||
#if DB_ENVIRONMENT == DB_ENVIRONMENT_DEVELOPMENT
|
||||
NSString* const DBRestKitBaseURL = @"http://localhost:3000";
|
||||
#elif DB_ENVIRONMENT == DB_ENVIRONMENT_STAGING
|
||||
// TODO: Need a staging environment...
|
||||
#elif DB_ENVIRONMENT == DB_ENVIRONMENT_PRODUCTION
|
||||
NSString* const DBRestKitBaseURL = @"http://discussionboard.heroku.com";
|
||||
#endif
|
||||
|
||||
NSString* const kAccessTokenHeaderField = @"X-USER-ACCESS-TOKEN";
|
||||
// TODO: Eliminate
|
||||
NSString* const kObjectCreatedUpdatedOrDestroyedNotificationName = @"kObjectCreatedUpdatedOrDestroyedNotificationName";
|
||||
|
||||
@@ -24,17 +24,21 @@
|
||||
#import "DBPost.h"
|
||||
#import "DBManagedObjectCache.h"
|
||||
#import "DBTopicViewController.h"
|
||||
#import "DBLoginViewController.h"
|
||||
#import "DBLoginOrSignUpViewController.h"
|
||||
#import "DBUser.h"
|
||||
#import "DBPostTableViewController.h"
|
||||
|
||||
/**
|
||||
* The HTTP Header Field we transmit the authentication token obtained
|
||||
* during login/sign-up back to the server. This token is verified server
|
||||
* side to establish an authenticated session
|
||||
*/
|
||||
static NSString* const kDBAccessTokenHTTPHeaderField = @"X-USER-ACCESS-TOKEN";
|
||||
|
||||
@implementation DiscussionBoardAppDelegate
|
||||
|
||||
@synthesize window;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Application lifecycle
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
// Initialize object manager
|
||||
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:DBRestKitBaseURL];
|
||||
@@ -44,7 +48,9 @@
|
||||
[RKRequestTTModel setDefaultRefreshRate:1];
|
||||
|
||||
// Do not overwrite properties that are missing in the payload to nil.
|
||||
objectManager.mapper.missingElementMappingPolicy = RKIgnoreMissingElementMappingPolicy;
|
||||
// TODO: Fix! There is a bug where elements that are in the payload
|
||||
// objectManager.mapper.missingElementMappingPolicy = RKIgnoreMissingElementMappingPolicy;
|
||||
objectManager.mapper.missingElementMappingPolicy = RKSetNilForMissingElementMappingPolicy;
|
||||
|
||||
// Initialize object store
|
||||
objectManager.objectStore = [[[RKManagedObjectStore alloc] initWithStoreFilename:@"DiscussionBoard.sqlite"] autorelease];
|
||||
@@ -56,18 +62,18 @@
|
||||
[mapper registerClass:[DBPost class] forElementNamed:@"post"];
|
||||
|
||||
// Set Up Router
|
||||
// TODO: Switch to Rails Router
|
||||
RKDynamicRouter* router = [[[RKDynamicRouter alloc] init] autorelease];
|
||||
// RKRailsRouter* router = [[[RKRailsRouter alloc] init] autorelease];
|
||||
// TODO: Comment me!
|
||||
RKRailsRouter* router = [[[RKRailsRouter alloc] init] autorelease];
|
||||
[router setModelName:@"user" forClass:[DBUser class]];
|
||||
[router routeClass:[DBUser class] toResourcePath:@"/signup" forMethod:RKRequestMethodPOST];
|
||||
[router routeClass:[DBUser class] toResourcePath:@"/login" forMethod:RKRequestMethodPUT];
|
||||
|
||||
// [router setModelName:@"topic" forClass:[DBTopic class]];
|
||||
[router setModelName:@"topic" forClass:[DBTopic class]];
|
||||
[router routeClass:[DBTopic class] toResourcePath:@"/topics" forMethod:RKRequestMethodPOST];
|
||||
[router routeClass:[DBTopic class] toResourcePath:@"/topics/(topicID)" forMethod:RKRequestMethodPUT];
|
||||
[router routeClass:[DBTopic class] toResourcePath:@"/topics/(topicID)" forMethod:RKRequestMethodDELETE];
|
||||
|
||||
// [router setModelName:@"post" forClass:[DBPost class]];
|
||||
[router setModelName:@"post" forClass:[DBPost class]];
|
||||
[router routeClass:[DBPost class] toResourcePath:@"/topics/(topicID)/posts" forMethod:RKRequestMethodPOST];
|
||||
[router routeClass:[DBPost class] toResourcePath:@"/topics/(topicID)/posts/(postID)" forMethod:RKRequestMethodPUT];
|
||||
[router routeClass:[DBPost class] toResourcePath:@"/topics/(topicID)/posts/(postID)" forMethod:RKRequestMethodDELETE];
|
||||
@@ -82,25 +88,39 @@
|
||||
[map from:@"db://topics/new" toViewController:[DBTopicViewController class]];
|
||||
[map from:@"db://posts/(initWithPostID:)" toViewController:[DBPostTableViewController class]];
|
||||
[map from:@"db://topics/(initWithTopicID:)/posts/new" toViewController:[DBPostTableViewController class]];
|
||||
[map from:@"db://login" toModalViewController:[DBLoginViewController class]];
|
||||
|
||||
[map from:@"db://login" toModalViewController:[DBLoginOrSignUpViewController class]];
|
||||
|
||||
[map from:@"*" toViewController:[TTWebController class]];
|
||||
|
||||
[[TTURLRequestQueue mainQueue] setMaxContentLength:0]; // Don't limit content length.
|
||||
|
||||
[[TTURLRequestQueue mainQueue] setMaxContentLength:0]; // Don't limit content length.
|
||||
|
||||
// Register for authentication notifications
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setAccessTokenHeaderFromAuthenticationNotification:) name:DBUserDidLoginNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setAccessTokenHeaderFromAuthenticationNotification:) name:DBUserDidLogoutNotification object:nil];
|
||||
|
||||
// Initialize authenticated access if we have a logged in current User reference
|
||||
DBUser* user = [DBUser currentUser];
|
||||
if ([user isLoggedIn]) {
|
||||
NSLog(@"Found logged in User record for username '%@' [Access Token: %@]", user.username, user.singleAccessToken);
|
||||
[objectManager.client setValue:user.singleAccessToken forHTTPHeaderField:kDBAccessTokenHTTPHeaderField];
|
||||
}
|
||||
|
||||
// Fire up the UI!
|
||||
TTOpenURL(@"db://topics");
|
||||
[[TTNavigator navigator].window makeKeyAndVisible];
|
||||
|
||||
DBUser* user = [DBUser currentUser];
|
||||
NSLog(@"Token: %@", user.singleAccessToken);
|
||||
NSLog(@"User: %@", user);
|
||||
[objectManager.client setValue:[DBUser currentUser].singleAccessToken forHTTPHeaderField:kAccessTokenHeaderField];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Watch for login/logout events and set the Access Token HTTP Header
|
||||
- (void)setAccessTokenHeaderFromAuthenticationNotification:(NSNotification*)notification {
|
||||
DBUser* user = (DBUser*) [notification object];
|
||||
RKObjectManager* objectManager = [RKObjectManager sharedManager];
|
||||
[objectManager.client setValue:user.singleAccessToken forHTTPHeaderField:kDBAccessTokenHTTPHeaderField];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[window release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
3F255CA112DB70E700AFD2D1 /* DBTopic.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F255C9F12DB70E700AFD2D1 /* DBTopic.m */; };
|
||||
3F255CA812DB711900AFD2D1 /* DBUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F255CA712DB711900AFD2D1 /* DBUser.m */; };
|
||||
3F255CC612DB747C00AFD2D1 /* DBTopicViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F255CC512DB747C00AFD2D1 /* DBTopicViewController.m */; };
|
||||
3F255D1E12DB779B00AFD2D1 /* DBLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F255D1D12DB779B00AFD2D1 /* DBLoginViewController.m */; };
|
||||
3F255D1E12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F255D1D12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.m */; };
|
||||
3F3239E112DBB9C600AB2F6E /* DBPostTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F3239E012DBB9C600AB2F6E /* DBPostTableViewController.m */; };
|
||||
3F3239ED12DBBA8D00AB2F6E /* DBAuthenticatedTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F3239EC12DBBA8D00AB2F6E /* DBAuthenticatedTableViewController.m */; };
|
||||
3F45615B12D7E31100BE25AD /* libRestKitCoreData.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A7A2D3B512D7822D00683D6F /* libRestKitCoreData.a */; };
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
1D6058910D05DD3D006BFB54 /* DiscussionBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DiscussionBoard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1D6058910D05DD3D006BFB54 /* DiscussionBoard-Development.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DiscussionBoard-Development.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
25359D4212E3E0A4008BF33D /* libThree20.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libThree20.a; sourceTree = "<group>"; };
|
||||
25359D4312E3E0A4008BF33D /* libThree20Core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libThree20Core.a; sourceTree = "<group>"; };
|
||||
@@ -435,6 +435,8 @@
|
||||
25359ECF12E51070008BF33D /* DiscussionBoardAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DiscussionBoardAppDelegate.m; path = Code/Other/DiscussionBoardAppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||
25359ED512E512BB008BF33D /* DiscussionBoard_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DiscussionBoard_Prefix.pch; path = Code/Other/DiscussionBoard_Prefix.pch; sourceTree = SOURCE_ROOT; };
|
||||
25359ED612E512BB008BF33D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Code/Other/main.m; sourceTree = SOURCE_ROOT; };
|
||||
25FED6E512E7D60600D94325 /* DiscussionBoard-Info copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "DiscussionBoard-Info copy.plist"; path = "Resources/DiscussionBoard-Info copy.plist"; sourceTree = "<group>"; };
|
||||
25FED7BC12E7D6EC00D94325 /* DiscussionBoard-Info copy 2.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "DiscussionBoard-Info copy 2.plist"; path = "Resources/DiscussionBoard-Info copy 2.plist"; sourceTree = "<group>"; };
|
||||
288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
3F22448612DDFCB30002559D /* UIViewController+RKLoading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+RKLoading.h"; sourceTree = "<group>"; };
|
||||
3F22448712DDFCB30002559D /* UIViewController+RKLoading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+RKLoading.m"; sourceTree = "<group>"; };
|
||||
@@ -452,8 +454,8 @@
|
||||
3F255CA712DB711900AFD2D1 /* DBUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBUser.m; sourceTree = "<group>"; };
|
||||
3F255CC412DB747C00AFD2D1 /* DBTopicViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBTopicViewController.h; sourceTree = "<group>"; };
|
||||
3F255CC512DB747C00AFD2D1 /* DBTopicViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBTopicViewController.m; sourceTree = "<group>"; };
|
||||
3F255D1C12DB779B00AFD2D1 /* DBLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBLoginViewController.h; sourceTree = "<group>"; };
|
||||
3F255D1D12DB779B00AFD2D1 /* DBLoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBLoginViewController.m; sourceTree = "<group>"; };
|
||||
3F255D1C12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBLoginOrSignUpViewController.h; sourceTree = "<group>"; };
|
||||
3F255D1D12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBLoginOrSignUpViewController.m; sourceTree = "<group>"; };
|
||||
3F3239DF12DBB9C600AB2F6E /* DBPostTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBPostTableViewController.h; sourceTree = "<group>"; };
|
||||
3F3239E012DBB9C600AB2F6E /* DBPostTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBPostTableViewController.m; sourceTree = "<group>"; };
|
||||
3F3239EB12DBBA8D00AB2F6E /* DBAuthenticatedTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBAuthenticatedTableViewController.h; sourceTree = "<group>"; };
|
||||
@@ -533,7 +535,7 @@
|
||||
19C28FACFE9D520D11CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1D6058910D05DD3D006BFB54 /* DiscussionBoard.app */,
|
||||
1D6058910D05DD3D006BFB54 /* DiscussionBoard-Development.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -954,6 +956,8 @@
|
||||
A755037512E4CBD4009FC5EC /* PNGs */,
|
||||
8D1107310486CEB800E47090 /* DiscussionBoard-Info.plist */,
|
||||
3F76BBD512D7DA9D001562DC /* DataModel.xcdatamodel */,
|
||||
25FED6E512E7D60600D94325 /* DiscussionBoard-Info copy.plist */,
|
||||
25FED7BC12E7D6EC00D94325 /* DiscussionBoard-Info copy 2.plist */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
@@ -984,8 +988,8 @@
|
||||
3F255C9712DB70E200AFD2D1 /* DBTopicsTableViewController.m */,
|
||||
3F255CC412DB747C00AFD2D1 /* DBTopicViewController.h */,
|
||||
3F255CC512DB747C00AFD2D1 /* DBTopicViewController.m */,
|
||||
3F255D1C12DB779B00AFD2D1 /* DBLoginViewController.h */,
|
||||
3F255D1D12DB779B00AFD2D1 /* DBLoginViewController.m */,
|
||||
3F255D1C12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.h */,
|
||||
3F255D1D12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.m */,
|
||||
3F3239DF12DBB9C600AB2F6E /* DBPostTableViewController.h */,
|
||||
3F3239E012DBB9C600AB2F6E /* DBPostTableViewController.m */,
|
||||
3F3239EB12DBBA8D00AB2F6E /* DBAuthenticatedTableViewController.h */,
|
||||
@@ -1100,7 +1104,7 @@
|
||||
);
|
||||
name = DiscussionBoard;
|
||||
productName = DiscussionBoard;
|
||||
productReference = 1D6058910D05DD3D006BFB54 /* DiscussionBoard.app */;
|
||||
productReference = 1D6058910D05DD3D006BFB54 /* DiscussionBoard-Development.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -1235,7 +1239,7 @@
|
||||
3F255CA112DB70E700AFD2D1 /* DBTopic.m in Sources */,
|
||||
3F255CA812DB711900AFD2D1 /* DBUser.m in Sources */,
|
||||
3F255CC612DB747C00AFD2D1 /* DBTopicViewController.m in Sources */,
|
||||
3F255D1E12DB779B00AFD2D1 /* DBLoginViewController.m in Sources */,
|
||||
3F255D1E12DB779B00AFD2D1 /* DBLoginOrSignUpViewController.m in Sources */,
|
||||
3F3239E112DBB9C600AB2F6E /* DBPostTableViewController.m in Sources */,
|
||||
3F3239ED12DBBA8D00AB2F6E /* DBAuthenticatedTableViewController.m in Sources */,
|
||||
3F22448812DDFCB30002559D /* UIViewController+RKLoading.m in Sources */,
|
||||
@@ -1268,7 +1272,7 @@
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1D6058940D05DD3E006BFB54 /* Debug */ = {
|
||||
1D6058940D05DD3E006BFB54 /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
@@ -1277,7 +1281,10 @@
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Code/Other/DiscussionBoard_Prefix.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DB_ENVIRONMENT=0",
|
||||
"DEBUG=1",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../../../Build,
|
||||
Libraries/three20,
|
||||
@@ -1289,18 +1296,21 @@
|
||||
"\"$(SRCROOT)\"",
|
||||
"\"$(SRCROOT)/Libraries/three20\"",
|
||||
);
|
||||
PRODUCT_NAME = DiscussionBoard;
|
||||
PRODUCT_NAME = "DiscussionBoard-Development";
|
||||
};
|
||||
name = Debug;
|
||||
name = Development;
|
||||
};
|
||||
1D6058950D05DD3E006BFB54 /* Release */ = {
|
||||
1D6058950D05DD3E006BFB54 /* Production */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Code/Other/DiscussionBoard_Prefix.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DB_ENVIRONMENT=2",
|
||||
"DEBUG=1",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../../../Build,
|
||||
Libraries/three20,
|
||||
@@ -1319,9 +1329,9 @@
|
||||
PRODUCT_NAME = DiscussionBoard;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
name = Production;
|
||||
};
|
||||
C01FCF4F08A954540054247B /* Debug */ = {
|
||||
25FED7DA12E7D78E00D94325 /* Staging */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
@@ -1340,9 +1350,58 @@
|
||||
PREBINDING = NO;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
name = Staging;
|
||||
};
|
||||
C01FCF5008A954540054247B /* Release */ = {
|
||||
25FED7DB12E7D78E00D94325 /* Staging */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = Code/Other/DiscussionBoard_Prefix.pch;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DB_ENVIRONMENT=1",
|
||||
"DEBUG=1",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../../../Build,
|
||||
Libraries/three20,
|
||||
);
|
||||
INFOPLIST_FILE = "Resources/DiscussionBoard-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)\"",
|
||||
"\"$(SRCROOT)/Libraries/three20\"",
|
||||
);
|
||||
PRODUCT_NAME = "DiscussionBoard-Staging";
|
||||
};
|
||||
name = Staging;
|
||||
};
|
||||
C01FCF4F08A954540054247B /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../../../Build,
|
||||
Libraries/three20/Build/Products/three20,
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-all_load",
|
||||
"-ObjC",
|
||||
);
|
||||
PREBINDING = NO;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
C01FCF5008A954540054247B /* Production */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
@@ -1358,7 +1417,7 @@
|
||||
PREBINDING = NO;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Release;
|
||||
name = Production;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
@@ -1366,20 +1425,22 @@
|
||||
1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DiscussionBoard" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1D6058940D05DD3E006BFB54 /* Debug */,
|
||||
1D6058950D05DD3E006BFB54 /* Release */,
|
||||
1D6058940D05DD3E006BFB54 /* Development */,
|
||||
25FED7DB12E7D78E00D94325 /* Staging */,
|
||||
1D6058950D05DD3E006BFB54 /* Production */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
defaultConfigurationName = Production;
|
||||
};
|
||||
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DiscussionBoard" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
C01FCF4F08A954540054247B /* Debug */,
|
||||
C01FCF5008A954540054247B /* Release */,
|
||||
C01FCF4F08A954540054247B /* Development */,
|
||||
25FED7DA12E7D78E00D94325 /* Staging */,
|
||||
C01FCF5008A954540054247B /* Production */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
defaultConfigurationName = Production;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.twotoasters.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.twotoasters.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -6,14 +6,14 @@ class SessionsController < ApplicationController
|
||||
@user = @user_session.user
|
||||
render :json => {:username => @user.username, :single_access_token => @user.single_access_token, :id => @user.id, :email => @user.email}
|
||||
else
|
||||
render :json => {:error => "Invalid username or password"}, :status => 401
|
||||
render :json => {:errors => ["Invalid username or password"]}, :status => 401
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
def destroy
|
||||
if current_user
|
||||
current_user.update_attributes!(:single_access_token => nil)
|
||||
end
|
||||
render :json => {}, :status => :ok
|
||||
render :json => {:user => {:single_access_token => nil}}, :status => :ok
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
# Examples:
|
||||
#
|
||||
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
|
||||
# Mayor.create(:name => 'Daley', :city => cities.first)
|
||||
# Mayor.create(:name => 'Daley', :city => cities.first)
|
||||
Reference in New Issue
Block a user