From d37daca17b444510a67cece4bbd5ec62744b753a Mon Sep 17 00:00:00 2001 From: Katsuhisa Abe Date: Thu, 3 Dec 2009 14:51:18 +0900 Subject: [PATCH] New Feature - Relationship with ReadItLater. - Add models NTLNReadItLaterAccount to manage user's ReadItLater account. NTLNReadItLaterClient.m to access ReadItLater API. - Add view NTLNBookmarkActionSheet, which inherits from UIActionSheet, for confirming user to add viewing site into ReadItLater or not. This is diplayed from NTLNBrowserViewController. - Add controller NTLNReadItLaterAccountViewController for controll inputs of user's ReadItLater account information. --- NatsuLion/app/NTLNAppDelegate.h | 1 + NatsuLion/app/NTLNAppDelegate.m | 10 ++ .../NTLNReadItLaterAccountViewController.h | 17 ++ .../NTLNReadItLaterAccountViewController.m | 161 ++++++++++++++++++++ .../tabviews/NTLNSettingViewController.m | 19 ++- .../tweetview/NTLNBrowserViewController.h | 6 +- .../tweetview/NTLNBrowserViewController.m | 84 ++++++++++- NatsuLion/models/account/NTLNReadItLaterAccount.h | 32 ++++ NatsuLion/models/account/NTLNReadItLaterAccount.m | 83 ++++++++++ .../models/configuration/NTLNConfigurationKeys.h | 2 + NatsuLion/models/network/NTLNReadItLaterClient.h | 30 ++++ NatsuLion/models/network/NTLNReadItLaterClient.m | 61 ++++++++ .../views/actionsheet/NTLNBookmarkActionSheet.h | 19 +++ .../views/actionsheet/NTLNBookmarkActionSheet.m | 33 ++++ ntlniph.xcodeproj/project.pbxproj | 37 +++++- 15 files changed, 585 insertions(+), 10 deletions(-) create mode 100644 NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.h create mode 100644 NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.m create mode 100644 NatsuLion/models/account/NTLNReadItLaterAccount.h create mode 100644 NatsuLion/models/account/NTLNReadItLaterAccount.m create mode 100644 NatsuLion/models/network/NTLNReadItLaterClient.h create mode 100644 NatsuLion/models/network/NTLNReadItLaterClient.m create mode 100644 NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.h create mode 100644 NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.m diff --git a/NatsuLion/app/NTLNAppDelegate.h b/NatsuLion/app/NTLNAppDelegate.h index eb0a716..2cdc050 100644 --- a/NatsuLion/app/NTLNAppDelegate.h +++ b/NatsuLion/app/NTLNAppDelegate.h @@ -34,6 +34,7 @@ - (BOOL)isInMoreTab:(UIViewController*)vc; - (void)presentTwitterAccountSettingView; +- (void)presentReadItLaterAccountSettingView; - (void)resetAllTimelinesAndCache; @end diff --git a/NatsuLion/app/NTLNAppDelegate.m b/NatsuLion/app/NTLNAppDelegate.m index bbc14ab..ff6389f 100644 --- a/NatsuLion/app/NTLNAppDelegate.m +++ b/NatsuLion/app/NTLNAppDelegate.m @@ -16,6 +16,7 @@ #import "OAToken.h" #import "NTLNConfigurationKeys.h" #import "NTLNTwitterAccountViewController.h" +#import "NTLNReadItLaterAccountViewController.h" @implementation NTLNAppDelegate @@ -237,6 +238,15 @@ [tabBarController presentModalViewController:nc animated:YES]; } +- (void)presentReadItLaterAccountSettingView { + UITableViewController *vc = [[[NTLNReadItLaterAccountViewController alloc] + initWithStyle:UITableViewStyleGrouped] autorelease]; + UINavigationController *nc = [[[UINavigationController alloc] + initWithRootViewController:vc] autorelease]; + [nc.navigationBar setBarStyle:UIBarStyleBlackOpaque]; + [tabBarController presentModalViewController:nc animated:YES]; +} + - (BOOL)isInMoreTab:(UIViewController*)vc { int cnt = 0; for (UINavigationController *v in tabBarController.viewControllers) { diff --git a/NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.h b/NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.h new file mode 100644 index 0000000..b99951d --- /dev/null +++ b/NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.h @@ -0,0 +1,17 @@ +// +// NTLNReadItLaterAccountViewController.h +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/28. +// Copyright 2009 Katsuhisa Abe. All rights reserved. +// + +#import +#import "UICTableViewController.h" +#import "NTLNReadItLaterClient.h" + +@interface NTLNReadItLaterAccountViewController : UICTableViewController { + NSString *usernameOriginal; +} + +@end diff --git a/NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.m b/NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.m new file mode 100644 index 0000000..67aab14 --- /dev/null +++ b/NatsuLion/controllers/settings/NTLNReadItLaterAccountViewController.m @@ -0,0 +1,161 @@ +// +// NTLNReadItLaterAccountViewController.m +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/28. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "NTLNReadItLaterAccountViewController.h" +#import "NTLNConfigurationKeys.h" +#import "NTLNReadItLaterAccount.h" +#import "NTLNAlert.h" +#import "UICTableViewCellTextInput.h" + +@interface NTLNReadItLaterAccountViewController(Private) +- (void)setupPrototypes; +- (void)setupNavButtons; +- (void)resignFirstResponderForCell:(NSIndexPath*)indexPath; +- (void)becomeFirstResponderForCell:(NSIndexPath*)indexPath; +- (void)doneButtonPushed:(id)sender; +- (void)cancelButtonPushed:(id)sender; + +@end + + +@implementation NTLNReadItLaterAccountViewController + +- (void)setupPrototypes { + if (groups != nil) return; + + UICPrototypeTableCellTextInput *c1 = [UICPrototypeTableCell cellForTextInput:@"Username" + withPlaceholder:@"required" + withUserDefaultsKey:NTLN_PREFERENCE_READITLATER_USERID]; + + UICPrototypeTableCellTextInput *c2 = [UICPrototypeTableCell cellForTextInput:@"Passowrd" + withPlaceholder:@"required" + withUserDefaultsKey:NTLN_PREFERENCE_READITLATER_PASSWORD]; + c2.secure = YES; + + NSArray *g1 = [NSArray arrayWithObjects:c1, c2, nil]; + + groups = [[NSArray arrayWithObjects: + [UICPrototypeTableGroup groupWithCells:g1 withTitle:nil], + nil] retain]; +} + +- (void)setupNavButtons { + UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" + style:UIBarButtonItemStylePlain + target:self + action:@selector(doneButtonPushed:)]; + [[self navigationItem] setRightBarButtonItem:doneButton]; +} + +- (id)initWithStyle:(UITableViewStyle)style { + if (self = [super initWithStyle:style]) { + [self.navigationItem setTitle:@"Read It Later Account"]; + } + return self; +} + + +// Implement loadView to create a view hierarchy programmatically, without using a nib. +- (void)loadView { + [self setupPrototypes]; + [self setupNavButtons]; + + [super loadView]; +} + +- (void)viewWillAppear:(BOOL)animated { + usernameOriginal = [[[NTLNReadItLaterAccount sharedInstance] userName] retain]; + [self.tableView reloadData]; + [self becomeFirstResponderForCell:[NSIndexPath indexPathForRow:0 inSection:0]]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [self resignFirstResponderForCell:[NSIndexPath indexPathForRow:0 inSection:0]]; + [self resignFirstResponderForCell:[NSIndexPath indexPathForRow:1 inSection:0]]; + + [[NTLNReadItLaterAccount sharedInstance] update]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; +} + + +- (void)resignFirstResponderForCell:(NSIndexPath*)indexPath { + UICTableViewCellTextInput *cell = (UICTableViewCellTextInput*)[self.tableView cellForRowAtIndexPath:indexPath]; + [cell.textField resignFirstResponder]; +} + +- (void)becomeFirstResponderForCell:(NSIndexPath*)indexPath { + UICTableViewCellTextInput *cell = (UICTableViewCellTextInput*)[self.tableView cellForRowAtIndexPath:indexPath]; + [cell.textField becomeFirstResponder]; +} + +- (void)doneButtonPushed:(id)sender { + [[NTLNReadItLaterAccount sharedInstance] update]; + [[NTLNReadItLaterClient sharedInstance] setDelegate:self]; + [[NTLNReadItLaterClient sharedInstance] verifyAccount]; +} + +- (void)cancelButtonPushed:(id)sender { + [self dismissModalViewControllerAnimated:YES]; +} + +- (void)dealloc { + [usernameOriginal release]; + [super dealloc]; +} + +#pragma mark NTLNReadItLaterClientDelegate +- (void)readItLaterClientSucceeded:(NTLNReadItLaterClient*)sender { + if (sender.statusCode == 200) { + // !!! this Alert Dialog should be displayed or not. + // [[NTLNAlert instance] alert:@"Read It Later: Authorization Succeed" + // withMessage:[NSString stringWithString:@"Username and password are correct."]]; + } else { + if (sender.statusCode != 304) { + switch (sender.statusCode) { + case 400: + // This error code must not be showed, since root cause is this application. + // 400 - Invalid request, please make sure you follow the documentation for proper syntax + [[NTLNAlert instance] alert:@"Read It Later: Invalid request" + withMessage:[NSString stringWithFormat:@"Please send it as a bug to the developers."]]; + + break; + case 401: + // 401 - Username and/or password is incorrect + [[NTLNAlert instance] alert:@"Read It Later: Authorization Failed" + withMessage:[NSString stringWithString:@"Username and/or password is incorrect."]]; + break; + case 403: + // 403 - Rate limit exceeded, please wait a little bit before resubmitting + [[NTLNAlert instance] alert:@"Read It Later: Rate Limit Exceeded" + withMessage:[NSString stringWithString:@"please wait a little bit before resubmitting."]]; + break; + case 503: + // # 503 - Read It Later's sync server is down for scheduled maintenance. + [[NTLNAlert instance] alert:@"Read It Later: Server Down" + withMessage:[NSString stringWithString:@"Read It Later's sync server is down for scheduled maintenance."]]; + break; + default: + [[NTLNAlert instance] alert:@"Read It Later: Failed" + withMessage:[NSString stringWithFormat:@"Read It Later responded %d.", sender.statusCode]]; + } + } + } + [self dismissModalViewControllerAnimated:YES]; +} + +- (void)readItLaterClientFailed:(NTLNReadItLaterClient *)sender error:(NSError *)error { + if (error) { + [[NTLNAlert instance] alert:@"Network error" withMessage:[error localizedDescription]]; + } + [self dismissModalViewControllerAnimated:YES]; +} + +@end diff --git a/NatsuLion/controllers/tabviews/NTLNSettingViewController.m b/NatsuLion/controllers/tabviews/NTLNSettingViewController.m index 698d6ab..b04b197 100644 --- a/NatsuLion/controllers/tabviews/NTLNSettingViewController.m +++ b/NatsuLion/controllers/tabviews/NTLNSettingViewController.m @@ -19,7 +19,11 @@ - (void)setupPrototypes { if (groups != nil) return; - NSArray *g1 = [NSArray arrayWithObjects:[UICPrototypeTableCell cellForTitle:@"Twitter Account"], nil]; + NSArray *g1 = [NSArray arrayWithObjects: + [UICPrototypeTableCell cellForTitle:@"Twitter Account"], + [UICPrototypeTableCell cellForTitle:@"Read It Later Account"], + nil]; + NSArray *g2 = [NSArray arrayWithObjects: [UICPrototypeTableCell cellForSelect:@"Auto refresh" withSelectTitles:[NSArray arrayWithObjects: @@ -120,15 +124,18 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - // for "Twitter account" cell - if ([indexPath section] == 0 && [indexPath row] == 0) { + // for "Twitter account" or "Read It Later account " cell + if ([indexPath section] == 0) { + if ([indexPath row] == 0) { // "Twitter account" #ifdef ENABLE_OAUTH - [[NTLNOAuthConsumer sharedInstance] requestToken:self.tabBarController]; + [[NTLNOAuthConsumer sharedInstance] requestToken:self.tabBarController]; #else - [(NTLNAppDelegate*)[UIApplication sharedApplication].delegate presentTwitterAccountSettingView]; + [(NTLNAppDelegate*)[UIApplication sharedApplication].delegate presentTwitterAccountSettingView]; #endif + } else if ([indexPath row] == 1) { // "ReadItLater account" + [(NTLNAppDelegate*)[UIApplication sharedApplication].delegate presentReadItLaterAccountSettingView]; + } } - // for "Footer" cell if ([indexPath section] == 3 && [indexPath row] == 0) { UITableViewController *vc = [[[NTLNFooterSettingViewController alloc] diff --git a/NatsuLion/controllers/tweetview/NTLNBrowserViewController.h b/NatsuLion/controllers/tweetview/NTLNBrowserViewController.h index 47db3c6..b90d219 100644 --- a/NatsuLion/controllers/tweetview/NTLNBrowserViewController.h +++ b/NatsuLion/controllers/tweetview/NTLNBrowserViewController.h @@ -1,10 +1,13 @@ #import #import "NTLNAccelerometerSensor.h" #import "NTLNWebView.h" +#import "NTLNBookmarkActionSheet.h" +#import "NTLNReadItLaterClient.h" -@interface NTLNBrowserViewController : UIViewController { +@interface NTLNBrowserViewController : UIViewController { NSString *url; NTLNWebView *webView; + NTLNBookmarkActionSheet *actionSheet; UIToolbar *toobarTop; UIToolbar *toobarBottom; @@ -14,6 +17,7 @@ UIBarButtonItem *reloadButton; UIBarButtonItem *prevButton; UIBarButtonItem *nextButton; + UIBarButtonItem *addButton; NSMutableArray *toobarTopItems; } diff --git a/NatsuLion/controllers/tweetview/NTLNBrowserViewController.m b/NatsuLion/controllers/tweetview/NTLNBrowserViewController.m index e7d265a..0bfcfc5 100644 --- a/NatsuLion/controllers/tweetview/NTLNBrowserViewController.m +++ b/NatsuLion/controllers/tweetview/NTLNBrowserViewController.m @@ -4,10 +4,13 @@ #import "NTLNWebView.h" #import "NTLNTwitterPost.h" #import "NTLNTweetPostViewController.h" +#import "NTLNBookmarkActionSheet.h" +#import "NTLNReadItLaterClient.h" @interface NTLNBrowserViewController(Private) - (void)setupToolbarTop; - (void)setupToolbarBottom; +- (void)setupActionSheet; - (void)updatePrevNextButton; - (void)updateReloadButton; @@ -17,6 +20,7 @@ - (void)nextButtonPushed:(id)sender; - (void)safariButtonPushed:(id)sender; - (void)tweetURLButtonPushed:(id)sender; +- (void)addButtonPushed:(id)sender; @end @@ -37,6 +41,8 @@ webView.frame = CGRectMake(0, 44, 320, 480-44-44); [self.view addSubview:webView]; + actionSheet = [NTLNBookmarkActionSheet sharedInstance]; + toobarBottom = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 480-44-20, 320, 44)]; toobarBottom.barStyle = UIBarStyleBlackOpaque; [self setupToolbarBottom]; @@ -49,10 +55,12 @@ - (void)viewWillDisappear:(BOOL)animated { webView.delegate = nil; + actionSheet.delegate = nil; } - (void)viewWillAppear:(BOOL)animated { webView.delegate = self; + actionSheet.delegate = self; [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]]; } @@ -67,6 +75,7 @@ [title release]; [prevButton release]; [nextButton release]; + [addButton release]; [toobarTopItems release]; @@ -107,6 +116,67 @@ return NO; } +#pragma mark UIActionSheetDelegate + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { + // use [sheet buttonTitleAtIndex:index] ? + switch (buttonIndex) { + case 0: + [[NTLNReadItLaterClient sharedInstance] setDelegate:self]; + [[NTLNReadItLaterClient sharedInstance] addReadItLaterURL:webView.request.URL.absoluteString]; + break; + default: + // NSLog(@"Cancel"); + break; + } +} + +#pragma mark NTLNReadItLaterClientDelegate +- (void)readItLaterClientSucceeded:(NTLNReadItLaterClient*)sender { + if (sender.statusCode == 200) { + [[NTLNAlert instance] alert:@"Read It Later: Successfully" + withMessage:[NSString stringWithString:@"Added this site into your Read It Later."]]; + } else { + if (sender.statusCode != 304) { + switch (sender.statusCode) { + case 400: + // This error code must not be showed, since root cause is this application. + // 400 - Invalid request, please make sure you follow the documentation for proper syntax + [[NTLNAlert instance] alert:@"Read It Later: Invalid request" + withMessage:[NSString stringWithFormat:@"Please send it as a bug to the developers."]]; + + break; + case 401: + // 401 - Username and/or password is incorrect + [[NTLNAlert instance] alert:@"Read It Later: Authorization Failed" + withMessage:[NSString stringWithString:@"Username and/or password is incorrect."]]; + break; + case 403: + // 403 - Rate limit exceeded, please wait a little bit before resubmitting + [[NTLNAlert instance] alert:@"Read It Later: Rate Limit Exceeded" + withMessage:[NSString stringWithString:@"please wait a little bit before resubmitting."]]; + break; + case 503: + // # 503 - Read It Later's sync server is down for scheduled maintenance. + [[NTLNAlert instance] alert:@"Read It Later: Server Down" + withMessage:[NSString stringWithString:@"Read It Later's sync server is down for scheduled maintenance."]]; + break; + default: + [[NTLNAlert instance] alert:@"Read It Later: Failed" + withMessage:[NSString stringWithFormat:@"Read It Later responded %d.", sender.statusCode]]; + } + } + } + +} + +- (void)readItLaterClientFailed:(NTLNReadItLaterClient*)sender error:(NSError *)error { + if (error) { + [[NTLNAlert instance] alert:@"Network error" withMessage:[error localizedDescription]]; + } +} + + #pragma mark Private - (void)setupToolbarTop { @@ -145,6 +215,10 @@ action:@selector(nextButtonPushed:)]; nextButton.enabled = NO; + addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd + target:self + action:@selector(addButtonPushed:)]; + UIBarButtonItem *safariButton = [[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"browser_icons_05.png"] style:UIBarButtonItemStylePlain target:self @@ -157,7 +231,7 @@ UIBarButtonItem *spacer = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease]; - [toobarBottom setItems:[NSArray arrayWithObjects:prevButton, spacer, nextButton, spacer, tweetURLButton, spacer, safariButton, nil]]; + [toobarBottom setItems:[NSArray arrayWithObjects:prevButton, spacer, nextButton, spacer, addButton, spacer, tweetURLButton, spacer, safariButton, nil]]; } - (void)reloadButtonPushed:(id)sender { @@ -191,6 +265,14 @@ [NTLNTweetPostViewController present:self]; } +- (void)addButtonPushed:(id)sender { + NSString *scheme = webView.request.URL.scheme; + if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) { + [actionSheet showInView:self.view]; + } +} + + - (void)updatePrevNextButton { prevButton.enabled = [webView canGoBack]; nextButton.enabled = [webView canGoForward]; diff --git a/NatsuLion/models/account/NTLNReadItLaterAccount.h b/NatsuLion/models/account/NTLNReadItLaterAccount.h new file mode 100644 index 0000000..4723ca1 --- /dev/null +++ b/NatsuLion/models/account/NTLNReadItLaterAccount.h @@ -0,0 +1,32 @@ +// +// NTLNReadItLaterAccount.h +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/29. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import "NTLNReadItLaterClient.h" + + +@interface NTLNReadItLaterAccount : NSObject { + NSString *userName; + NSString *password; +} + ++ (NTLNReadItLaterAccount*)sharedInstance; + +- (BOOL)valid; + +- (void)update; + +- (void)setUserName:(NSString*)userName; +- (NSString*)userName; + +- (void)setPassword:(NSString*)password; +- (NSString*)password; + +- (NSString*)apikey; + +@end diff --git a/NatsuLion/models/account/NTLNReadItLaterAccount.m b/NatsuLion/models/account/NTLNReadItLaterAccount.m new file mode 100644 index 0000000..bcfcd02 --- /dev/null +++ b/NatsuLion/models/account/NTLNReadItLaterAccount.m @@ -0,0 +1,83 @@ +// +// NTLNReadItLaterAccount.m +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/29. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "NTLNReadItLaterAccount.h" +#import "NTLNConfigurationKeys.h" +#import "GTMObjectSingleton.h" + +@implementation NTLNReadItLaterAccount + +// @synthesize delegate; + +GTMOBJECT_SINGLETON_BOILERPLATE(NTLNReadItLaterAccount, sharedInstance) + +- (id)init { + if (self = [super init]) { + // !!! check how to use OAToken for ReadItLater. + // userToken = [[OAToken alloc] initWithUserDefaultsUsingServiceProviderName:NTLN_OAUTH_PROVIDER + // prefix:NTLN_OAUTH_PREFIX]; + [self update]; + } + return self; +} + +- (void)update { + [userName release]; + [password release]; + + userName = [[[NSUserDefaults standardUserDefaults] stringForKey:NTLN_PREFERENCE_READITLATER_USERID] retain]; + password = [[[NSUserDefaults standardUserDefaults] stringForKey:NTLN_PREFERENCE_READITLATER_PASSWORD] retain]; + +} + +- (void)dealloc { + [userName release]; + [password release]; + [super dealloc]; +} + +- (void)setUserName:(NSString*)un { + [userName release]; + userName = [un retain]; + [[NSUserDefaults standardUserDefaults] setObject:userName forKey:NTLN_PREFERENCE_READITLATER_USERID]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (NSString*)userName { + return userName; +} + +- (void)setPassword:(NSString *)pw { + [password release]; + password = [pw retain]; + [[NSUserDefaults standardUserDefaults] setObject:password forKey:NTLN_PREFERENCE_READITLATER_PASSWORD]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (NSString*)password { + return password; +} + +- (NSString*)apikey { + return @""; // TODO should contact on ReadItLater to access this APIKey privately. +} + +- (BOOL)valid { +#ifdef ENABLE_OAUTH + /* + * !!! check how to use OAuth for ReadItLater + return userName.length > 0 && + userToken && + userToken.key.length > 0 && + userToken.secret.length > 0; + */ +#endif + return userName.length > 0 && password.length > 0; +} + +@end diff --git a/NatsuLion/models/configuration/NTLNConfigurationKeys.h b/NatsuLion/models/configuration/NTLNConfigurationKeys.h index f2f7753..f2f1310 100644 --- a/NatsuLion/models/configuration/NTLNConfigurationKeys.h +++ b/NatsuLion/models/configuration/NTLNConfigurationKeys.h @@ -1,6 +1,8 @@ #define NTLN_PREFERENCE_USERID @"userId" #define NTLN_PREFERENCE_PASSWORD @"password" #define NTLN_PREFERENCE_TWITTER_USERID @"twitter_user_id" +#define NTLN_PREFERENCE_READITLATER_USERID @"readitlater_user_id" +#define NTLN_PREFERENCE_READITLATER_PASSWORD @"readitlater_password" #define NTLN_PREFERENCE_REFRESH_INTERVAL @"refreshInterval" #define NTLN_PREFERENCE_USE_SAFARI @"useSafari" diff --git a/NatsuLion/models/network/NTLNReadItLaterClient.h b/NatsuLion/models/network/NTLNReadItLaterClient.h new file mode 100644 index 0000000..798024a --- /dev/null +++ b/NatsuLion/models/network/NTLNReadItLaterClient.h @@ -0,0 +1,30 @@ +// +// NTLNReadItLaterClient.h +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/30. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import "NTLNHttpClient.h" + +@class NTLNReadItLaterClient; + +@protocol NTLNReadItLaterClientDelegate +- (void)readItLaterClientSucceeded:(NTLNReadItLaterClient*)sender; +- (void)readItLaterClientFailed:(NTLNReadItLaterClient*)sender error:(NSError *)error; +@end + +@interface NTLNReadItLaterClient : NTLNHttpClient { + id delegate; +} + ++ (NTLNReadItLaterClient*)sharedInstance; + +- (void)addReadItLaterURL:(NSString*)url; +- (void)verifyAccount; + +@property (readwrite, assign) id delegate; + +@end diff --git a/NatsuLion/models/network/NTLNReadItLaterClient.m b/NatsuLion/models/network/NTLNReadItLaterClient.m new file mode 100644 index 0000000..33fc89a --- /dev/null +++ b/NatsuLion/models/network/NTLNReadItLaterClient.m @@ -0,0 +1,61 @@ +// +// NTLNReadItLaterClient.m +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/30. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "NTLNReadItLaterClient.h" +#import "NTLNReadItLaterAccount.h" +#import "NTLNAlert.h" +#import "GTMObjectSingleton.h" + +@implementation NTLNReadItLaterClient + +@synthesize delegate; + +GTMOBJECT_SINGLETON_BOILERPLATE(NTLNReadItLaterClient, sharedInstance) + +// private methods ++ (NSString*)URLForReadItLaterWithAccount { + return @"https://readitlaterlist.com/v2/"; +} + +- (void)dealloc { + [super dealloc]; +} + +- (void)addReadItLaterURL:(NSString *)url { + NSString *username = [[NTLNReadItLaterAccount sharedInstance] userName]; + NSString *password = [[NTLNReadItLaterAccount sharedInstance] password]; + NSString *apikey = [[NTLNReadItLaterAccount sharedInstance] apikey]; + + NSString *postUrl = [NSString stringWithFormat:@"%@add?username=%@&password=%@&apikey=%@&url=%@", + [NTLNReadItLaterClient URLForReadItLaterWithAccount], + username, password, apikey, url]; + [self requestPOST:postUrl body:nil]; + +} + +- (void)verifyAccount { + NSString *username = [[NTLNReadItLaterAccount sharedInstance] userName]; + NSString *password = [[NTLNReadItLaterAccount sharedInstance] password]; + NSString *apikey = [[NTLNReadItLaterAccount sharedInstance] apikey]; + + NSString *verifyUrl = [NSString stringWithFormat:@"%@auth?username=%@&password=%@&apikey=%@", + [NTLNReadItLaterClient URLForReadItLaterWithAccount], + username, password, apikey]; + [self requestPOST:verifyUrl body:nil]; +} + +// These functions are defined by NTLNHttpClient, but these must be implemented at sub-class. +- (void)requestSucceeded { + [delegate readItLaterClientSucceeded:self]; +} + +- (void)requestFailed:(NSError*)error { + [delegate readItLaterClientFailed:self error:error]; +} + +@end diff --git a/NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.h b/NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.h new file mode 100644 index 0000000..eca3a24 --- /dev/null +++ b/NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.h @@ -0,0 +1,19 @@ +// +// NTLNBookmarkActionSheet.h +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/30. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +//#import +#import + + +@interface NTLNBookmarkActionSheet : UIActionSheet { + +} + ++ (NTLNBookmarkActionSheet*)sharedInstance; + +@end diff --git a/NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.m b/NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.m new file mode 100644 index 0000000..1668b72 --- /dev/null +++ b/NatsuLion/views/actionsheet/NTLNBookmarkActionSheet.m @@ -0,0 +1,33 @@ +// +// NTLNBookmarkActionSheet.m +// ntlniph +// +// Created by Katsuhisa ABE/阿部 勝久 on 09/11/30. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "NTLNBookmarkActionSheet.h" +#import "GTMObjectSingleton.h" + + +@implementation NTLNBookmarkActionSheet + +GTMOBJECT_SINGLETON_BOILERPLATE(NTLNBookmarkActionSheet, sharedInstance) + +- (id)init { + if (self = [super initWithFrame:[[UIScreen mainScreen] applicationFrame]]) { + self.title = @""; + self.delegate = nil; + [self addButtonWithTitle:@"Read It Later"]; + [self addButtonWithTitle:@"Cancel"]; + self.cancelButtonIndex = 1; + self.actionSheetStyle = UIActionSheetStyleDefault; + } + return self; +} + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/ntlniph.xcodeproj/project.pbxproj b/ntlniph.xcodeproj/project.pbxproj index 5eed2ff..cbda795 100755 --- a/ntlniph.xcodeproj/project.pbxproj +++ b/ntlniph.xcodeproj/project.pbxproj @@ -8,6 +8,10 @@ /* Begin PBXBuildFile section */ 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 372195A610C15D780062C3B8 /* NTLNReadItLaterAccountViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 372195A510C15D780062C3B8 /* NTLNReadItLaterAccountViewController.m */; }; + 374A395E10C347F400153136 /* NTLNBookmarkActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 374A395D10C347F400153136 /* NTLNBookmarkActionSheet.m */; }; + 374A3A3110C36FEB00153136 /* NTLNReadItLaterClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 374A3A3010C36FEB00153136 /* NTLNReadItLaterClient.m */; }; + 3756EA8B10C2011C002A4D85 /* NTLNReadItLaterAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 3756EA8A10C2011C002A4D85 /* NTLNReadItLaterAccount.m */; }; 8D1EF37B0FA6C46200BD452F /* libxml2.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D1EF37A0FA6C46200BD452F /* libxml2.2.dylib */; }; 8D3576F30E65D90E00A22D11 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D3576F20E65D90E00A22D11 /* Default.png */; }; 8D3C40150F8FC26300E69E26 /* more_button_normal.png in Resources */ = {isa = PBXBuildFile; fileRef = 8D3C40130F8FC26300E69E26 /* more_button_normal.png */; }; @@ -177,6 +181,14 @@ 1D6058910D05DD3D006BFB54 /* ntlniph.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ntlniph.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ../../main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* ntlniph_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ntlniph_Prefix.pch; path = ../../ntlniph_Prefix.pch; sourceTree = ""; }; + 372195A410C15D780062C3B8 /* NTLNReadItLaterAccountViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NTLNReadItLaterAccountViewController.h; sourceTree = ""; }; + 372195A510C15D780062C3B8 /* NTLNReadItLaterAccountViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NTLNReadItLaterAccountViewController.m; sourceTree = ""; }; + 374A395C10C347F400153136 /* NTLNBookmarkActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NTLNBookmarkActionSheet.h; sourceTree = ""; }; + 374A395D10C347F400153136 /* NTLNBookmarkActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NTLNBookmarkActionSheet.m; sourceTree = ""; }; + 374A3A2F10C36FEB00153136 /* NTLNReadItLaterClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NTLNReadItLaterClient.h; sourceTree = ""; }; + 374A3A3010C36FEB00153136 /* NTLNReadItLaterClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NTLNReadItLaterClient.m; sourceTree = ""; }; + 3756EA8910C2011C002A4D85 /* NTLNReadItLaterAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NTLNReadItLaterAccount.h; sourceTree = ""; }; + 3756EA8A10C2011C002A4D85 /* NTLNReadItLaterAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NTLNReadItLaterAccount.m; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8D1EF37A0FA6C46200BD452F /* libxml2.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.2.dylib; path = usr/lib/libxml2.2.dylib; sourceTree = SDKROOT; }; 8D3576F20E65D90E00A22D11 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = resources/Default.png; sourceTree = ""; }; @@ -502,6 +514,15 @@ name = Frameworks; sourceTree = ""; }; + 3756EB2010C2A338002A4D85 /* actionsheet */ = { + isa = PBXGroup; + children = ( + 374A395C10C347F400153136 /* NTLNBookmarkActionSheet.h */, + 374A395D10C347F400153136 /* NTLNBookmarkActionSheet.m */, + ); + path = actionsheet; + sourceTree = ""; + }; 8D3ECB8E0F8929FA0090DCB1 /* backgrounds */ = { isa = PBXGroup; children = ( @@ -645,7 +666,6 @@ F1474EF30FD3F457007D9F4C /* controllers */ = { isa = PBXGroup; children = ( - F1474F0D0FD3F457007D9F4C /* timeline */, F1474EFE0FD3F457007D9F4C /* tabviews */, F1474F180FD3F457007D9F4C /* tweetview */, F1474EF40FD3F457007D9F4C /* post */, @@ -673,6 +693,8 @@ F1474EFB0FD3F457007D9F4C /* NTLNFooterSettingViewController.m */, F1474EFC0FD3F457007D9F4C /* NTLNTwitterAccountViewController.h */, F1474EFD0FD3F457007D9F4C /* NTLNTwitterAccountViewController.m */, + 372195A410C15D780062C3B8 /* NTLNReadItLaterAccountViewController.h */, + 372195A510C15D780062C3B8 /* NTLNReadItLaterAccountViewController.m */, ); path = settings; sourceTree = ""; @@ -712,7 +734,8 @@ F1474F150FD3F457007D9F4C /* NTLNTimelineViewControllerTableView.m */, F1474F160FD3F457007D9F4C /* NTLNTimelineViewControllerTimeline.m */, ); - path = timeline; + name = timeline; + path = ../controllers/timeline; sourceTree = ""; }; F1474F180FD3F457007D9F4C /* tweetview */ = { @@ -761,6 +784,8 @@ children = ( F1474F280FD3F457007D9F4C /* NTLNAccount.h */, F1474F290FD3F457007D9F4C /* NTLNAccount.m */, + 3756EA8910C2011C002A4D85 /* NTLNReadItLaterAccount.h */, + 3756EA8A10C2011C002A4D85 /* NTLNReadItLaterAccount.m */, ); path = account; sourceTree = ""; @@ -792,6 +817,8 @@ F1474F3A0FD3F457007D9F4C /* NTLNTwitterClient.m */, F1474F3F0FD3F457007D9F4C /* NTLNTwitterUserClient.h */, F1474F400FD3F457007D9F4C /* NTLNTwitterUserClient.m */, + 374A3A2F10C36FEB00153136 /* NTLNReadItLaterClient.h */, + 374A3A3010C36FEB00153136 /* NTLNReadItLaterClient.m */, ); path = network; sourceTree = ""; @@ -875,7 +902,9 @@ F1474F6B0FD3F457007D9F4C /* post */, F1474F800FD3F457007D9F4C /* user */, F1474F850FD3F457007D9F4C /* utlis */, + F1474F0D0FD3F457007D9F4C /* timeline */, F1474F880FD3F457007D9F4C /* web */, + 3756EB2010C2A338002A4D85 /* actionsheet */, ); path = views; sourceTree = ""; @@ -1249,6 +1278,10 @@ F1474FEE0FD3F486007D9F4C /* UICTableViewCellTextInput.m in Sources */, F1474FEF0FD3F486007D9F4C /* UICTableViewController.m in Sources */, F1474FF00FD3F486007D9F4C /* UICTableViewControllerSelect.m in Sources */, + 372195A610C15D780062C3B8 /* NTLNReadItLaterAccountViewController.m in Sources */, + 3756EA8B10C2011C002A4D85 /* NTLNReadItLaterAccount.m in Sources */, + 374A395E10C347F400153136 /* NTLNBookmarkActionSheet.m in Sources */, + 374A3A3110C36FEB00153136 /* NTLNReadItLaterClient.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- 1.6.5.2