diff --git a/.gitmodules b/.gitmodules index 820e82690..8e5799a78 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "Submodules/evernote-ios-sdk"] path = Submodules/evernote-ios-sdk url = https://github.com/evernote/evernote-sdk-ios.git +[submodule "Submodules/sinaweibo-ios-sdk"] + path = Submodules/sinaweibo-ios-sdk + url = https://github.com/mobileresearch/weibo_ios_sdk_sso-oauth.git diff --git a/Classes/Example/ExampleShareText.m b/Classes/Example/ExampleShareText.m index 6ebe3d4c6..5f737e3e3 100644 --- a/Classes/Example/ExampleShareText.m +++ b/Classes/Example/ExampleShareText.m @@ -59,7 +59,7 @@ - (void)loadView self.textView = [[[UITextView alloc] initWithFrame:CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height)] autorelease]; [self.view addSubview:textView]; - textView.text = @"This is a chunk of text. If you highlight it, you'll be able to share the selection. If you tap the share button below, it will share all of it."; + textView.text = SHKLocalizedString(@"This is a chunk of text. If you highlight it, you'll be able to share the selection. If you tap the share button below, it will share all of it."); textView.editable = NO; } diff --git a/Classes/Example/ShareKitAppDelegate.m b/Classes/Example/ShareKitAppDelegate.m index 5e639d68d..18f285493 100644 --- a/Classes/Example/ShareKitAppDelegate.m +++ b/Classes/Example/ShareKitAppDelegate.m @@ -11,6 +11,9 @@ #import "SHKReadItLater.h" #import "SHKFacebook.h" +#import "SHKSinaWeibo.h" +#import "SHKTencentWeixin.h" + #import "SHKConfiguration.h" #import "ShareKitDemoConfigurator.h" @@ -23,7 +26,8 @@ @implementation ShareKitAppDelegate #pragma mark - #pragma mark Application lifecycle -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ // Override point for customization after app launch //Here you load ShareKit submodule with app specific configuration @@ -38,6 +42,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [navigationController setToolbarHidden:NO]; [self performSelector:@selector(testOffline) withObject:nil afterDelay:0.5]; + + // Register Tencent Weixin App + [SHKTencentWeixin registerApp]; return YES; } @@ -54,10 +61,15 @@ - (void)applicationWillTerminate:(UIApplication *)application - (BOOL)handleOpenURL:(NSURL*)url { - NSString* scheme = [url scheme]; - if ([scheme hasPrefix:[NSString stringWithFormat:@"fb%@", SHKCONFIG(facebookAppId)]]) - return [SHKFacebook handleOpenURL:url]; - return YES; + NSString* scheme = [url scheme]; + if ([scheme hasPrefix:[NSString stringWithFormat:@"fb%@", SHKCONFIG(facebookAppId)]]) + return [SHKFacebook handleOpenURL:url]; + else if ([scheme hasPrefix:[NSString stringWithFormat:@"sinaweibosso.%@", SHKCONFIG(sinaWeiboConsumerKey)]]) + return [SHKSinaWeibo handleOpenURL:url]; + else if ([scheme hasPrefix:[NSString stringWithFormat:@"%@", SHKCONFIG(tencentWeixinAppId)]]) + return [SHKTencentWeixin handleOpenURL:url]; + + return YES; } - (BOOL)application:(UIApplication *)application @@ -65,19 +77,20 @@ - (BOOL)application:(UIApplication *)application sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - return [self handleOpenURL:url]; + return [self handleOpenURL:url]; } - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { - return [self handleOpenURL:url]; + return [self handleOpenURL:url]; } #pragma mark - #pragma mark Memory management -- (void)dealloc { +- (void)dealloc +{ [navigationController release]; [window release]; [super dealloc]; diff --git a/Classes/Example/ShareKitDemoConfigurator.m b/Classes/Example/ShareKitDemoConfigurator.m index 35632bc84..59cbb5e2c 100644 --- a/Classes/Example/ShareKitDemoConfigurator.m +++ b/Classes/Example/ShareKitDemoConfigurator.m @@ -40,6 +40,165 @@ - (NSString*)appURL { leaving that decision up to the user. */ +// Sina Weibo + + +// If you want to force use of old-style, for example to ensure +// sina weibo accounts don't end up in the devices account store, set this to true. +- (NSNumber*)forcePreSinaWeiboAccess +{ + return [NSNumber numberWithBool:false]; +} + +// Fill sina weibo App Key(Consumer Key) below and Do not forget to fill it on facebook developer ("URL Scheme Suffix"). +// Leave it blank unless you are sure of what you are doing. +// +// The CFBundleURLSchemes in your App-Info.plist should be "sinaweibosso." + App Key +// Example: +// sinaWeiboConsumerKey = 1631351849 +// +// Your CFBundleURLSchemes entry: sinaweibosso.1631351849 +- (NSString*)sinaWeiboConsumerKey { + return @"1631351849"; +} + +- (NSString*)sinaWeiboConsumerSecret { + return @"9164c304b4e547b8cdbf024fc4534720"; +} + +// You need to set this if using OAuth (MUST be set and SAME AS "Callback Url" of "OAuth 2.0 Auth Settings" on Sina Weibo open plaform. +// Url like this: http://open.weibo.com/apps/{app_key}/info/advanced +- (NSString*)sinaWeiboCallbackUrl { + return @"http://icyleaf.com"; +} + +// To use xAuth, set to 1 +- (NSNumber*)sinaWeiboUseXAuth { + return [NSNumber numberWithInt:0]; +} + +// Enter your sina weibo screen name (Only for xAuth) +- (NSString*)sinaWeiboScreenname { + return @"icyleaf"; +} + +//Enter your app's sina weibo account if you'd like to ask the user to follow it when logging in. (Only for xAuth) +- (NSString*)sinaWeiboUserID { + return @"1708250715"; +} + +// NetEase Weibo +- (NSString*)netEaseWeiboConsumerKey +{ + return @"FP4aD8G9cEFNZEBv"; +} + +- (NSString*)netEaseWeiboConsumerSecret +{ + return @"ZohrmWOBEnVC16jNWIEliXytq62f6xDh"; +} + +// You need to set this if using OAuth (MUST be set "null") +- (NSString*)netEaseWeiboCallbackUrl +{ + return @"null"; +} + +// To use xAuth, set to 1 +- (NSNumber*)netEaseWeiboUseXAuth +{ + return [NSNumber numberWithInt:0]; +} + +// Enter your sina weibo screen name (Only for xAuth) +- (NSString*)netEaseaWeiboScreenname +{ + return @"icyleaf"; +} + +//Enter your app's sina weibo account if you'd like to ask the user to follow it when logging in. (Only for xAuth) +- (NSString*)netEaseWeiboUserID +{ + return @""; +} + + +// Tencent Weibo +- (NSString*)tencentWeiboConsumerKey +{ + return @"801065801"; +} + +- (NSString*)tencentWeiboConsumerSecret +{ + return @"f33650da32c7b1f335311d0c1bd9a6f2"; +} + +- (NSString*)tencentWeiboCallbackUrl +{ + return @"null"; +} + +// Tencent Weixin - http://open.weixin.qq.com +- (NSString*)tencentWeixinAppId +{ + return @"wx59794006e6eb35f5"; +} + +- (NSString*)tencentWeixinAppKey +{ + return @"290fc50a89598b79a1f4d6e3dfc3abc6"; +} + + +// Douban +- (NSString*)doubanConsumerKey { + return @"035c8265fdb968b10a158731f92c3a13"; +} + +- (NSString*)doubanConsumerSecret { + return @"bd44db472be8bf16"; +} + +// You need to set this if using OAuth (MUST be set, it could be any words) +- (NSString*)doubanCallbackUrl { + return @"http://icyleaf.com"; +} + + +// RenRen +- (NSString*)renrenAppId +{ + return @"134180"; +} + +- (NSString*)renrenConsumerKey +{ + return @"ff5fe131651842c7adbdc061f676dc88"; +} + +- (NSString*)renrenConsumerSecret +{ + return @"41d17695626d4c43b3572ce7f923b8a3"; +} + + +// Plurk +- (NSString*)plurkConsumerKey +{ + return @"Vfh091HVf15O"; +} + +- (NSString*)plurkConsumerSecret +{ + return @"mFX8ntsPL2p2Dz17jwKWs8PU7eDHDaR9"; +} + +- (NSString*)plurkCallbackUrl +{ + return @"http://icyleaf.com"; +} + // Vkontakte // SHKVkontakteAppID is the Application ID provided by Vkontakte @@ -194,6 +353,24 @@ - (NSString*)foursquareV2RedirectURI { return @"app://foursquare"; } +/* + Favorite Sharers + ---------------- + These values are used to define the default favorite sharers appearing on ShareKit's action sheet. + */ +- (NSArray*)defaultFavoriteURLSharers { + return [NSArray arrayWithObjects:@"SHKDouban",@"SHKSinaWeibo",@"SHKRenren",@"SHKNetEaseWeibo", nil]; +} +- (NSArray*)defaultFavoriteImageSharers { + return [NSArray arrayWithObjects:@"SHKSinaWeibo",@"SHKNetEaseWeibo", nil]; +} +- (NSArray*)defaultFavoriteTextSharers { + return [NSArray arrayWithObjects:@"SHKMail",@"SHKDouban",@"SHKSinaWeibo",@"SHKNetEaseWeibo", nil]; +} +- (NSArray*)defaultFavoriteFileSharers { + return [NSArray arrayWithObjects:@"SHKMail",@"SHKEvernote", nil]; +} + /* UI Configuration : Basic ------------------------ diff --git a/Classes/Example/sanFran.jpg b/Classes/Example/sanFran.jpg index 6ad777ca0..5edb0cb04 100644 Binary files a/Classes/Example/sanFran.jpg and b/Classes/Example/sanFran.jpg differ diff --git a/Classes/ShareKit/Configuration/DefaultSHKConfigurator.h b/Classes/ShareKit/Configuration/DefaultSHKConfigurator.h index 20ca5630f..e48b9c449 100644 --- a/Classes/ShareKit/Configuration/DefaultSHKConfigurator.h +++ b/Classes/ShareKit/Configuration/DefaultSHKConfigurator.h @@ -50,6 +50,36 @@ - (NSArray*)defaultFavoriteImageSharers; - (NSArray*)defaultFavoriteTextSharers; - (NSArray*)defaultFavoriteFileSharers; +- (NSNumber*)forcePreSinaWeiboAccess; +- (NSString*)sinaWeiboConsumerKey; +- (NSString*)sinaWeiboConsumerSecret; +- (NSString*)sinaWeiboCallbackUrl; +- (NSNumber*)sinaWeiboUseXAuth; +- (NSString*)sinaWeiboScreenname; +- (NSString*)sinaWeiboUserID; +- (NSString*)netEaseWeiboConsumerKey; +- (NSString*)netEaseWeiboConsumerSecret; +- (NSString*)netEaseWeiboCallbackUrl; +- (NSNumber*)netEaseWeiboUseXAuth; +- (NSString*)netEaseaWeiboScreenname; +- (NSString*)netEaseWeiboUserID; +- (NSString*)tencentWeiboConsumerKey; +- (NSString*)tencentWeiboConsumerSecret; +- (NSString*)tencentWeiboCallbackUrl; +- (NSString*)tencentWeixinAppId; +- (NSString*)tencentWeixinAppKey; +- (NSString*)doubanConsumerKey; +- (NSString*)doubanConsumerSecret; +- (NSString*)doubanCallbackUrl; +- (NSString*)renrenAppId; +- (NSString*)renrenConsumerKey; +- (NSString*)renrenConsumerSecret; +- (NSString*)plurkConsumerKey; +- (NSString*)plurkConsumerSecret; +- (NSString*)plurkCallbackUrl; +- (NSString*)vkontakteAppId; +- (NSString*)facebookAppId; +- (NSString*)facebookLocalAppId; - (NSString*)vkontakteAppId; - (NSString*)facebookAppId; - (NSString*)facebookLocalAppId; diff --git a/Classes/ShareKit/Configuration/DefaultSHKConfigurator.m b/Classes/ShareKit/Configuration/DefaultSHKConfigurator.m index 6de7a26ab..804a029be 100644 --- a/Classes/ShareKit/Configuration/DefaultSHKConfigurator.m +++ b/Classes/ShareKit/Configuration/DefaultSHKConfigurator.m @@ -59,6 +59,166 @@ - (NSString*)appURL { leaving that decision up to the user. */ +// Sina Weibo - http://open.weibo.com/ + +// If you want to force use of old-style, for example to ensure +// sina weibo accounts don't end up in the devices account store, set this to true. +- (NSNumber*)forcePreSinaWeiboAccess +{ + return [NSNumber numberWithBool:false]; +} + +// Fill sina weibo App Key(Consumer Key) below and Do not forget to fill it on facebook developer ("URL Scheme Suffix"). +// Leave it blank unless you are sure of what you are doing. +// +// The CFBundleURLSchemes in your App-Info.plist should be "sinaweibosso." + App Key +// Example: +// sinaWeiboConsumerKey = 1631351849 +// +// Your CFBundleURLSchemes entry: sinaweibosso.1631351849 +- (NSString*)sinaWeiboConsumerKey { + return @""; +} + +- (NSString*)sinaWeiboConsumerSecret { + return @""; +} + +// You need to set this if using OAuth (MUST be set and SAME AS "Callback Url" of "OAuth 2.0 Auth Settings" on Sina Weibo open plaform. +// Url like this: http://open.weibo.com/apps/{app_key}/info/advanced +- (NSString*)sinaWeiboCallbackUrl { + return @""; +} + +// To use xAuth, set to 1 +- (NSNumber*)sinaWeiboUseXAuth { + return [NSNumber numberWithInt:0]; +} + +// Enter your sina weibo screen name (Only for xAuth) +- (NSString*)sinaWeiboScreenname { + return @""; +} + +//Enter your app's sina weibo account if you'd like to ask the user to follow it when logging in. (Only for xAuth) +- (NSString*)sinaWeiboUserID { + return @""; +} + + +// NetEase Weibo - http://open.t.163.com/ +- (NSString*)netEaseWeiboConsumerKey +{ + return @""; +} + +- (NSString*)netEaseWeiboConsumerSecret +{ + return @""; +} + +// You need to set this if using OAuth (MUST be set "null") +- (NSString*)netEaseWeiboCallbackUrl +{ + return @"null"; +} + +// To use xAuth, set to 1 +- (NSNumber*)netEaseWeiboUseXAuth +{ + return [NSNumber numberWithInt:0]; +} + +// Enter your netease weibo screen name (Only for xAuth) +- (NSString*)netEaseaWeiboScreenname +{ + return @""; +} + +//Enter your app's netease weibo account if you'd like to ask the user to follow it when logging in. (Only for xAuth) +- (NSString*)netEaseWeiboUserID +{ + return @""; +} + + +// Tencent Weibo - http://open.t.qq.com/ +- (NSString*)tencentWeiboConsumerKey +{ + return @""; +} + +- (NSString*)tencentWeiboConsumerSecret +{ + return @""; +} + +- (NSString*)tencentWeiboCallbackUrl +{ + return @""; +} + +// Tencent Weixin - http://open.weixin.qq.com +- (NSString*)tencentWeixinAppId +{ + return @""; +} + +- (NSString*)tencentWeixinAppKey +{ + return @""; +} + +// Douban - http://www.douban.com/service/apidoc/ +- (NSString*)doubanConsumerKey { + return @""; +} + +- (NSString*)doubanConsumerSecret { + return @""; +} + +// You need to set this if using OAuth (MUST be set, it could be any words) +- (NSString*)doubanCallbackUrl { + return @""; +} + + +// RenRen - http://dev.renren.com/ +- (NSString*)renrenAppId +{ + return @""; +} + +- (NSString*)renrenConsumerKey +{ + return @""; +} + +- (NSString*)renrenConsumerSecret +{ + return @""; +} + + +// Plurk - http://www.plurk.com/API +- (NSString*)plurkConsumerKey +{ + return @""; +} + +- (NSString*)plurkConsumerSecret +{ + return @""; +} + +// You need to set this if using OAuth (Dont forget set it during create app on web) +- (NSString*)plurkCallbackUrl +{ + return @""; +} + + // Vkontakte // SHKVkontakteAppID is the Application ID provided by Vkontakte - (NSString*)vkontakteAppId { diff --git a/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m b/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m index 322ba1ba0..a08692290 100644 --- a/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m +++ b/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m @@ -144,7 +144,13 @@ - (void)tokenRequestTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*) - (void)tokenAuthorize { NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?oauth_token=%@", authorizeURL.absoluteString, requestToken.key]]; - + if ( ! [[authorizeCallbackURL absoluteString] isEqualToString:@""]) { + url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?oauth_token=%@&oauth_callback=%@", + authorizeURL.absoluteString, + requestToken.key, + [authorizeCallbackURL absoluteString]]]; + } + SHKOAuthView *auth = [[SHKOAuthView alloc] initWithURL:url delegate:self]; [[SHK currentHelper] showViewController:auth]; [auth release]; diff --git a/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.h b/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.h index 61d73c42b..3a7fd187f 100644 --- a/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.h +++ b/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.h @@ -162,6 +162,7 @@ typedef enum #pragma mark API Implementation -(NSString *)tagStringJoinedBy:(NSString *)joinString allowedCharacters:(NSCharacterSet *)charset tagPrefix:(NSString *)prefixString; +-(NSString *)tagStringJoinedBy:(NSString *)joinString allowedCharacters:(NSCharacterSet *)charset tagPrefix:(NSString *)prefixString forChina:(BOOL)forChina; - (BOOL)validateItem; - (BOOL)tryToSend; diff --git a/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.m b/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.m index b8e2758b2..18c903063 100644 --- a/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.m +++ b/Classes/ShareKit/Core/Base Sharer Classes/SHKSharer.m @@ -598,6 +598,25 @@ -(NSString *)tagStringJoinedBy:(NSString *)joinString allowedCharacters:(NSChara return [cleanedTags componentsJoinedByString:joinString]; } +-(NSString *)tagStringJoinedBy:(NSString *)joinString allowedCharacters:(NSCharacterSet *)charset tagPrefix:(NSString *)prefixString forChina:(BOOL)forChina { + + NSMutableArray *cleanedTags = [NSMutableArray arrayWithCapacity:[self.item.tags count]]; + + for (NSString *tag in self.item.tags) { + NSCharacterSet *removeSet = [charset invertedSet]; + NSString *strippedTag = [[tag componentsSeparatedByCharactersInSet:removeSet] + componentsJoinedByString:@"" ]; + if ([strippedTag length] < 1) continue; + strippedTag = [strippedTag stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if ([strippedTag length] < 1) continue; + if ([prefixString length] > 0) [cleanedTags addObject:[NSString stringWithFormat:@"%@%@%@", prefixString, strippedTag, forChina ? prefixString : @""]]; + else [cleanedTags addObject:strippedTag]; + } + + if ([cleanedTags count] < 1) return @""; + return [cleanedTags componentsJoinedByString:joinString]; +} + #pragma mark - - (void)updateItemWithForm:(SHKFormController *)form diff --git a/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m b/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m index f0014856a..9a7a8eb60 100755 --- a/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m +++ b/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m @@ -227,7 +227,8 @@ - (NSString *)_signatureBaseString [parameterPairs addObject:[[OARequestParameter requestParameterWithName:parameterName value:[extraOAuthParameters objectForKey:parameterName]] URLEncodedNameValuePair]]; } - if (![[self valueForHTTPHeaderField:@"Content-Type"] hasPrefix:@"multipart/form-data"]) { + if ( ! [[self valueForHTTPHeaderField:@"Content-Type"] hasPrefix:@"multipart/form-data"] + && ! [[self valueForHTTPHeaderField:@"Content-Type"] hasPrefix:@"application/atom+xml"]) { for (OARequestParameter *param in [self parameters]) { [parameterPairs addObject:[param URLEncodedNameValuePair]]; } diff --git a/Classes/ShareKit/Core/SHKSharers.plist b/Classes/ShareKit/Core/SHKSharers.plist index a261ee0c2..40e07687b 100644 --- a/Classes/ShareKit/Core/SHKSharers.plist +++ b/Classes/ShareKit/Core/SHKSharers.plist @@ -14,7 +14,14 @@ services + SHKDouban SHKKippt + SHKSinaWeibo + SHKNetEaseWeibo + SHKTencentWeibo + SHKTencentWeixin + SHKRenRen + SHKPlurk SHKReadability SHKEvernote SHKDelicious diff --git a/Classes/ShareKit/ShareKit.bundle/fi.lproj/Localizable.strings b/Classes/ShareKit/ShareKit.bundle/fi.lproj/Localizable.strings index 6a2d1a154..91ad3ac68 100644 --- a/Classes/ShareKit/ShareKit.bundle/fi.lproj/Localizable.strings +++ b/Classes/ShareKit/ShareKit.bundle/fi.lproj/Localizable.strings @@ -103,4 +103,4 @@ "Logged Out!" = "Kirjauduttu ulos!"; "Sent from %@" = "Lähetetty palvelusta %@"; "Save to Photo Album" = "Tallenna Kuva-albumiin"; -"Tag, tag" = "Tagi, tagi"; \ No newline at end of file +"Tag, tag" = "Tagi, tagi"; diff --git a/Classes/ShareKit/ShareKit.bundle/zh_CN.lproj/Localizable.strings b/Classes/ShareKit/ShareKit.bundle/zh_CN.lproj/Localizable.strings index bd2f4c692..bf0711cdb 100644 --- a/Classes/ShareKit/ShareKit.bundle/zh_CN.lproj/Localizable.strings +++ b/Classes/ShareKit/ShareKit.bundle/zh_CN.lproj/Localizable.strings @@ -1,100 +1,147 @@ "Email" = "电子邮件"; + "Username" = "用户名"; + "Password" = "密码"; + "Follow %@" = "关注%@"; + "Continue" = "继续"; + "Share" = "分享"; + "More..." = "更多…"; + "Cancel" = "取消"; + "Slug" = "Slug"; + "Private" = "私有"; + "Public" = "公开"; + "Caption" = "标题"; + "Title" = "标题"; + +"Tags" = "标签"; + "Close" = "关闭"; + "Notes" = "笔记"; + "Note" = "笔记"; + "Shared" = "已分享"; + "Edit" = "编辑"; + "Actions" = "动作"; + "Services" = "服务"; -"Send to %@" = "发送到 %@"; + +"Send to %@" = "分享到%@"; + "Copy" = "复制"; + "Copied!" = "已复制!"; -"Saving to %@" = "保存至%@"; -"Saved!" = "已保存!"; + +"Saving to %@" = "正在分享至%@"; + +"Saved!" = "分享成功!"; + "Offline" = "离线"; + "Error" = "错误"; + "Login" = "登录"; + "Logging In..." = "登录中…"; + "Login Error" = "登录出错"; -"Connecting..." = "连接中…"; +"Connecting..." = "连接中…"; "Shortening URL..." = "缩短网址…"; + "Shorten URL Error" = "缩短网址出错"; + "We could not shorten the URL." = "我们无法缩短网址。"; "Create a free account at %@" = "在 %@ 上创建一个免费账户"; + "Create an account at %@" = "在 %@ 上创建一个账户"; "Send to Twitter" = "发送到 Twitter"; "Message is too long" = "消息太长了"; + "Twitter posts can only be 140 characters in length." = "Twitter 消息不能超过 140 个字符。"; + "Message is empty" = "消息为空"; + "You must enter a message in order to post." = "你必须先输入一条消息。"; "Enter your message:" = "输入你的消息:"; "Invalid email or password." = "Email 或密码不正确。"; + "The service encountered an error. Please try again later." = "此服务碰到了一点错误,请稍后重试。"; + "There was an error sending your post to Tumblr." = "发送至 Tumblr 的过程中出错。"; "There was an error saving to Pinboard" = "保存到 Pinboard 的过程中出错"; "Sorry, %@ did not accept your credentials. Please try again." = "抱歉,%@ 无法验证您的账号,请重试。"; -"Sorry, %@ encountered an error. Please try again." = "抱歉,%@ 碰到了一个问题,请重试。"; -"There was a problem saving to %@." = "保存到 %@ 的过程中出错。"; + +"Sorry, Instapaper encountered an error. Please try again." = "抱歉,Instapaper 碰到了一个问题,请重试。"; + +"There was a problem saving to Instapaper." = "保存到 Instapaper 的过程中出错。"; "Incorrect username and password" = "用户名或密码不正确"; -"There was an error logging into Google Reader" = "登录到 Google Reader 的过程中出错"; +"There was an error logging into Google Reader" = "登录到 Google Reader 的过程中出错"; "There was a problem saving your note." = "保存您笔记的过程中出错。"; "Open in Safari" = "在 Safari 中打开"; -"Attached: %@" = "附件: %@"; + +"Attached: %@" = "附件:%@"; "You must be online to login to %@" = "要登录到 %@ 上您必须在线"; "Auto Share" = "自动分享"; + "Enable auto share to skip this step in the future." = "启动自动分享,在以后可以跳过此步。"; "You must be online in order to share with %@" = "要分享 %@ 的话您必须在线。"; "Could not authenticate you. Please relogin." = "无法验证,请重新登录。"; + "There was a problem requesting authorization from %@" = "在向 %@ 请求验证的过程中出错"; + "Request Error" = "请求错误"; +"There was an error while sharing" = "分享过程中出错"; + "Authorize Error" = "验证错误"; + "There was an error while authorizing" = "验证的过程中出错"; "Authenticating..." = "验证中…"; + "There was a problem requesting access from %@" = "从 %@ 获取口令出错"; "Access Error" = "访问错误"; -"There was an error while sharing" = "在分享的过程中出错"; -"Save to Photo Album" = "保存到相簿"; "Logout" = "注销"; -"Sharing a Link" = "分享一个链接"; +"Sharing a Link" = "分享链接"; -"Sharing an Image" = "分享一张图片"; +"Sharing an Image" = "分享图片"; -"Sharing Text" = "分享一段文字"; +"Sharing Text" = "分享文字"; -"Sharing a File" = "分享一份文件"; +"Sharing a File" = "分享文件"; "Are you sure you want to logout of all share services?" = "确认注销所有绑定的服务?"; @@ -114,6 +161,8 @@ "Description" = "描述"; +"Tag (space) Tag" = "标签 (空格) 标签"; + "Is Public" = "是否公开"; "Is Friend" = "好友可见"; @@ -126,7 +175,7 @@ "Save to Photo Album" = "保存到相簿"; -"Tag, tag" = "标签,标签"; +"Tag,Tag" = "标签,标签"; "Logout of All Services" = "退出所有服务"; @@ -158,4 +207,11 @@ "Search places" = "搜索地点"; /* No comment provided by engineer. */ -"Searching places..." = "正在搜索地点…"; \ No newline at end of file +"Searching places..." = "正在搜索地点…"; + +/* No comment provided by icyleaf. */ +"SMS" = "短信"; + +/* No comment provided by icyleaf. */ +"This is a chunk of text. If you highlight it, you'll be able to share the selection. If you tap the share button below, it will share all of it." = "这里一段演示文字。你可以分享选中高亮部分的文字。如果你直接按下底部的分享按钮,默认会分享全部文字。"; + diff --git a/Classes/ShareKit/Sharers/Services/Douban/SHKDouban.h b/Classes/ShareKit/Sharers/Services/Douban/SHKDouban.h new file mode 100644 index 000000000..f9d0f749f --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Douban/SHKDouban.h @@ -0,0 +1,52 @@ +// +// SHKDouban.h +// ShareKit +// +// Created by icyleaf on 12-03-16. +// Copyright 2012 icyleaf.com. All rights reserved. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import +#import "SHKOAuthSharer.h" +#import "SHKFormControllerLargeTextField.h" + +@interface SHKDouban : SHKOAuthSharer + +#pragma mark - +#pragma mark UI Implementation + +- (void)showDoubanForm; + +#pragma mark - +#pragma mark Share API Methods + +- (void)sendStatus; +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error; + +// TODO: Finish it below +//- (void)sendUserInfo; +//- (void)sendUserInfo:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +//- (void)sendUserInfo:(OAServiceTicket *)ticket didFailWithError:(NSError*)error; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Douban/SHKDouban.m b/Classes/ShareKit/Sharers/Services/Douban/SHKDouban.m new file mode 100644 index 000000000..0f482be46 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Douban/SHKDouban.m @@ -0,0 +1,373 @@ +// +// SHKDouban.m +// ShareKit +// +// Created by icyleaf on 12-03-16. +// Copyright 2012 icyleaf.com. All rights reserved. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +#import "SHKDouban.h" +#import "SHKConfiguration.h" +#import "JSONKit.h" +#import "SHKXMLResponseParser.h" +#import "NSMutableDictionary+NSNullsToEmptyStrings.h" + +static NSString *const kSHKDoubanUserInfo = @"kSHKDoubanUserInfo"; + +@interface SHKDouban () + +- (BOOL)shortenURL; +- (void)shortenURLFinished:(SHKRequest *)aRequest; +- (BOOL)validateItemAfterUserEdit; +- (void)handleUnsuccessfulTicket:(NSData *)data; + +@end + +@implementation SHKDouban + +- (id)init +{ + if (self = [super init]) + { + // OAUTH + self.consumerKey = SHKCONFIG(doubanConsumerKey); + self.secretKey = SHKCONFIG(doubanConsumerSecret); + self.authorizeCallbackURL = [NSURL URLWithString:SHKCONFIG(doubanCallbackUrl)]; + + // -- // + + // You do not need to edit these, they are the same for everyone + self.authorizeURL = [NSURL URLWithString:@"http://www.douban.com/service/auth/authorize"]; + self.requestURL = [NSURL URLWithString:@"http://www.douban.com/service/auth/request_token"]; + self.accessURL = [NSURL URLWithString:@"http://www.douban.com/service/auth/access_token"]; + } + return self; +} + + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"豆瓣"; +} + ++ (BOOL)canShareURL +{ + return YES; +} + ++ (BOOL)canShareText +{ + return YES; +} + ++ (BOOL)canGetUserInfo +{ + return YES; +} + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + +#pragma mark - +#pragma mark Authorization + ++ (void)logout +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kSHKDoubanUserInfo]; + [super logout]; +} + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { + [self shortenURL]; + } + + else if (item.shareType == SHKShareTypeImage) + { + [item setCustomValue:item.title forKey:@"status"]; + [self showDoubanForm]; + } + + else if (item.shareType == SHKShareTypeText) + { + [item setCustomValue:item.text forKey:@"status"]; + [self showDoubanForm]; + } + + else if (item.shareType == SHKShareTypeUserInfo) + { + [self setQuiet:YES]; + [self tryToSend]; + } +} + +- (void)showDoubanForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil bundle:nil delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + [item setCustomValue:form.textView.text forKey:@"status"]; + [self tryToSend]; +} + +#pragma mark - + +- (BOOL)shortenURL +{ + if ([SHKCONFIG(sinaWeiboConsumerKey) isEqualToString:@""] || SHKCONFIG(sinaWeiboConsumerKey) == nil) + NSAssert(NO, @"ShareKit: Could not shorting url with empty sina weibo consumer key."); + + if (![SHK connected]) + { + [item setCustomValue:[NSString stringWithFormat:@"%@: %@", item.title, [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] forKey:@"status"]; + [self showDoubanForm]; + return NO; + } + + if (!quiet) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Shortening URL...")]; + + self.request = [[[SHKRequest alloc] initWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"http://api.t.sina.com.cn/short_url/shorten.json?source=%@&url_long=%@", + SHKCONFIG(sinaWeiboConsumerKey), + SHKEncodeURL(item.URL) + ]] + params:nil + delegate:self + isFinishedSelector:@selector(shortenURLFinished:) + method:@"GET" + autostart:YES] autorelease]; + + return YES; +} + +- (void)shortenURLFinished:(SHKRequest *)aRequest +{ + [[SHKActivityIndicator currentIndicator] hide]; + + @try + { + NSArray *result = [[aRequest getResult] objectFromJSONString]; + item.URL = [NSURL URLWithString:[[result objectAtIndex:0] objectForKey:@"url_short"]]; + } + @catch (NSException *exception) + { + // TODO - better error message + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Shorten URL Error") + message:SHKLocalizedString(@"We could not shorten the URL.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; + } + + [item setCustomValue:[NSString stringWithFormat:@"%@: %@", item.title, item.URL.absoluteString] + forKey:@"status"]; + + [self showDoubanForm]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem +{ + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + if ( ! [self validateItemAfterUserEdit]) + return NO; + + switch (item.shareType) + { +// case SHKShareTypeUserInfo: +// [self sendUserInfo]; +// break; +// + default: + [self sendStatus]; + break; + } + + // Notify delegate + [self sendDidStart]; + + return YES; +} + +- (void)sendStatus +{ + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://api.douban.com/miniblog/saying"] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:nil]; + + [oRequest setHTTPMethod:@"POST"]; + [oRequest addValue:@"application/atom+xml" forHTTPHeaderField:@"Content-Type"]; + + NSMutableString *body = [NSMutableString stringWithFormat:@""]; + [body appendFormat:@""]; + [body appendFormat:@"", [item customValueForKey:@"status"]]; + [body appendFormat:@""]; + + [oRequest setHTTPBody:[body dataUsingEncoding:NSUnicodeStringEncoding allowLossyConversion:YES]]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendStatusTicket:didFinishWithData:) + didFailSelector:@selector(sendStatusTicket:didFailWithError:)]; + + [fetcher start]; + [oRequest release]; +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data +{ + // TODO better error handling here + + if (ticket.didSucceed) + [self sendDidFinish]; + + else + { + [self handleUnsuccessfulTicket:data]; + } +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error +{ + [self sendDidFailWithError:error]; +} + +#pragma mark - Overrewrite parent method +- (void)tokenAuthorize +{ + NSString *urlString = [NSString stringWithFormat:@"%@?oauth_token=%@&p=1", authorizeURL.absoluteString, requestToken.key]; + + if ( ! [[authorizeCallbackURL absoluteString] isEqualToString:@""]) { + urlString = [NSString stringWithFormat:@"%@&oauth_callback=%@&p=1", + urlString, + [authorizeCallbackURL absoluteString]]; + } + + SHKOAuthView *auth = [[SHKOAuthView alloc] initWithURL:[NSURL URLWithString:urlString] delegate:self]; + [[SHK currentHelper] showViewController:auth]; + [auth release]; +} + +#pragma mark - + +- (void)handleUnsuccessfulTicket:(NSData *)data +{ + if (SHKDebugShowLogs) + SHKLog(@"Sina Weibo Send Status Error: %@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + // CREDIT: Oliver Drobnik + + NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + + // in case our makeshift parsing does not yield an error message + NSString *errorMessage = @"Unknown Error"; + + NSScanner *scanner = [NSScanner scannerWithString:string]; + + // skip until error message + [scanner scanUpToString:@"\"error\":\"" intoString:nil]; + + + if ([scanner scanString:@"\"error\":\"" intoString:nil]) + { + // get the message until the closing double quotes + [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\""] intoString:&errorMessage]; + } + + + // this is the error message for revoked access ...?... || removed app from Twitter + if ([errorMessage isEqualToString:@"Invalid / used nonce"] || [errorMessage isEqualToString:@"Could not authenticate with OAuth."]) { + + [self shouldReloginWithPendingAction:SHKPendingSend]; + + } else { + + //when sharing image, and the user removed app permissions there is no JSON response expected above, but XML, which we need to parse. 401 is obsolete credentials -> need to relogin + if ([[SHKXMLResponseParser getValueForElement:@"code" fromResponse:data] isEqualToString:@"401"]) { + + [self shouldReloginWithPendingAction:SHKPendingSend]; + return; + } + } + + NSError *error = [NSError errorWithDomain:@"SinaWeibo" code:2 userInfo:[NSDictionary dictionaryWithObject:errorMessage forKey:NSLocalizedDescriptionKey]]; + [self sendDidFailWithError:error]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Flickr/SHKFlickr.h b/Classes/ShareKit/Sharers/Services/Flickr/SHKFlickr.h index b469adfa2..127bc981b 100644 --- a/Classes/ShareKit/Sharers/Services/Flickr/SHKFlickr.h +++ b/Classes/ShareKit/Sharers/Services/Flickr/SHKFlickr.h @@ -31,8 +31,7 @@ #import "ObjectiveFlickr.h" #import "SHKFormOptionController.h" -@interface SHKFlickr : SHKSharer< OFFlickrAPIRequestDelegate, - SHKOAuthViewDelegate, +@interface SHKFlickr : SHKSharer< SHKOAuthViewDelegate, SHKFormOptionControllerOptionProvider> { OFFlickrAPIContext *flickrContext; diff --git a/Classes/ShareKit/Sharers/Services/NetEase Weibo/SHKNetEaseWeibo.h b/Classes/ShareKit/Sharers/Services/NetEase Weibo/SHKNetEaseWeibo.h new file mode 100644 index 000000000..9c42e9c0d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/NetEase Weibo/SHKNetEaseWeibo.h @@ -0,0 +1,62 @@ +// +// SHKNetEaseWeibo.h +// ShareKit +// +// Created by icyleaf on 11-12-04. +// Copyright 2011 icyleaf.com. All rights reserved. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import +#import "SHKOAuthSharer.h" +#import "SHKFormControllerLargeTextField.h" + + +@interface SHKNetEaseWeibo : SHKOAuthSharer +{ + BOOL xAuth; +} + +@property BOOL xAuth; + + +#pragma mark - +#pragma mark UI Implementation + +- (void)showNetEaseWeiboForm; + +#pragma mark - +#pragma mark Share API Methods + +- (void)sendStatus; +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error; + +- (void)sendImage; +- (void)sendImageTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +- (void)sendImageTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error; + +- (void)followMe; +- (void)followMeTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +- (void)followMeTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error; + +@end diff --git a/Classes/ShareKit/Sharers/Services/NetEase Weibo/SHKNetEaseWeibo.m b/Classes/ShareKit/Sharers/Services/NetEase Weibo/SHKNetEaseWeibo.m new file mode 100644 index 000000000..aa9ea048f --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/NetEase Weibo/SHKNetEaseWeibo.m @@ -0,0 +1,622 @@ +// +// SHKNetEaseWeibo.m +// ShareKit +// +// Created by icyleaf on 12-03-16. +// Copyright 2012 icyleaf.com. All rights reserved. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "SHKNetEaseWeibo.h" +#import "JSONKit.h" +#import "SHKConfiguration.h" +#import "NSMutableDictionary+NSNullsToEmptyStrings.h" + + +#define API_DOMAIN @"http://api.t.163.com" + +static NSString *const kSHKNetEaseWeiboUserInfo = @"kSHKNetEaseWeiboUserInfo"; + + +@interface SHKNetEaseWeibo (Private) + +- (BOOL)prepareItem; +- (BOOL)shortenURL; +- (void)shortenURLFinished:(SHKRequest *)aRequest; +- (BOOL)validateItemAfterUserEdit; +- (void)handleUnsuccessfulTicket:(NSData *)data; + +@end + +@implementation SHKNetEaseWeibo + +@synthesize xAuth; + +- (id)init +{ + if ((self = [super init])) + { + // OAuth + self.consumerKey = SHKCONFIG(netEaseWeiboConsumerKey); + self.secretKey = SHKCONFIG(netEaseWeiboConsumerSecret); + self.authorizeCallbackURL = [NSURL URLWithString:SHKCONFIG(netEaseWeiboCallbackUrl)]; + + // xAuth + self.xAuth = [SHKCONFIG(netEaseWeiboUseXAuth) boolValue] ? YES : NO; + + // You do not need to edit these, they are the same for everyone + self.authorizeURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/oauth/authenticate", API_DOMAIN]]; + self.requestURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/oauth/request_token", API_DOMAIN]]; + self.accessURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/oauth/access_token", API_DOMAIN]]; + } + return self; +} + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"网易微博"; +} + ++ (BOOL)canShareURL +{ + return YES; +} + ++ (BOOL)canShareText +{ + return YES; +} + ++ (BOOL)canShareImage +{ + return YES; +} + ++ (BOOL)canGetUserInfo +{ + return YES; +} + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + +#pragma mark - +#pragma mark Commit Share + +- (void)share +{ + BOOL itemPrepared = [self prepareItem]; + + //the only case item is not prepared is when we wait for URL to be shortened on background thread. In this case [super share] is called in callback method + if (itemPrepared) { + [super share]; + } +} + +#pragma mark - + +- (BOOL)prepareItem +{ + BOOL result = YES; + + if (item.shareType == SHKShareTypeURL) + { + BOOL isURLAlreadyShortened = [self shortenURL]; + result = isURLAlreadyShortened; + + } + + else if (item.shareType == SHKShareTypeImage) + { + [item setCustomValue:item.title forKey:@"status"]; + } + + else if (item.shareType == SHKShareTypeText) +{ + [item setCustomValue:item.text forKey:@"status"]; + } + + return result; +} + +#pragma mark - +#pragma mark Authorization + +- (void)promptAuthorization +{ + if (xAuth) + [super authorizationFormShow]; // xAuth process + + else + [super promptAuthorization]; // OAuth process +} + ++ (void)logout { + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kSHKNetEaseWeiboUserInfo]; + [super logout]; +} + +#pragma mark xAuth + ++ (NSString *)authorizationFormCaption +{ + return SHKLocalizedString(@"Create a free account at %@", @"t.163.com"); +} + ++ (NSArray *)authorizationFormFields +{ + if ([SHKCONFIG(netEaseWeiboUserID) isEqualToString:@""]) + return [super authorizationFormFields]; + + NSString *followMeString = [SHKCONFIG(netEaseaWeiboScreenname) isEqualToString:@""] ? + SHKLocalizedString(@"Follow us") : SHKLocalizedString(@"Follow %@", SHKCONFIG(netEaseaWeiboScreenname)); + + + return [NSArray arrayWithObjects: + [SHKFormFieldSettings label:SHKLocalizedString(@"Username") key:@"username" type:SHKFormFieldTypeText start:nil], + [SHKFormFieldSettings label:SHKLocalizedString(@"Password") key:@"password" type:SHKFormFieldTypePassword start:nil], + [SHKFormFieldSettings label:followMeString key:@"followMe" type:SHKFormFieldTypeSwitch start:SHKFormFieldSwitchOn], + nil]; +} + +- (void)authorizationFormValidate:(SHKFormController *)form +{ + self.pendingForm = form; + [self tokenAccess]; +} + +- (void)tokenAccessModifyRequest:(OAMutableURLRequest *)oRequest +{ + if (xAuth) + { + NSDictionary *formValues = [pendingForm formValues]; + + OARequestParameter *username = [[[OARequestParameter alloc] initWithName:@"x_auth_username" + value:[formValues objectForKey:@"username"]] autorelease]; + + OARequestParameter *password = [[[OARequestParameter alloc] initWithName:@"x_auth_password" + value:[formValues objectForKey:@"password"]] autorelease]; + + OARequestParameter *mode = [[[OARequestParameter alloc] initWithName:@"x_auth_mode" + value:@"client_auth"] autorelease]; + + [oRequest setParameters:[NSArray arrayWithObjects:username, password, mode, nil]]; + } + else + { + if (pendingAction == SHKPendingRefreshToken) + { + if (accessToken.sessionHandle != nil) + [oRequest setOAuthParameterName:@"oauth_session_handle" withValue:accessToken.sessionHandle]; + } + + else if ([authorizeResponseQueryVars objectForKey:@"oauth_verifier"]) + [oRequest setOAuthParameterName:@"oauth_verifier" withValue:[authorizeResponseQueryVars objectForKey:@"oauth_verifier"]]; + } +} + +- (void)tokenAccessTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data +{ + if (xAuth) + { + if (ticket.didSucceed) + { + [item setCustomValue:[[pendingForm formValues] objectForKey:@"followMe"] forKey:@"followMe"]; + [pendingForm close]; + } + + else + { + NSString *response = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + + SHKLog(@"tokenAccessTicket Response Body: %@", response); + + [self tokenAccessTicket:ticket didFailWithError:[SHK error:response]]; + return; + } + } + + [super tokenAccessTicket:ticket didFinishWithData:data]; +} + + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { + [self showNetEaseWeiboForm]; + } + + else if (item.shareType == SHKShareTypeImage) + { + [self showNetEaseWeiboForm]; + } + + else if (item.shareType == SHKShareTypeText) + { + [self showNetEaseWeiboForm]; + } + + else if (item.shareType == SHKShareTypeUserInfo) + { + [self setQuiet:YES]; + [self tryToSend]; + } +} + +- (void)showNetEaseWeiboForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil bundle:nil delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + [item setCustomValue:form.textView.text forKey:@"status"]; + [self tryToSend]; +} + +#pragma mark - + +- (BOOL)shortenURL +{ + if ([SHKCONFIG(sinaWeiboConsumerKey) isEqualToString:@""] || SHKCONFIG(sinaWeiboConsumerKey) == nil) + NSAssert(NO, @"ShareKit: Could not shorting url with empty sina weibo consumer key."); + + if (![SHK connected]) + { + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title, [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] forKey:@"status"]; + return YES; + } + + if (!quiet) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Shortening URL...")]; + + self.request = [[[SHKRequest alloc] initWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"http://api.t.sina.com.cn/short_url/shorten.json?source=%@&url_long=%@", + SHKCONFIG(sinaWeiboConsumerKey), + SHKEncodeURL(item.URL) + ]] + params:nil + delegate:self + isFinishedSelector:@selector(shortenURLFinished:) + method:@"GET" + autostart:YES] autorelease]; + + return NO; +} + +- (void)shortenURLFinished:(SHKRequest *)aRequest +{ + [[SHKActivityIndicator currentIndicator] hide]; + + @try + { + NSArray *result = [[aRequest getResult] objectFromJSONString]; + item.URL = [NSURL URLWithString:[[result objectAtIndex:0] objectForKey:@"url_short"]]; + } + @catch (NSException *exception) + { + // TODO - better error message + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Shorten URL Error") + message:SHKLocalizedString(@"We could not shorten the URL.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; + } + + [item setCustomValue:[NSString stringWithFormat:@"%@: %@", item.title, item.URL.absoluteString] + forKey:@"status"]; + + [super share]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem + { + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + // Check if we should send follow request too + if (xAuth && [item customBoolForSwitchKey:@"followMe"]) + [self followMe]; + + if (![self validateItemAfterUserEdit]) + return NO; + + switch (item.shareType) { + + case SHKShareTypeImage: + [self sendImage]; + break; + + case SHKShareTypeUserInfo: +// [self sendUserInfo]; + break; + + default: + [self sendStatus]; + break; + } + + // Notify delegate + [self sendDidStart]; + + return YES; +} + +- (void)sendStatus +{ + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/statuses/update.json", API_DOMAIN]] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:nil]; + + [oRequest setHTTPMethod:@"POST"]; + + OARequestParameter *statusParam = [[OARequestParameter alloc] initWithName:@"status" + value:[item customValueForKey:@"status"]]; + NSArray *params = [NSArray arrayWithObjects:statusParam, nil]; + [oRequest setParameters:params]; + [statusParam release]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendStatusTicket:didFinishWithData:) + didFailSelector:@selector(sendStatusTicket:didFailWithError:)]; + + [fetcher start]; + [oRequest release]; +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data +{ + // TODO better error handling here + + if (ticket.didSucceed) + [self sendDidFinish]; + + else + { + [self handleUnsuccessfulTicket:data]; + } +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error +{ + [self sendDidFailWithError:error]; +} + +- (void)sendImage { + + NSURL *serviceURL = nil; + if([item customValueForKey:@"profile_update"]){ + serviceURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/account/update_profile_image.json", API_DOMAIN]]; + } else { + serviceURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/statuses/upload.json", API_DOMAIN]]; + } + + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL + consumer:consumer + token:accessToken + realm:API_DOMAIN + signatureProvider:signatureProvider]; + [oRequest setHTTPMethod:@"POST"]; + [oRequest prepare]; + + CGFloat compression = 0.9f; + NSData *imageData = UIImageJPEGRepresentation([item image], compression); + + // TODO + // Note from Nate to creator of sendImage method - This seems like it could be a source of sluggishness. + // For example, if the image is large (say 3000px x 3000px for example), it would be better to resize the image + // to an appropriate size (max of img.ly) and then start trying to compress. + + while ([imageData length] > 700000 && compression > 0.1) { + // NSLog(@"Image size too big, compression more: current data size: %d bytes",[imageData length]); + compression -= 0.1; + imageData = UIImageJPEGRepresentation([item image], compression); + + } + + NSString *boundary = @"0xKhTmLbOuNdArY"; + NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; + [oRequest setValue:contentType forHTTPHeaderField:@"Content-Type"]; + + NSMutableData *body = [NSMutableData data]; + NSString *dispKey = @""; + if([item customValueForKey:@"profile_update"]){ + dispKey = @"Content-Disposition: form-data; name=\"image\"; filename=\"upload.jpg\"\r\n"; + } else { + dispKey = @"Content-Disposition: form-data; name=\"pic\"; filename=\"upload.jpg\"\r\n"; + } + + [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[dispKey dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:imageData]; + [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + +// if([item customValueForKey:@"profile_update"]){ +// // no ops +// } else { +// [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; +// [body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"status\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; +// [body appendData:[[item customValueForKey:@"status"] dataUsingEncoding:NSUTF8StringEncoding]]; +// [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; +// } + + [body appendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + + // setting the body of the post to the reqeust + [oRequest setHTTPBody:body]; + + // Notify delegate + [self sendDidStart]; + + // Start the request + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendImageTicket:didFinishWithData:) + didFailSelector:@selector(sendImageTicket:didFailWithError:)]; + + [fetcher start]; + + + [oRequest release]; +} + +- (void)sendImageTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { + // TODO better error handling here + SHKLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + if (ticket.didSucceed) { + [self sendDidFinish]; + + @try + { + // Finished uploading Image, now need to posh the message and url in netease weibo + NSDictionary *result = [data objectFromJSONData]; + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", [item customValueForKey:@"status"], [result objectForKey:@"upload_image_url"]] + forKey:@"status"]; + + } + @catch (NSException *exception) { + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Upload image Error") + message:SHKLocalizedString(@"We could not upload the image.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; + } + + [self sendStatus]; + } else { + [self sendDidFailWithError:[SHK error:SHKLocalizedString(@"There was a problem saving to NetEase Weibo.")]]; + } +} + +- (void)sendImageTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error { + [self sendDidFailWithError:error]; +} + + +- (void)followMe +{ + // remove it so in case of other failures this doesn't get hit again + [item setCustomValue:nil forKey:@"followMe"]; + + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/friendships/create.json", API_DOMAIN]] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:nil]; + + [oRequest setHTTPMethod:@"POST"]; + OARequestParameter *statusParam = [[OARequestParameter alloc] initWithName:@"id" + value:kSHKNetEaseWeiboUserInfo]; + NSArray *params = [NSArray arrayWithObjects:statusParam, nil]; + [oRequest setParameters:params]; + [statusParam release]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self // Currently not doing any error handling here. If it fails, it's probably best not to bug the user to follow you again. + didFinishSelector:@selector(followMeTicket:didFinishWithData:) + didFailSelector:@selector(followMeTicket:didFailWithError:)]; + + [fetcher start]; + [oRequest release]; +} + + +- (void)followMeTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { + SHKLog(@"followMeTicket response: %@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + if ( ! ticket.didSucceed) { + [self sendDidFailWithError:[SHK error:SHKLocalizedString(@"There was an error while follow NetEase Weibo account, May be user is not exist.")]]; + } +} + +- (void)followMeTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error { + [self sendDidFailWithError:error]; +} + +#pragma mark - Request + +//- (void)tokenAuthorize +//{ +// NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?oauth_token=%@&client_type=mobile", +// authorizeURL.absoluteString, +// requestToken.key]]; +// +// SHKOAuthView *auth = [[SHKOAuthView alloc] initWithURL:url delegate:self]; +// [[SHK currentHelper] showViewController:auth]; +// [auth release]; +//} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Plurk/SHKPlurk.h b/Classes/ShareKit/Sharers/Services/Plurk/SHKPlurk.h new file mode 100644 index 000000000..6bcceacd0 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Plurk/SHKPlurk.h @@ -0,0 +1,52 @@ +// +// SHKPlurk.h +// ShareKit +// +// Created by Che-Ching Wu on 6/16/2011. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import +#import "SHKOAuthSharer.h" +#import "SHKFormControllerLargeTextField.h" + +@interface SHKPlurk : SHKOAuthSharer + + +#pragma mark - +#pragma mark UI Implementation + +- (void)showPlurkForm; + +#pragma mark - +#pragma mark Share API Methods + +- (void)sendStatus; +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error; + +- (void)uploadImage; +- (void)uploadImageTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data; +- (void)uploadImageTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error; +- (void)alertUploadImageWithError:(NSError *)error; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Plurk/SHKPlurk.m b/Classes/ShareKit/Sharers/Services/Plurk/SHKPlurk.m new file mode 100644 index 000000000..8471a9dd7 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Plurk/SHKPlurk.m @@ -0,0 +1,445 @@ +// +// SHKPlurk.m +// ShareKit +// +// Created by Che-Ching Wu on 6/16/2011. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +// TODO - SHKPlurk supports offline sharing, however the url cannot be shortened without an internet connection. Need a graceful workaround for this. + + +#import "SHKPlurk.h" +#import "SHKConfiguration.h" +#import "NSMutableDictionary+NSNullsToEmptyStrings.h" + + +@interface SHKPlurk () + +- (BOOL)shortenURL; +- (void)shortenURLFinished:(SHKRequest *)aRequest; + +@end + + +@implementation SHKPlurk + +- (id)init +{ + if (self = [super init]) + { + // OAUTH + self.consumerKey = SHKCONFIG(plurkConsumerKey); + self.secretKey = SHKCONFIG(plurkConsumerSecret); + self.authorizeCallbackURL = [NSURL URLWithString:SHKCONFIG(plurkCallbackUrl)]; + + // -- // + + // You do not need to edit these, they are the same for everyone + self.authorizeURL = [NSURL URLWithString:@"http://www.plurk.com/m/authorize"]; + self.requestURL = [NSURL URLWithString:@"http://www.plurk.com/OAuth/request_token"]; + self.accessURL = [NSURL URLWithString:@"http://www.plurk.com/OAuth/access_token"]; + } + return self; +} + + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"Plurk"; +} + ++ (BOOL)canShareURL +{ + return YES; +} + ++ (BOOL)canShareText +{ + return YES; +} + ++ (BOOL)canShareImage +{ + return YES; +} + + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + + +#pragma mark - +#pragma mark Authorization + +- (BOOL)isAuthorized +{ + return [self restoreAccessToken]; +} + +- (void)promptAuthorization +{ + [super promptAuthorization]; +} + +- (void)tokenAccessModifyRequest:(OAMutableURLRequest *)oRequest +{ + [oRequest setOAuthParameterName:@"oauth_verifier" withValue:[authorizeResponseQueryVars objectForKey:@"oauth_verifier"]]; +} + + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { + [self shortenURL]; + } + + else if (item.shareType == SHKShareTypeImage) + { + [self uploadImage]; + } + + else if (item.shareType == SHKShareTypeText) + { + [item setCustomValue:item.text forKey:@"status"]; + [self showPlurkForm]; + } +} + +- (void)showPlurkForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil bundle:nil delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + [item setCustomValue:form.textView.text forKey:@"status"]; + [self tryToSend]; +} + + +#pragma mark - + +- (BOOL)shortenURL +{ + NSString *bitLyLogin = SHKCONFIG(bitLyLogin); + NSString *bitLyKey = SHKCONFIG(bitLyKey); + BOOL bitLyConfigured = [bitLyLogin length] > 0 && [bitLyKey length] > 0; + + if (bitLyConfigured == NO || ![SHK connected]) + { + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title ? item.title : item.text, [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] forKey:@"status"]; + return YES; + } + + if (!quiet) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Shortening URL...")]; + + self.request = [[[SHKRequest alloc] initWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"http://api.bit.ly/v3/shorten?login=%@&apikey=%@&longUrl=%@&format=txt", + bitLyLogin, + bitLyKey, + SHKEncodeURL(item.URL) + ]] + params:nil + delegate:self + isFinishedSelector:@selector(shortenURLFinished:) + method:@"GET" + autostart:YES] autorelease]; + return NO; +} + +- (void)shortenURLFinished:(SHKRequest *)aRequest +{ + [[SHKActivityIndicator currentIndicator] hide]; + + NSString *result = [[aRequest getResult] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + + if (result == nil || [NSURL URLWithString:result] == nil) + { + // TODO - better error message + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Shorten URL Error") + message:SHKLocalizedString(@"We could not shorten the URL.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; + + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title ? item.title : item.text, [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] forKey:@"status"]; + } + + else + { + ///if already a bitly login, use url instead + if ([result isEqualToString:@"ALREADY_A_BITLY_LINK"]) + result = [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title ? item.title : item.text, result] forKey:@"status"]; + } + + [self showPlurkForm]; +} + +#pragma mark - + +- (void)uploadImage +{ + if (!quiet) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Uploading Image...")]; + + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.plurk.com/APP/Timeline/uploadPicture"] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:nil]; + [oRequest setHTTPMethod:@"POST"]; + + CGFloat compression = 0.6f; + NSData *imageData = UIImageJPEGRepresentation([item image], compression); + + // TODO + // Note from Nate to creator of sendImage method - This seems like it could be a source of sluggishness. + // For example, if the image is large (say 3000px x 3000px for example), it would be better to resize the image + // to an appropriate size (max of img.ly) and then start trying to compress. + + while ([imageData length] > 700000 && compression > 0.1) { + // NSLog(@"Image size too big, compression more: current data size: %d bytes",[imageData length]); + compression -= 0.1; + imageData = UIImageJPEGRepresentation([item image], compression); + } + + NSString *boundary = @"0XkHtMlBoUnDaRy"; + NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; + [oRequest setValue:contentType forHTTPHeaderField:@"Content-Type"]; + + NSMutableData *body = [NSMutableData data]; + + [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[@"Content-Disposition: form-data; name=\"image\"; filename=\"shk.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:imageData]; + [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + + // setting the body of the post to the reqeust + [oRequest setHTTPBody:body]; + + // Start the request + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(uploadImageTicket:didFinishWithData:) + didFailSelector:@selector(uploadImageTicket:didFailWithError:)]; + + [fetcher start]; + [oRequest release]; +} + +- (void)uploadImageTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data +{ + [[SHKActivityIndicator currentIndicator] hide]; + + if (SHKDebugShowLogs) { + SHKLog(@"Plurk Upload Picture Status Code: %d", [ticket.response statusCode]); + SHKLog(@"Plurk Upload Picture Error: %@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + } + + if (ticket.didSucceed) { + // Finished uploading Image, now need to posh the message and url in twitter + NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + NSScanner *scanner = [NSScanner scannerWithString:dataString]; + if ([scanner scanString:@"{\"full\": \"" intoString:nil]) { + NSString *urlString = nil; + [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\","] intoString:&urlString]; + urlString = [urlString stringByReplacingOccurrencesOfString:@"\\" withString:@""]; + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title, urlString] forKey:@"status"]; + [self showPlurkForm]; + } + } else { + [self alertUploadImageWithError:nil]; + } +} + +- (void)uploadImageTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error +{ + [[SHKActivityIndicator currentIndicator] hide]; + + [self alertUploadImageWithError:error]; +} + + +- (void)alertUploadImageWithError:(NSError *)error +{ + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Upload Image Error") + message:SHKLocalizedString(@"We could not upload the image.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem +{ + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + if ( ! [self validateItemAfterUserEdit]) + return NO; + + else + { + [self sendStatus]; + + // Notify delegate + [self sendDidStart]; + + return YES; + } + + return NO; +} + +- (void)sendStatus +{ + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.plurk.com/APP/Timeline/plurkAdd"] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:nil]; + + [oRequest setHTTPMethod:@"POST"]; + + OARequestParameter *qualifierParam = [[OARequestParameter alloc] initWithName:@"qualifier" + value:@"shares"]; + OARequestParameter *statusParam = [[OARequestParameter alloc] initWithName:@"content" + value:[item customValueForKey:@"status"]]; + NSArray *params = [NSArray arrayWithObjects:qualifierParam, statusParam, nil]; + [oRequest setParameters:params]; + [qualifierParam release]; + [statusParam release]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendStatusTicket:didFinishWithData:) + didFailSelector:@selector(sendStatusTicket:didFailWithError:)]; + + [fetcher start]; + [oRequest release]; +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data +{ + // TODO better error handling here + + if (ticket.didSucceed) + [self sendDidFinish]; + + else + { + if (SHKDebugShowLogs) + SHKLog(@"Plurk Send Status Error: %@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + // CREDIT: Oliver Drobnik + + NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + + // in case our makeshift parsing does not yield an error message + NSString *errorMessage = @"Unknown Error"; + + NSScanner *scanner = [NSScanner scannerWithString:string]; + + // skip until error message + [scanner scanUpToString:@"\"error\":\"" intoString:nil]; + + + if ([scanner scanString:@"\"error\":\"" intoString:nil]) + { + // get the message until the closing double quotes + [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\""] intoString:&errorMessage]; + } + + + // this is the error message for revoked access + if ([errorMessage isEqualToString:@"Invalid / used nonce"] || [errorMessage isEqualToString:@"Could not authenticate with OAuth."]) + { + [self sendDidFailWithError:[SHK error:SHKLocalizedString(@"Could not authenticate you. Please relogin.")] shouldRelogin:YES]; + } + else + { + NSError *error = [NSError errorWithDomain:@"Plurk" code:2 userInfo:[NSDictionary dictionaryWithObject:errorMessage forKey:NSLocalizedDescriptionKey]]; + [self sendDidFailWithError:error]; + } + } +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error +{ + [self sendDidFailWithError:error]; +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Error/ROError.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Error/ROError.h new file mode 100755 index 000000000..fb1cea4be --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Error/ROError.h @@ -0,0 +1,50 @@ +// +// ROError.h +// SimpleDemo +// +// Created by Winston on 11-8-15. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import + +#define kROErrorDomain @"Renren Open-platform" +#define kROUnknowDialogErrorCode 99999999 +@interface ROError : NSError{ + +} +/** + * 返回由oAuth接口返回错误信息构建的错误对象. + */ ++ (ROError*)errorWithOAuthResult:(NSDictionary*)result; + +/** + * 返回由Rest接口错误信息构建的错误对象. + */ ++ (ROError*)errorWithRestInfo:(NSDictionary*)restInfo; + + +/** + * 返回由NSError构建的错误对象. + */ ++ (ROError*)errorWithNSError:(NSError*)error; + +/** + * 构造ROError错误。 + * + * @param code 错误代码 + * @param errorMessage 错误信息 + * + * 返回错误对象. + */ ++ (ROError*)errorWithCode:(NSInteger)code errorMessage:(NSString*)errorMessage; + +/** + * 返回错误描述 + */ +- (NSString *)localizedDescription; +/** + * 返回调用Rest Api 的 method字段的值. + */ +- (NSString*)methodForRestApi; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Error/ROError.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Error/ROError.m new file mode 100755 index 000000000..4ab0e7b71 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Error/ROError.m @@ -0,0 +1,108 @@ +// +// ROError.m +// SimpleDemo +// +// Created by Winston on 11-8-15. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROError.h" + +@implementation ROError + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (ROError*)errorWithOAuthResult:(NSDictionary*)result +{ + NSNumber* errorCode = [result objectForKey:@"error"]; + NSString* errorMessage = [result objectForKey:@"error_description"]; + NSString* errorURL = [result objectForKey:@"error_url"]; + NSMutableDictionary* errorInfo = [[NSMutableDictionary alloc] initWithCapacity:2]; + if (errorCode) { + [errorInfo setObject:errorCode forKey:@"error_code"]; + } + if (errorMessage) { + [errorInfo setObject:errorMessage forKey:@"error_msg"]; + } + if (errorURL) { + [errorInfo setObject:errorURL forKey:@"error_url"]; + } + ROError* error = [ROError errorWithDomain:kROErrorDomain code:[errorCode intValue] userInfo:errorInfo]; + [errorInfo release]; + return error; +} +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (ROError*)errorWithRestInfo:(NSDictionary*)restInfo { + //TO DO:确定restInfo的获取类型 + ROError* error = nil; + NSDictionary* errorInfo = [restInfo objectForKey:@"error_response"]; + if (errorInfo) { + NSNumber* errorCode = [errorInfo objectForKey:@"error_code"]; + error = [ROError errorWithDomain:kROErrorDomain code:[errorCode intValue] userInfo:errorInfo]; + }else { + NSNumber* errorCode = [restInfo objectForKey:@"error_code"]; + error = [ROError errorWithDomain:kROErrorDomain code:[errorCode intValue] userInfo:restInfo]; + } + return error; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (ROError*)errorWithNSError:(NSError*)error { + + ROError* myError = [ROError errorWithDomain:error.domain code:error.code userInfo:error.userInfo]; + return myError; +} +/////////////////////////////////////////////////////////////////////////////////////////////////// ++ (ROError*)errorWithCode:(NSInteger)code errorMessage:(NSString*)errorMessage { + NSMutableDictionary* userInfo = [[NSMutableDictionary alloc] initWithCapacity:2]; + [userInfo setObject:[NSString stringWithFormat:@"%d", code] forKey:@"error_code"]; + if (errorMessage) { + [userInfo setObject:errorMessage forKey:@"error_msg"]; + } + + ROError* error = [ROError errorWithDomain:kROErrorDomain code:code userInfo:userInfo]; + [userInfo release]; + return error; + +} +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (id)initWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict { + if (self = [super initWithDomain:domain code:code userInfo:dict]) { + + } + return self; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString *)localizedDescription +{ + if (![self.domain isEqualToString:kROErrorDomain]) { + return [super localizedDescription]; + } + if (![self.userInfo objectForKey:@"error_msg"]) { + return @"未知错误"; + } + return [self.userInfo objectForKey:@"error_msg"]; +} +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (NSString*)methodForRestApi { + NSDictionary* userInfo = self.userInfo; + if (!userInfo) { + return nil; + } + + NSArray* requestArgs = [userInfo objectForKey:@"request_args"]; + if (!requestArgs) { + return nil; + } + + for (NSDictionary* pair in requestArgs) { + if (NSOrderedSame == [@"method" compare:[pair objectForKey:@"key"]]) { + return [pair objectForKey:@"value"]; + } + } + + return nil; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROConnect.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROConnect.h new file mode 100755 index 000000000..d7bc37db1 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROConnect.h @@ -0,0 +1,49 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#pragma mark -- RequesrParm + +#import "RORequestParam.h" +#import "ROAlbumsInfoRequestParam.h" +#import "ROCreateAlbumRequestParam.h" +#import "ROGetFriendsRequestParam.h" +#import "ROPasswordFlowRequestParam.h" +#import "ROPublishPhotoRequestParam.h" +#import "ROUserInfoRequestParam.h" + + +#pragma mark -- ResponseItem + +#import "ROResponseItem.h" +#import "ROAlbumResponseltem.h" +#import "ROCreateAlbumResponseItem.h" +#import "ROFriendResponseItem.h" +#import "ROPublishPhotoResponseItem.h" +#import "ROUserResponseItem.h" + + +#pragma mark -- Dialog + +#import "RODialogView.h" +#import "RODialogModel.h" +#import "ROPublishPhotoInternal.h" +#import "ROPublishPhotoDialogModel.h" + + +#pragma mark -- Tools + +#import "ROUtility.h" +#import "ROGlobalStyle.h" +#import "ROCloseButton.h" +#import "ROImageView.h" +#import "SBJSON.h" + + +#pragma mark -- Base + +#import "RODialog.h" +#import "RORequest.h" +#import "ROError.h" +#import "ROResponse.h" +#import "Renren.h" + diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RODialog.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RODialog.h new file mode 100755 index 000000000..982422a24 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RODialog.h @@ -0,0 +1,124 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import + +enum { + RODialogOperateSuccess, + RODialogOperateFailure, + RODialogOperateCancel +}; +typedef NSUInteger RODialogOperateType; //Dialog操作类型 + +@protocol RODialogDelegate; + +@class ROResponse; +@interface RODialog : UIView { + id _delegate; + NSMutableDictionary *_params; + NSString * _serverURL; + NSURL* _loadingURL; + UIWebView* _webView; + UIActivityIndicatorView* _spinner; + UIImageView* _iconView; + UIDeviceOrientation _orientation; + BOOL _showingKeyboard; + UIView* _modalBackgroundView; + UIButton* _cancelButton; + ROResponse* _response; + BOOL _webScaleEnlarge; +} + +@property(nonatomic, assign) id delegate; + +@property(nonatomic, retain) NSMutableDictionary *params; + +@property(nonatomic, retain) ROResponse *response; + +- (id)initWithURL:(NSString *)loadingURL params:(NSMutableDictionary *)params delegate:(id)delegate; + +-(void)errormsg:(NSString *)errorReason; + +- (void)show; + +- (void)load; + +- (void)loadURL:(NSString*)url get:(NSDictionary*)getParams; + +- (BOOL)isAuthDialog; + +////隐藏视图并通知委托成功或者取消 +//- (void)dismissWithSuccess:(BOOL)success animated:(BOOL)animated; + +//隐藏视图并通知委托出现错误 +- (void)dismissWithError:(NSError*)error animated:(BOOL)animated; + +//子类重载并在显示对话前执行 +- (void)dialogWillAppear; + +//子类重载并在隐藏对话前执行 +- (void)dialogWillDisappear; + + +- (void)dialogDidSucceed:(NSURL *)url; + + +- (void)dialogDidCancel:(NSURL *)url; +@end + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/* + * 你的应用要实现以下委托 + */ +@protocol RODialogDelegate + +@optional + +- (void)authDialog:(RODialog *)dialog withOperateType:(RODialogOperateType )operateType; + +- (void)widgetDialog:(RODialog *)dialog withOperateType:(RODialogOperateType )operateType; + +- (BOOL)dialog:(RODialog *)dialog shouldOpenURLInExternalBrowser:(NSURL *)url; + + +///** +// * dialog 成功调用. +// */ +//- (void)dialogDidComplete:(RODialog *)dialog; +// +///** +// * +// * 当dialog成功调用返回一个url时调用 +// */ +//- (void)dialogCompleteWithUrl:(NSURL *)url; +// +///** +// * +// * 当dialog 让用户取消时调用 +// */ +//- (void)dialogDidNotCompleteWithUrl:(NSURL *)url; +// +//- (void)dialogDidNotComplete:(RODialog *)dialog; +// +///** +// * 当dialog 加载时遇到错误时调用. +// */ +//- (void)dialog:(RODialog*)dialog didFailWithError:(NSError *)error; +// +// +// +//- (void)widgetDialogCompleteWithDict:(NSDictionary*)params; +// +///** +// * dialog登录授权成功执行 +// */ +//- (void)rrDialogLogin:(NSString *)token expirationDate:(NSDate *)expirationDate; +///** +// * 取消登录时执行 +// */ +//- (void)rrDialogNotLogin:(BOOL)cancelled; + + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RODialog.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RODialog.m new file mode 100755 index 000000000..7db1f3f7d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RODialog.m @@ -0,0 +1,569 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "Renren.h" +#import "ROConnect.h" +#import "ROUtility.h" +#import "RODialog.h" + + +static CGFloat kRenrenBlue[4] = {0.42578125, 0.515625, 0.703125, 1.0}; +static CGFloat kBorderGray[4] = {0.3, 0.3, 0.3, 0.8}; +static CGFloat kBorderBlack[4] = {0.3, 0.3, 0.3, 1}; +static CGFloat kBorderBlue[4] = {0.23, 0.35, 0.6, 1.0}; +static CGFloat kTransitionDuration = 0.3; +static CGFloat kPadding = 10; +static CGFloat kBorderWidth = 10; +/*static NSString* kWidgetURL = @"http://widget.renren.com/callback.html"; +static NSString* kWidgetDialogURL = @"//widget.renren.com/dialog";*/ +#define kWidgetURL @"http://widget.renren.com/callback.html" +#define kWidgetDialogURL @"//widget.renren.com/dialog" +#define kWidgetDialogUA @"1adca1369e205c22a43d9c64a2b21875" + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +BOOL RRIsDeviceIPad() { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + return YES; + } +#endif + return NO; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation RODialog + +@synthesize delegate = _delegate; +@synthesize params = _params; +@synthesize response = _response; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// private + +- (void)addRoundedRectToPath:(CGContextRef)context rect:(CGRect)rect radius:(float)radius { + CGContextBeginPath(context); + CGContextSaveGState(context); + + if (radius == 0) { + CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); + CGContextAddRect(context, rect); + } else { + rect = CGRectOffset(CGRectInset(rect, 0.5, 0.5), 0.5, 0.5); + CGContextTranslateCTM(context, CGRectGetMinX(rect)-0.5, CGRectGetMinY(rect)-0.5); + CGContextScaleCTM(context, radius, radius); + float fw = CGRectGetWidth(rect) / radius; + float fh = CGRectGetHeight(rect) / radius; + + CGContextMoveToPoint(context, fw, fh/2); + CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); + CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); + CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); + CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); + } + + CGContextClosePath(context); + CGContextRestoreGState(context); +} + +- (void)drawRect:(CGRect)rect fill:(const CGFloat*)fillColors radius:(CGFloat)radius { + CGContextRef context = UIGraphicsGetCurrentContext(); + CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); + + if (fillColors) { + CGContextSaveGState(context); + CGContextSetFillColor(context, fillColors); + if (radius) { + [self addRoundedRectToPath:context rect:rect radius:radius]; + CGContextFillPath(context); + } else { + CGContextFillRect(context, rect); + } + CGContextRestoreGState(context); + } + + CGColorSpaceRelease(space); +} + +- (void)strokeLines:(CGRect)rect stroke:(const CGFloat*)strokeColor { + CGContextRef context = UIGraphicsGetCurrentContext(); + CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); + + CGContextSaveGState(context); + CGContextSetStrokeColorSpace(context, space); + CGContextSetStrokeColor(context, strokeColor); + CGContextSetLineWidth(context, 1.0); + + { + CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y-0.5}, + {rect.origin.x+rect.size.width, rect.origin.y-0.5}}; + CGContextStrokeLineSegments(context, points, 2); + } + { + CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y+rect.size.height-0.5}, + {rect.origin.x+rect.size.width-0.5, rect.origin.y+rect.size.height-0.5}}; + CGContextStrokeLineSegments(context, points, 2); + } + { + CGPoint points[] = {{rect.origin.x+rect.size.width-0.5, rect.origin.y}, + {rect.origin.x+rect.size.width-0.5, rect.origin.y+rect.size.height}}; + CGContextStrokeLineSegments(context, points, 2); + } + { + CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y}, + {rect.origin.x+0.5, rect.origin.y+rect.size.height}}; + CGContextStrokeLineSegments(context, points, 2); + } + + CGContextRestoreGState(context); + + CGColorSpaceRelease(space); +} + +- (BOOL)shouldRotateToOrientation:(UIDeviceOrientation)orientation { + if (orientation == _orientation) { + return NO; + } else { + return orientation == UIDeviceOrientationLandscapeLeft + || orientation == UIDeviceOrientationLandscapeRight + || orientation == UIDeviceOrientationPortrait + || orientation == UIDeviceOrientationPortraitUpsideDown; + } +} + +- (CGAffineTransform)transformForOrientation { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (orientation == UIInterfaceOrientationLandscapeLeft) { + return CGAffineTransformMakeRotation(M_PI*1.5); + } else if (orientation == UIInterfaceOrientationLandscapeRight) { + return CGAffineTransformMakeRotation(M_PI/2); + } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { + return CGAffineTransformMakeRotation(-M_PI); + } else { + return CGAffineTransformIdentity; + } +} + +- (void)sizeToFitOrientation:(BOOL)transform { + if (transform) { + self.transform = CGAffineTransformIdentity; + } + + CGRect frame = [UIScreen mainScreen].applicationFrame; + CGPoint center = CGPointMake( + frame.origin.x + ceil(frame.size.width/2), + frame.origin.y + ceil(frame.size.height/2)); + + CGFloat scale_factor = 1.0f; + if (RRIsDeviceIPad()) { + // On the iPad the dialog's dimensions should only be 60% of the screen's + scale_factor = 0.6f; + } + + CGFloat width = floor(scale_factor * frame.size.width) - kPadding * 2; + CGFloat height = floor(scale_factor * frame.size.height) - kPadding * 2; + + _orientation = [UIApplication sharedApplication].statusBarOrientation; + if (UIInterfaceOrientationIsLandscape(_orientation)) { + self.frame = CGRectMake(kPadding, kPadding, height, width); + } else { + self.frame = CGRectMake(kPadding, kPadding, width, height); + } + self.center = center; + _cancelButton.frame = CGRectMake(kBorderWidth+1, self.frame.size.height - (kBorderWidth+1) - 50,self.frame.size.width - (kBorderWidth+1)*2, 50); + if (transform) { + self.transform = [self transformForOrientation]; + } +} + +- (void)updateWebOrientation { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (UIInterfaceOrientationIsLandscape(orientation)) { + [_webView stringByEvaluatingJavaScriptFromString: + @"document.body.setAttribute('orientation', 90);"]; + } else { + [_webView stringByEvaluatingJavaScriptFromString: + @"document.body.removeAttribute('orientation');"]; + } +} + +- (void)bounce1AnimationStopped { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration/2]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(bounce2AnimationStopped)]; + self.transform = CGAffineTransformScale([self transformForOrientation], 0.9, 0.9); + [UIView commitAnimations]; +} + +- (void)bounce2AnimationStopped { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration/2]; + self.transform = [self transformForOrientation]; + [UIView commitAnimations]; +} + +- (void)addObservers { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:@"UIKeyboardWillShowNotification" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:@"UIKeyboardWillHideNotification" object:nil]; +} + +- (void)removeObservers { + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIKeyboardWillShowNotification" object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIKeyboardWillHideNotification" object:nil]; +} + +- (void)postDismissCleanup { + [self removeObservers]; + [self removeFromSuperview]; + [_modalBackgroundView removeFromSuperview]; +} + +- (void)dismiss:(BOOL)animated { + [self dialogWillDisappear]; + + [_loadingURL release]; + _loadingURL = nil; + + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(postDismissCleanup)]; + self.alpha = 0; + [UIView commitAnimations]; + } else { + [self postDismissCleanup]; + } +} + +- (void)cancel { + [self dialogDidCancel:nil]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// NSObject + +- (id)init { + self = [super initWithFrame:CGRectZero]; + if (self) { + _delegate = nil; + _loadingURL = nil; + _orientation = UIDeviceOrientationUnknown; + _showingKeyboard = NO; + _webScaleEnlarge = NO; + + self.backgroundColor = [UIColor clearColor]; + self.autoresizesSubviews = YES; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.contentMode = UIViewContentModeRedraw; + + _webView = [[UIWebView alloc] initWithFrame:CGRectMake(kPadding, kPadding, 480, 480)]; + _webView.delegate = self; + _webView.backgroundColor = [ROGlobalStyle renrenPageColor]; + _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self addSubview:_webView]; + + _spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: + UIActivityIndicatorViewStyleWhiteLarge]; + _spinner.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin + | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [self addSubview:_spinner]; + _cancelButton = [[UIButton alloc] init]; + _cancelButton.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7]; + [_cancelButton setTitle:@"取消" forState:UIControlStateNormal]; + [_cancelButton addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside]; + _cancelButton.titleLabel.font = [UIFont boldSystemFontOfSize:24]; + [self addSubview:_cancelButton]; + _modalBackgroundView = [[UIView alloc] init]; + } + return self; +} + +- (void)dealloc { + _webView.delegate = nil; + [_webView release]; + [_params release]; + [_serverURL release]; + [_spinner release]; + [_loadingURL release]; + [_modalBackgroundView release]; + [_response release]; + [_cancelButton release]; + [super dealloc]; +} + +- (BOOL)isAuthDialog +{ + return [_serverURL isEqualToString:kAuthBaseURL]; +} +/////////////////////////////////////////////////////////////////////////////////////////////////// +// UIView + +- (void)drawRect:(CGRect)rect { + CGRect grayRect = CGRectOffset(rect, -0.5, -0.5); + [self drawRect:grayRect fill:kBorderGray radius:10]; + + CGRect headerRect = CGRectMake( + ceil(rect.origin.x + kBorderWidth), ceil(rect.origin.y + kBorderWidth), + rect.size.width - kBorderWidth*2,0); + [self drawRect:headerRect fill:kRenrenBlue radius:0]; + [self strokeLines:headerRect stroke:kBorderBlue]; + + CGRect webRect = CGRectMake( + ceil(rect.origin.x + kBorderWidth), headerRect.origin.y + headerRect.size.height, + rect.size.width - kBorderWidth*2, _webView.frame.size.height+1); + [self strokeLines:webRect stroke:kBorderBlack]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// UIWebViewDelegate methods +// 以下三个方法实现为UIWebViewDelegate协议方法。 +#pragma mark - UIWebViewDelegate Methods + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + NSURL *url = request.URL; + NSString *query = [url fragment]; // url中#字符后面的部分。 + if (!query) { + query = [url query]; + } + NSDictionary *params = [ROUtility parseURLParams:query]; + NSString *accessToken = [params objectForKey:@"access_token"]; + NSString *error_desc = [params objectForKey:@"error_description"]; + NSString *errorReason = [params objectForKey:@"error"]; + if(nil != errorReason) { + [self errormsg:error_desc]; +// ROError *error = [ROError errorWithCode:kROUnknowDialogErrorCode +// errorMessage:[NSString stringWithFormat:@"%@:%@",errorReason,error_desc]]; +// [self dismissWithError:error animated:YES]; + [self dialogDidCancel:nil]; + return NO; + } + if (navigationType == UIWebViewNavigationTypeLinkClicked)/*点击链接*/{ + BOOL userDidCancel = ((errorReason && [errorReason isEqualToString:@"login_denied"])||[errorReason isEqualToString:@"access_denied"]); + if(userDidCancel){ + [self dialogDidCancel:url]; + }else { + + [[UIApplication sharedApplication] openURL:request.URL]; + + } + return NO; + } + if (navigationType == UIWebViewNavigationTypeFormSubmitted) {//提交表单 + NSString *state = [params objectForKey:@"flag"]; + if ((state && [state isEqualToString:@"success"])||accessToken) { + [self dialogDidSucceed:url]; + } + } + return YES; +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + [_spinner stopAnimating]; + _spinner.hidden = YES; + _cancelButton.hidden = YES; + [self updateWebOrientation]; +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { + // 102 == WebKitErrorFrameLoadInterruptedByPolicyChange + if (!([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102)) { + [self dismissWithError:error animated:YES]; + } +} + +#pragma mark -- +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +-(void)errormsg:(NSString *)errorReason{ + if (errorReason) { + NSLog(@"%@",errorReason); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// UIDeviceOrientationDidChangeNotification + +- (void)deviceOrientationDidChange:(void*)object { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (!_showingKeyboard && [self shouldRotateToOrientation:orientation]) { + [self updateWebOrientation]; + + CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:duration]; + [self sizeToFitOrientation:YES]; + [UIView commitAnimations]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// UIKeyboardNotifications + +- (void)keyboardWillShow:(NSNotification*)notification { + + _showingKeyboard = YES; + + if (RRIsDeviceIPad()) { + // On the iPad the screen is large enough that we don't need to + // resize the dialog to accomodate the keyboard popping up + return; + } + + if (!_webScaleEnlarge) { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (UIInterfaceOrientationIsLandscape(orientation)) { + _webView.frame = CGRectInset(_webView.frame, + -(kPadding + kBorderWidth), + -(kPadding + kBorderWidth)); + } + _webScaleEnlarge = YES; + } +} + +- (void)keyboardWillHide:(NSNotification*)notification { + _showingKeyboard = NO; + + if (RRIsDeviceIPad()) { + return; + } + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (UIInterfaceOrientationIsLandscape(orientation)) { + _webView.frame = CGRectInset(_webView.frame, kPadding + kBorderWidth, kPadding + kBorderWidth) ; + } + _webScaleEnlarge = NO; +} + +- (id)initWithURL: (NSString *)serverURL params: (NSMutableDictionary *)params delegate: (id)delegate { + self = [self init]; + _serverURL = [serverURL retain]; + _params = [params retain]; + [_params setObject:kWidgetDialogUA forKey:@"ua"]; + _delegate = delegate; + + return self; +} + +- (void)load { + [self loadURL:_serverURL get:_params]; +} + +- (void)loadURL:(NSString*)url get:(NSDictionary*)getParams { + [_loadingURL release]; + _loadingURL = [[ROUtility generateURL:url params:getParams] copy]; + NSLog(@"RODialog start load URL: %@", _loadingURL); + NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:_loadingURL]; + [_webView loadRequest:request]; +} + +- (void)show { + [self load]; + [self sizeToFitOrientation:NO]; + CGFloat innerWidth = self.frame.size.width - (kBorderWidth+1)*2; + _webView.frame = CGRectMake(kBorderWidth+1, kBorderWidth, innerWidth, self.frame.size.height - (1 + kBorderWidth*2)); + + + [_spinner sizeToFit]; + [_spinner startAnimating]; + _spinner.center = _webView.center; + _cancelButton.hidden = _spinner.hidden; + UIWindow* window = [UIApplication sharedApplication].keyWindow; + if (!window) { + window = [[UIApplication sharedApplication].windows objectAtIndex:0]; + } + + _modalBackgroundView.frame = window.frame; + [_modalBackgroundView addSubview:self]; + [window addSubview:_modalBackgroundView]; + + [window addSubview:self]; + + [self dialogWillAppear]; + + self.transform = CGAffineTransformScale([self transformForOrientation], 0.001, 0.001); + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration/1.5]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(bounce1AnimationStopped)]; + self.transform = CGAffineTransformScale([self transformForOrientation], 1.1, 1.1); + [UIView commitAnimations]; + + [self addObservers]; +} + +- (void)dialogWillAppear { +} + +- (void)dialogWillDisappear { +} + +- (void)dialogDidSucceed:(NSURL *)url { + NSString *q = [url absoluteString]; + if([self isAuthDialog]) { + NSString *token = [ROUtility getValueStringFromUrl:q forParam:@"access_token"]; + NSString *expTime = [ROUtility getValueStringFromUrl:q forParam:@"expires_in"]; + NSDate *expirationDate = [ROUtility getDateFromString:expTime]; + NSDictionary *responseDic = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:token,expirationDate,nil] + forKeys:[NSArray arrayWithObjects:@"token",@"expirationDate",nil]]; + self.response = [ROResponse responseWithRootObject:responseDic]; + + if ((token == (NSString *) [NSNull null]) || (token.length == 0)) { + [self dialogDidCancel:nil]; + } else { + if ([_delegate respondsToSelector:@selector(authDialog:withOperateType:)]) { + [_delegate authDialog:self withOperateType:RODialogOperateSuccess]; + } + } + }else { + NSString *flag = [ROUtility getValueStringFromUrl:q forParam:@"flag"]; + if ([flag isEqualToString:@"success"]) { + NSString *query = [url fragment]; + if (!query) { + query = [url query]; + } + NSDictionary *params = [ROUtility parseURLParams:query]; + self.response = [ROResponse responseWithRootObject:params]; + if ([_delegate respondsToSelector:@selector(widgetDialog:withOperateType:)]) { + [_delegate widgetDialog:self withOperateType:RODialogOperateSuccess]; + } + } + } + [self dismiss:YES]; + +} + +- (void)dismissWithError:(NSError*)error animated:(BOOL)animated { + self.response = [ROResponse responseWithError:[ROError errorWithNSError:error]]; + if ([self isAuthDialog]) { + if ([_delegate respondsToSelector:@selector(authDialog:withOperateType:)]){ + [_delegate authDialog:self withOperateType:RODialogOperateFailure]; + } + }else { + if ([_delegate respondsToSelector:@selector(widgetDialog:withOperateType:)]) { + + [_delegate widgetDialog:self withOperateType:RODialogOperateFailure]; + } + } + + [self dismiss:animated]; +} + +- (void)dialogDidCancel:(NSURL *)url { + if ([self isAuthDialog]) { + if ([_delegate respondsToSelector:@selector(authDialog:withOperateType:)]){ + [_delegate authDialog:self withOperateType:RODialogOperateCancel]; + } + }else { + if ([_delegate respondsToSelector:@selector(widgetDialog:withOperateType:)]){ + [_delegate widgetDialog:self withOperateType:RODialogOperateCancel]; + } + } + + [self dismiss:YES]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RORequest.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RORequest.h new file mode 100755 index 000000000..3923ee9de --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RORequest.h @@ -0,0 +1,121 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import + +@protocol RORequestDelegate; +@protocol RORequestDebugDelegate; +@class RORequestParam; +@class ROResponse; +@class ROError; + +@interface RORequest : NSObject { + id _delegate; + id _debugDelegate; + NSString *_url; + NSString *_httpMethod; + NSMutableDictionary *_param; + NSURLConnection *_connection; + NSMutableData *_responseData; + + RORequestParam *_requestParamObject; + ROResponse *_responseObject; +} + + +@property(nonatomic, assign) id delegate; + +@property(nonatomic, assign) id debugDelegate; + +@property(nonatomic, copy) NSString *url; + +@property(nonatomic, copy) NSString *httpMethod; + +@property(nonatomic, retain) NSMutableDictionary *params; + +@property(nonatomic, assign) NSURLConnection *connection; + +@property(nonatomic, assign) NSMutableData *responseData; + +@property(nonatomic, retain) RORequestParam *requestParamObject; + +@property(nonatomic, retain) ROResponse *responseObject; + +//新的接口。 ++ (RORequest *)getRequestWithParam:(RORequestParam *)param httpMethod:(NSString *)httpMethod delegate:(id)delegate requestURL:(NSString *)url; +//旧的接口。 ++ (RORequest *)getRequestWithParams:(NSMutableDictionary *)params httpMethod:(NSString *)httpMethod delegate:(id)delegate requestURL:(NSString *)url; +//////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ (id)getRequestSessionKeyWithParams:(NSString *)url; + ++ (NSString*)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params; + + ++ (NSString*)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params httpMethod:(NSString *)httpMethod; +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)isKindOfUIImage; + +- (BOOL) loading; + +- (void) connect; + +@end + +//////////////////////////////////////////////////////////////////////////////// +/* + * RORequestDelegate protocol definition. + */ +@protocol RORequestDelegate + +@optional + +/** + * 请求发送给服务器之前调用。 + */ +- (void)requestLoading:(RORequest *)request; + +/** + * 服务器回应后准备再次发送数据时调用。 + */ +- (void)request:(RORequest *)request didReceiveResponse:(NSURLResponse *)response; + +/** + * 错误使请求无法成功时调用。旧方法,为保持兼容存在。 + */ +- (void)request:(RORequest *)request didFailWithError:(NSError *)error; + +/** + * 当收到回应回应并解析为对象后应用。 + * + * 结果对应可以是dictionary,array,string,number,依赖于API返回的数据。 + */ +- (void)request:(RORequest *)request didLoad:(id)result; + +/** + * 请求取消的时候调用。 + */ +- (void)request:(RORequest *)request didLoadRawResponse:(NSData *)data; + +/** + * 服务器返回错误或NSConnection delegate方法返回错误时调用。 + */ +- (void)request:(RORequest *)request didFailWithROError:(ROError *)error; + +@end + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * RORequestDebugDelegate protocol definition. + * 只能在调试时使用。 + */ +@protocol RORequestDebugDelegate + +- (void)requestToServer:(NSString *)requestParam forMethod:(NSString *)methodName; +- (void)responseFormServer:(NSString *)response forMethod:(NSString *)methodName; +- (void)otherErrors:(NSString *)errorDescription forMethod:(NSString *)methodName; + +@end + + diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RORequest.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RORequest.m new file mode 100755 index 000000000..c1a7f5fe3 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RORequest.m @@ -0,0 +1,365 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "RORequest.h" +#import "ROResponse.h" +#import "JSON.h" +#import "RORequestParam.h" +#import "ROError.h" +#import "ROUtility.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// global + +static NSString* kUserAgent = @"Renren iOS SDK v2.0"; +static NSString* kStringBoundary = @"3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3"; +static const int kGeneralErrorCode = 10000; + +static const NSTimeInterval kTimeoutInterval = 60.0; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +@interface RORequest(Private) + +- (NSMutableData *)generatePostBody; + +- (id)parseJsonResponse:(NSData *)data error:(NSError **)error; + +- (void)handleResponseData:(NSData *)data; + +@end +/////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation RORequest + +@synthesize delegate = _delegate; +@synthesize debugDelegate = _debugDelegate; +@synthesize url = _url; +@synthesize httpMethod = _httpMethod; +@synthesize params = _params; +@synthesize connection = _connection; +@synthesize responseData = _responseData; +@synthesize requestParamObject = _requestParamObject; +@synthesize responseObject = _responseObject; + +/** + * Free internal structure + */ +- (void)dealloc { + [_connection cancel]; + [_connection release]; + [_responseData release]; + [_url release]; + [_httpMethod release]; + [_params release]; + [_requestParamObject release]; + [_responseObject release]; + [super dealloc]; +} + +////////////////////////////////////////////////////////////////////////////////////////////////// +// class public +// 新的接口。 ++ (RORequest *)getRequestWithParam:(RORequestParam *)param httpMethod:(NSString *)httpMethod delegate:(id)delegate requestURL:(NSString *)url{ + RORequest* request = [[[RORequest alloc] init] autorelease]; + request.delegate = delegate; + request.url = url; + request.httpMethod = httpMethod; + request.requestParamObject = param; + request.params = [param requestParamToDictionary]; + request.connection = nil; + request.responseData = nil; + request.responseObject = nil; + return request; +} + +//旧的接口。 ++ (RORequest *)getRequestWithParams:(NSMutableDictionary *)params httpMethod:(NSString *)httpMethod delegate:(id)delegate requestURL:(NSString *)url{ + RORequest* request = [[[RORequest alloc] init] autorelease]; + request.delegate = delegate; + request.url = url; + request.httpMethod = httpMethod; + request.params = params; + request.requestParamObject = [[[RORequestParam alloc] init] autorelease]; + request.connection = nil; + request.responseData = nil; + request.responseObject = nil; + return request; +} + + +#pragma mark - methods for one purpose - +/////////////////////////////////////////////////////////////////////////////////////////////////// +//下面三个方法。 ++ (NSString *)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params{ + return [self serializeURL:baseUrl params:params httpMethod:@"GET"]; +} + +/** + * Generate get URL + */ ++ (NSString*)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params httpMethod:(NSString *)httpMethod{ + NSURL* parsedURL = [NSURL URLWithString:baseUrl]; + NSString* queryPrefix = parsedURL.query ? @"&" : @"?"; + + NSMutableArray* pairs = [NSMutableArray array]; + for (NSString* key in [params keyEnumerator]) { + if (([[params valueForKey:key] isKindOfClass:[UIImage class]]) + ||([[params valueForKey:key] isKindOfClass:[NSData class]])) { + if ([httpMethod isEqualToString:@"GET"]) { + NSLog(@"can not use GET to upload a file"); + } + continue; + } + + NSString* escaped_value = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,/* allocator */ (CFStringRef)[params objectForKey:key], NULL, /* charactersToLeaveUnescaped */ (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8); + + [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, escaped_value]]; + [escaped_value release]; + } + NSString* query = [pairs componentsJoinedByString:@"&"]; + + return [NSString stringWithFormat:@"%@%@%@", baseUrl, queryPrefix, query]; +} + ++ (id)getRequestSessionKeyWithParams:(NSString *)url { + NSURL* sessionKeyURL = [NSURL URLWithString:url]; + NSData *data=[NSData dataWithContentsOfURL:sessionKeyURL]; + NSString* responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + SBJSON *jsonParser = [[SBJSON new] autorelease]; + id result = [jsonParser objectWithString:responseString]; + return result; +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Formulate the NSError + */ +- (NSError *)formError:(NSInteger)code userInfo:(NSDictionary *)errorData{ + return [NSError errorWithDomain:@"renrenErrDomain" code:code userInfo:errorData]; +} + + +/* + * private helper function: call the delegate function when the request + * fails with error + */ +- (void)failWithError:(NSError *)error { + if([_delegate respondsToSelector:@selector(request:didFailWithROError:)]){ + if (nil == self.responseObject || nil == self.responseObject.error) { + [_delegate request:self didFailWithROError:[ROError errorWithNSError:error]]; + }else{ + [_delegate request:self didFailWithROError:self.responseObject.error]; + } + return; + }else if([_delegate respondsToSelector:@selector(request:didFailWithError:)]) { + [_delegate request:self didFailWithError:error]; + } +} + + + +////////////////////////////////////////////////////////////////////////////////////////////////// +// public + +- (BOOL)loading { + return !!_connection; +} + + +- (void)connect{ + if ([_delegate respondsToSelector:@selector(requestLoading:)]) { + [_delegate requestLoading:self]; + } + + NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:kTimeoutInterval]; + + [urlRequest setHTTPMethod:self.httpMethod]; + UIDevice *device = [UIDevice currentDevice]; + NSString *ua = [NSString stringWithFormat:@"%@ (%@; %@ %@)",kUserAgent,device.model,device.systemName,device.systemVersion]; + [urlRequest setValue:ua forHTTPHeaderField:@"User-Agent"]; + if ([self isKindOfUIImage]) { + NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kStringBoundary]; + [urlRequest setValue:contentType forHTTPHeaderField:@"Content-Type"]; + } + [urlRequest setHTTPBody:[self generatePostBody]]; + if (_debugDelegate && [_debugDelegate respondsToSelector:@selector(requestToServer:forMethod:)] && self.requestParamObject) { + [_debugDelegate requestToServer:[_params description] forMethod:self.requestParamObject.method]; + } + /* + NSString* responseString = [[[NSString alloc] initWithData:[self generatePostBody] + encoding:NSUTF8StringEncoding] + autorelease]; + NSLog(@"======:%@",responseString); + */ + //NSLog(@"Here's the request headers: %@", [urlRequest allHTTPHeaderFields]); + //NSLog(@"Here's the request body: %@", [urlRequest HTTPBody]); + _connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self]; +} + +-(BOOL)isKindOfUIImage{ + NSString *iskind=nil; + for (NSString *key in [_params keyEnumerator]) { + if ([key isEqualToString:@"upload"]) { + iskind=key; + break; + } + } + return iskind!=nil; +} + + +#pragma mark - NSURLConnectionDelegate methods - +////////////////////////////////////////////////////////////////////////////////////////////////// +// NSURLConnectionDelegate + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + _responseData = [[NSMutableData alloc] init]; + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + + if([_delegate respondsToSelector:@selector(request:didReceiveResponse:)]) { + [_delegate request:self didReceiveResponse:httpResponse]; + } +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + [_responseData appendData:data]; +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse{ + return nil; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + [self handleResponseData:_responseData]; + + [_responseData release]; + _responseData = nil; + [_connection release]; + _connection = nil; +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + [self failWithError:error]; + if(_debugDelegate && [_debugDelegate respondsToSelector:@selector(otherErrors:forMethod:)] && self.requestParamObject){ + [_debugDelegate otherErrors:[error localizedDescription] forMethod:self.requestParamObject.method]; + } + + [_responseData release]; + _responseData = nil; + [_connection release]; + _connection = nil; +} + +#pragma mark - Private Methods - +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// private methods +/* + * private helper function: handle the response data + */ +- (void)handleResponseData:(NSData *)data{ + if([_delegate respondsToSelector:@selector(request:didLoadRawResponse:)]){ + [_delegate request:self didLoadRawResponse:data]; + } + + if([_delegate respondsToSelector:@selector(request:didLoad:)] || [_delegate respondsToSelector:@selector(request:didFailWithError:)]){ + NSError* error = nil; + id result = [self parseJsonResponse:data error:&error]; + if(_debugDelegate && [_debugDelegate respondsToSelector:@selector(responseFormServer:forMethod:)] && self.requestParamObject) { + [_debugDelegate responseFormServer:[result description] forMethod:self.requestParamObject.method]; + } + if(error){ + [self failWithError:error]; + }else if([_delegate respondsToSelector:@selector(request:didLoad:)]){ + [_delegate request:self didLoad:(result == nil ? data : result)]; + } + } +} + +/** + * 解析返回的data, 只有handleResponseData函数调用. + */ +- (id)parseJsonResponse:(NSData *)data error:(NSError **)error{ + + NSString* responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + NSLog(@"Here's the response string: %@", responseString); + SBJSON *jsonParser = [[SBJSON new] autorelease]; + if ([responseString isEqualToString:@"true"]) { + return [NSDictionary dictionaryWithObject:@"true" forKey:@"result"]; + }else if([responseString isEqualToString:@"false"]) { + if(error != nil){ + *error = [self formError:kGeneralErrorCode userInfo:[NSDictionary dictionaryWithObject:@"This operation cann't be completed!" forKey:@"error_msg"]]; + } + return nil; + } + + + id result = [jsonParser objectWithString:responseString]; + + self.responseObject = [self.requestParamObject requestResultToResponse:result]; + self.responseObject.param = self.requestParamObject; + if (![result isKindOfClass:[NSArray class]]) { + if([result objectForKey:@"error"] != nil){ + if (error != nil) { + *error = [self formError:kGeneralErrorCode userInfo:result]; + } + return nil; + } + + if ([result objectForKey:@"error_code"] != nil) { + if (error != nil) { + *error = [self formError:[[result objectForKey:@"error_code"] intValue] userInfo:result]; + } + return nil; + } + + if ([result objectForKey:@"error_msg"] != nil) { + if (error != nil) { + *error = [self formError:kGeneralErrorCode userInfo:result]; + } + } + + if ([result objectForKey:@"error_reason"] != nil) { + if (error != nil) { + *error = [self formError:kGeneralErrorCode userInfo:result]; + } + } + } + + return result; +} + +- (NSMutableData *)generatePostBody { + NSMutableData *body = [NSMutableData data]; + NSString *endLine = [NSString stringWithFormat:@"\r\n--%@\r\n", kStringBoundary]; + NSMutableArray *pairs = [NSMutableArray array]; + if ([self isKindOfUIImage]) { + [body appendData:[[NSString stringWithFormat:@"--%@\r\n", kStringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; + for(NSString *key in [_params keyEnumerator]){ + if ([key isEqualToString:@"upload"]) { + continue; + } + [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name = \"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[_params valueForKey:key] dataUsingEncoding:NSUTF8StringEncoding]]; + + [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]]; + } + NSData *_dataParam=[_params valueForKey:@"upload"]; + NSData *imageData = UIImagePNGRepresentation((UIImage*)_dataParam); + [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"upload\";filename=no.jpg"] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[endLine dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithString:@"Content-Type:image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:imageData]; + [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", kStringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; + }else { + for (NSString* key in [_params keyEnumerator]) { + NSString* value = [_params objectForKey:key]; + NSString* value_str = [ROUtility encodeString:value urlEncode:NSUTF8StringEncoding]; + [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, value_str]]; + } + NSString* params = [pairs componentsJoinedByString:@"&"]; + [body appendData:[params dataUsingEncoding:NSUTF8StringEncoding]]; + } + return body; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROResponse.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROResponse.h new file mode 100755 index 000000000..ea140d8d1 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROResponse.h @@ -0,0 +1,42 @@ +// +// ROResponse.h +// SimpleDemo +// +// Created by Winston on 11-8-16. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import + +@class ROError; +@class RORequestParam; +@interface ROResponse : NSObject{ + id _rootObject; + ROError *_error; + RORequestParam *_param; +} +/** + * 接口返回的正确处理对象 + * 对象类型:ROResponseItem | NSArray + * 请调用者自行判断。 + */ +@property(nonatomic, retain)id rootObject; +/** + * 接口返回的错误对象. + */ +@property(nonatomic, retain)ROError *error; +/** + * 接口请求的参数对象 + * 用于调用者判断是那个接口返回的response; + */ +@property(nonatomic, retain)RORequestParam *param; +/** + * 返回由Rest接口正确信息构建的Response对象. + */ ++(ROResponse *)responseWithRootObject:(id)rootObject; +/** + * 返回由Rest接口错误信息构建的Response对象. + */ ++(ROResponse *)responseWithError:(ROError *)error; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROResponse.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROResponse.m new file mode 100755 index 000000000..608183604 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ROResponse.m @@ -0,0 +1,50 @@ +// +// ROResponse.m +// SimpleDemo +// +// Created by Winston on 11-8-16. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROResponse.h" + +@implementation ROResponse + +@synthesize rootObject = _rootObject; +@synthesize error = _error; +@synthesize param = _param; +- (id)init +{ + self = [super init]; + if (self) { + // Initialization code here. + } + + return self; +} + +-(void)dealloc +{ + [_rootObject release]; + [_error release]; + [_param release]; + [super dealloc]; +} + ++(ROResponse *)responseWithRootObject:(id)rootObject +{ + ROResponse *response = [[self alloc] init]; + response.rootObject = rootObject; + return [response autorelease]; + +} + ++(ROResponse *)responseWithError:(ROError *)error +{ + ROResponse *response = [[self alloc] init]; + response.error = error; + return [response autorelease]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/bottom-bar.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/bottom-bar.png new file mode 100755 index 000000000..e74ebda76 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/bottom-bar.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/bottom-bar@2x.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/bottom-bar@2x.png new file mode 100755 index 000000000..0d68a2e0c Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/bottom-bar@2x.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/head-frame.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/head-frame.png new file mode 100644 index 000000000..f72aa470a Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/head-frame.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/head-frame@2x.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/head-frame@2x.png new file mode 100644 index 000000000..e68fcad9a Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/head-frame@2x.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/input-frame.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/input-frame.png new file mode 100755 index 000000000..762ad8b37 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/input-frame.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/input-frame@2x.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/input-frame@2x.png new file mode 100755 index 000000000..ffc7249b4 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/input-frame@2x.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/photo-frame.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/photo-frame.png new file mode 100755 index 000000000..db79c56f5 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/photo-frame.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/photo-frame@2x.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/photo-frame@2x.png new file mode 100644 index 000000000..86516fef0 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/photo-frame@2x.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/renren-logo-top-bar.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/renren-logo-top-bar.png new file mode 100755 index 000000000..bd4abc0d8 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/renren-logo-top-bar.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/renren-logo-top-bar@2x.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/renren-logo-top-bar@2x.png new file mode 100644 index 000000000..be3b4cb1b Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/renren-logo-top-bar@2x.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/small-button-normal.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/small-button-normal.png new file mode 100755 index 000000000..e9eb8b65d Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/small-button-normal.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/small-button-normal@2x.png b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/small-button-normal@2x.png new file mode 100755 index 000000000..8d00cd882 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RRConnect.bundle/small-button-normal@2x.png differ diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Renren.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Renren.h new file mode 100755 index 000000000..b4ab773cf --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Renren.h @@ -0,0 +1,229 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "RODialog.h" +#import "ROResponse.h" +#import "RORequest.h" +#import "ROAlbumsInfoRequestParam.h" +#import "ROCreateAlbumRequestParam.h" +#import "ROUserInfoRequestParam.h" +#import "ROPasswordFlowRequestParam.h" +#import "ROGetFriendsRequestParam.h" +#import "ROPublishPhotoRequestParam.h" +#import "ROGetFriendsInfoRequestParam.h" +#import "SHKConfiguration.h" + + +#define kAuthBaseURL @"http://graph.renren.com/oauth/authorize" +#define kDialogBaseURL @"http://widget.renren.com/dialog/" +#define kRestserverBaseURL @"http://api.renren.com/restserver.do" +#define kRRSessionKeyURL @"http://graph.renren.com/renren_api/session_key" +#define kRRSuccessURL @"http://widget.renren.com/callback.html" +#define kSDKversion @"2.0" +#define kPasswordFlowBaseURL @"https://graph.renren.com/oauth/token" + + +@protocol RenrenDelegate; +@protocol RORequestDelegate; +@protocol RODialogDelegate; + +@class RORequest; +@class ROPublishPhotoRequestParam; +@class ROPasswordFlowRequestParam; + +@interface Renren: NSObject { + NSString *_accessToken; + NSString *_secret; + NSString *_sessionKey; + NSDate *_expirationDate; + NSString *_createTime; + RORequest *_request; + RODialog *_rrDialog; + NSString *_appId; + NSString *_appKey; + NSArray *_permissions; + id _renrenDelegate; +} + +@property(nonatomic, copy) NSString *accessToken; + +@property(nonatomic, copy) NSString *secret; + +@property(nonatomic, copy) NSString *sessionKey; + +@property(nonatomic, copy) NSDate *expirationDate; + +@property(nonatomic, copy) NSString *appKey; + +@property(nonatomic, copy) NSString *appId; + +@property(nonatomic, assign) id renrenDelegate; + +@property(nonatomic, retain) NSArray *permissions; + +#pragma mark - Initialization - + +/* + * 获取静态、共享的Renren实例对象。Renren类的单例方法。 + * @return 返回共享的Renren单例对象。 + */ ++ (Renren *)sharedRenren; + +/* + * 获取新的Renren实例对象。Renren类的工厂方法。 + * 需要自行控制Renren对象的生命周期以保证调用的完成 + * @return 返回Renren类实例。 + */ ++ (Renren *)newRenRen; + +#pragma mark - General Public Methods - + +/* + * 判断用户登录后的当前会话生命周期是否有效。 + * @return 当前session有效,返回YES,否则, NO. + */ +-(BOOL)isSessionValid; + + +#pragma mark - Authorize & Logout - + +/** + * 授权页面方式获取授权 + * @param permissions 需要开通的权限字符串数组。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +- (void)authorizationWithPermisson:(NSArray *)permissions andDelegate:(id)delegate; + +/** + * 使用password flow方式获取授权 + * @param param 用户密码认证方式的ROPasswordFlowRequestParam对象 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +- (void)passwordFlowAuthorizationWithParam:(ROPasswordFlowRequestParam *)param andDelegate:(id)delegate; + +/** + * 用户登出时调用本方法。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +- (void)logout:(id)delegate; + +#pragma mark - Customlized API Request Methods - + +/* + * 通过组装传入的params字典中包含的信息,向服务器对应接口发出请求。 + * @param param 包含接口请求参数的字典对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +- (RORequest *)requestWithParams:(NSMutableDictionary *)params andDelegate:(id )delegate; + +/** + * 调用指定的widget dialog.通过widget Dialog的方式使用SDK. + * @param action 通过dialog调用的接口标记字符串。 + * @param params 接口调用参数字典对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +- (void)dialog:(NSString *)action andParams:(NSMutableDictionary *)params andDelegate:(id )delegate; + +#pragma mark - One-Click API Function Methods - + +/** + * 一键发布照片流程方法 + * @param image 准备上传图片对象 + * @param caption 照片的描述 + * @return 一键上传图片界面所用视图 + */ +-(void)publishPhotoSimplyWithImage:(UIImage *)image caption:(NSString *)caption; + +#pragma mark - Packaged API Function Methods - + +/** + * 创建相册,返回新相册的相关信息 + * @param param包含接口参数所需数据成员的ROCreateAlbumRequestParam对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +-(void)createAlbum:(ROCreateAlbumRequestParam *)param andDelegate:(id)delegate; + +/** + * 获取相册信息,可以返回全部相册列表,也可指定相册id + * @param param包含接口参数所需数据成员的ROAlbumsInfoRequestParam对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +-(void)getAlbums:(ROAlbumsInfoRequestParam *)param andDelegate:(id)delegate; + +/** + * 获取用户详细信息,可以指定多个用户id + * @param param包含接口参数所需数据成员的ROUserInfoRequestParam对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +-(void)getUsersInfo:(ROUserInfoRequestParam *)param andDelegate:(id)delegate; + +/** + * 上传照片,默认上传至“快速上传”相册。 + * @param param包含接口参数所需数据成员的ROPublishPhotoRequestParam对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +-(void)publishPhoto:(ROPublishPhotoRequestParam *)param andDelegate:(id)delegate; + +/** + * 获取好友id列表 + * @param param包含接口参数所需数据成员的ROGetFriendsRequestParam对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +-(void)getFriends:(ROGetFriendsRequestParam *)param andDelegate:(id)delegate; + +/** + * 获取好友详细信息 + * @param param包含接口参数所需数据成员的ROGetFriendsInfoRequestParam对象。 + * @param delegate 实现RenrenDelegate协议的类型对象。 + */ +-(void)getFriendsInfo:(ROGetFriendsInfoRequestParam *)param andDelegate:(id)delegate; + + +@end + +/** + * Renren的代理协议,包含了各种接口回调方法。 + * 如需要接收接口返回数据或实现自定义错误处理过程,请实现此协议。 + */ +@protocol RenrenDelegate + +@optional + +/** + * 接口请求成功,第三方开发者实现这个方法 + * @param renren 传回代理服务器接口请求的Renren类型对象。 + * @param response 传回接口请求的响应。 + */ +- (void)renren:(Renren *)renren requestDidReturnResponse:(ROResponse*)response; + +/** + * 接口请求失败,第三方开发者实现这个方法 + * @param renren 传回代理服务器接口请求的Renren类型对象。 + * @param response 传回接口请求的错误对象。 + */ +- (void)renren:(Renren *)renren requestFailWithError:(ROError*)error; + +/** + * renren取消Dialog时调用,第三方开发者实现这个方法 + * @param renren 传回代理授权登录接口请求的Renren类型对象。 + */ +- (void)renrenDialogDidCancel:(Renren *)renren; +/** + * 授权登录成功时被调用,第三方开发者实现这个方法 + * @param renren 传回代理授权登录接口请求的Renren类型对象。 + */ +- (void)renrenDidLogin:(Renren *)renren; + +/** + * 用户登出成功后被调用 第三方开发者实现这个方法 + * @param renren 传回代理登出接口请求的Renren类型对象。 + */ +- (void)renrenDidLogout:(Renren *)renren; + +/** + * 授权登录失败时被调用,第三方开发者实现这个方法 + * @param renren 传回代理授权登录接口请求的Renren类型对象。 + */ +- (void)renren:(Renren *)renren loginFailWithError:(ROError*)error; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Renren.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Renren.m new file mode 100755 index 000000000..45fadef4c --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Renren.m @@ -0,0 +1,646 @@ +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import "ROConnect.h" +#import "JSON.h" +#import "ROCreateAlbumResponseItem.h" +#import "ROUserResponseItem.h" +#import "ROUtility.h" +#import "ROPublishPhotoRequestParam.h" +#import "RODialog.h" +#import "RORequest.h" +#import "Renren.h" + +@interface Renren(Private) + +- (void)setGeneralRequestArgs:(RORequestParam *)inRequestParam; + +- (void)getLoggedInUserId; +// 新方法。 +- (void)sendRequestWithUrl:(NSString *)url param:(RORequestParam *)param httpMethod:(NSString *)httpMethod delegate:(id)delegate; + +// 旧方法。 +- (RORequest*)openUrl:(NSString *)url params:(NSMutableDictionary *)params httpMethod:(NSString *)httpMethod delegate:(id)delegate; + +- (NSString *)getSecretKeyByToken:(NSString *)token; +- (NSString *)getSessionKeyByToken:(NSString *)token; + + +/** + * 删除当前用户登录状态 + */ +- (void)delUserSessionInfo; + +- (void)authorizeWithRRAppAuth:(BOOL)tryRRAppAuth safariAuth:(BOOL)trySafariAuth; + +@end + +@implementation Renren + +@synthesize accessToken = _accessToken; +@synthesize expirationDate = _expirationDate; +@synthesize secret=_secret; +@synthesize sessionKey=_sessionKey; +@synthesize appKey = _appKey; +@synthesize appId = _appId; +@synthesize renrenDelegate = _renrenDelegate; +@synthesize permissions = _permissions; + + +#pragma mark - Construction & Destruction - + +static Renren *sharedRenren = nil; + +/** + * Override NSObject : release the data members. + */ +- (void)dealloc { + [_accessToken release]; + [_expirationDate release]; + [_request release]; + [_rrDialog release]; + [_appId release]; + self.appKey = nil; + [_secret release]; + [_permissions release]; + [_sessionKey release]; + [super dealloc]; +} + ++ (Renren *)newRenRen{ + Renren *newRenrenObject = [[Renren alloc] init]; + [newRenrenObject isSessionValid]; + newRenrenObject.appKey = SHKCONFIG(renrenConsumerKey); + newRenrenObject.appId = SHKCONFIG(renrenAppId); + return [newRenrenObject autorelease]; +} + ++ (Renren *)sharedRenren { + if (!sharedRenren) { + sharedRenren = [[Renren alloc] init]; + [sharedRenren isSessionValid]; + sharedRenren.appKey = SHKCONFIG(renrenConsumerKey); + sharedRenren.appId = SHKCONFIG(renrenAppId); + } + return sharedRenren; +} + +#pragma mark - General Public Methods - + +-(BOOL)isSessionValid{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + if (nil != defaults){ + self.accessToken = [defaults objectForKey:@"access_Token"]; + self.expirationDate = [defaults objectForKey:@"expiration_Date"]; + self.sessionKey = [defaults objectForKey:@"session_Key"]; + self.secret = [defaults objectForKey:@"secret_Key"]; + } + return (self.accessToken != nil && self.expirationDate != nil && self.sessionKey != nil && NSOrderedDescending == [self.expirationDate compare:[NSDate date]]); +} + + +#pragma mark - Private Methods - + +/** + * 保存用户经oauth 2.0登录后的信息,到UserDefaults中。 + */ +-(void)saveUserSessionInfo{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + if (self.accessToken) { + [defaults setObject:self.accessToken forKey:@"access_Token"]; + } + if (self.expirationDate) { + [defaults setObject:self.expirationDate forKey:@"expiration_Date"]; + } + if (self.sessionKey) { + [defaults setObject:self.sessionKey forKey:@"session_Key"]; + [defaults setObject:self.secret forKey:@"secret_Key"]; + } + + [defaults synchronize]; +} + +/** + * 删除UserDefaults中保存的用户oauth 2.0信息 + */ +-(void)delUserSessionInfo{ + NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; + [defaults removeObjectForKey:@"access_Token"]; + [defaults removeObjectForKey:@"secret_Key"]; + [defaults removeObjectForKey:@"session_Key"]; + [defaults removeObjectForKey:@"expiration_Date"]; + [defaults removeObjectForKey:@"session_UserId"]; + NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray* graphCookies = [cookies cookiesForURL: + [NSURL URLWithString:@"http://graph.renren.com"]]; + + for (NSHTTPCookie* cookie in graphCookies) { + [cookies deleteCookie:cookie]; + } + NSArray* widgetCookies = [cookies cookiesForURL:[NSURL URLWithString:@"http://widget.renren.com"]]; + + for (NSHTTPCookie* cookie in widgetCookies) { + [cookies deleteCookie:cookie]; + } + [defaults synchronize]; +} + +- (void)getLoggedInUserId{ + NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; + if ([defaults objectForKey:@"session_UserId"]) { + return; + } + RORequestParam * param = [[[RORequestParam alloc] init] autorelease]; + param.method = @"users.getLoggedInUser"; + [self requestWithParam:param andDelegate:self]; + +} +// 新的接口。 +- (void)sendRequestWithUrl:(NSString *)url param:(RORequestParam *)param httpMethod:(NSString *)httpMethod delegate:(id)delegate{ + [_request release]; + + delegate = delegate?delegate:self; + _request = [[RORequest getRequestWithParam:param httpMethod:httpMethod delegate:delegate requestURL:url] retain]; + [_request connect]; + return; +} + +// 旧的接口 +- (RORequest*)openUrl:(NSString *)url params:(NSMutableDictionary *)params httpMethod:(NSString *)httpMethod delegate:(id)delegate{ + [_request release]; + + delegate = delegate?delegate:self; + _request = [[RORequest getRequestWithParams:params httpMethod:httpMethod delegate:delegate requestURL:url] retain]; + [_request connect]; + return _request; +} + +- (void)requestWithParam:(RORequestParam *)param andDelegate:(id )delegate { + if (nil == param.method || [param.method length] <= 0) { + NSLog(@"API Method must be specified"); + return; + } + + if (![self isSessionValid]) { + NSLog(@"Session is not valid! Request abort!!"); + return; + } + + [self setGeneralRequestArgs:param]; + + [self sendRequestWithUrl:kRestserverBaseURL param:param httpMethod:@"POST" delegate:delegate]; + + return; +} + +#pragma mark - RODialogDelegate Methods - + +- (void)authDialog:(RODialog *)dialog withOperateType:(RODialogOperateType )operateType{ + if (dialog != _rrDialog) { + return; + } + NSDictionary* authDictionary = nil; + ROError* authError = nil; + switch (operateType) { + case RODialogOperateSuccess: + authDictionary = (NSDictionary *)dialog.response.rootObject; + NSString* token = [authDictionary objectForKey:@"token"]; + NSDate* expirationDate = [authDictionary objectForKey:@"expirationDate"]; + self.accessToken = token; + self.expirationDate = expirationDate; + self.secret=[self getSecretKeyByToken:token]; + self.sessionKey=[self getSessionKeyByToken:token]; + //用户信息保存到本地 + [self saveUserSessionInfo]; + [self getLoggedInUserId]; + if ([_renrenDelegate respondsToSelector:@selector(renrenDidLogin:)]) { + [_renrenDelegate renrenDidLogin:self]; + } + break; + case RODialogOperateFailure: + authError = dialog.response.error; + if ([_renrenDelegate respondsToSelector:@selector(renren:loginFailWithError:)]) { + [_renrenDelegate renren:self loginFailWithError:authError]; + } + break; + default: + if ([_renrenDelegate respondsToSelector:@selector(renrenDialogDidCancel:)]) { + [_renrenDelegate renrenDialogDidCancel:self]; + } + break; + } + +} + +- (void)widgetDialog:(RODialog *)dialog withOperateType:(RODialogOperateType )operateType{ + if (dialog != _rrDialog) { + return; + } + switch (operateType) { + case RODialogOperateSuccess: + if ([_renrenDelegate respondsToSelector:@selector(renren:requestDidReturnResponse:)]) { + [_renrenDelegate renren:self requestDidReturnResponse:dialog.response]; + } + break; + case RODialogOperateFailure: + if([_renrenDelegate respondsToSelector:@selector(renren:requestFailWithError:)]){ + [_renrenDelegate renren:self requestFailWithError:dialog.response.error]; + } + break; + default: + if ([_renrenDelegate respondsToSelector:@selector(renrenDialogDidCancel:)]) { + [_renrenDelegate renrenDialogDidCancel:self]; + } + break; + } +} + +#pragma mark - Util Methods - +/* + * 用于设置通用的一些参数到param对象中。 + */ +-(void)setGeneralRequestArgs: (RORequestParam *)inRequestParam{ + // 这里假设此前已经调用[self isSessionValid],并且返回Ture。 + inRequestParam.sessionKey = self.sessionKey; + inRequestParam.apiKey = self.appKey; + inRequestParam.callID = [ROUtility generateCallId]; + inRequestParam.xn_ss = @"1"; + inRequestParam.format = @"json"; + inRequestParam.apiVersion = kSDKversion; + + inRequestParam.sig = [ROUtility generateSig:[inRequestParam requestParamToDictionary] secretKey:self.secret]; +} + +/** + * 用accesstoken 获取调用api 时用到的参数session_secret + */ +-(NSString *)getSecretKeyByToken:(NSString *)token{ + NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: + token, @"oauth_token", + nil]; + NSString *getKeyUrl = [RORequest serializeURL:kRRSessionKeyURL params:params]; + id result = [RORequest getRequestSessionKeyWithParams:getKeyUrl]; + if ([result isKindOfClass:[NSDictionary class]]) { + NSString* secretkey=[[result objectForKey:@"renren_token"] objectForKey:@"session_secret"]; + return secretkey; + } + return nil; +} + +/** + * 用accesstoken 获取调用api 时用到的参数session_key + */ +-(NSString *)getSessionKeyByToken:(NSString *)token{ + NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: + token, @"oauth_token", + nil]; + NSString *getKeyUrl = [RORequest serializeURL:kRRSessionKeyURL params:params]; + id result = [RORequest getRequestSessionKeyWithParams:getKeyUrl]; + if ([result isKindOfClass:[NSDictionary class]]) { + NSString* sessionkey=[[result objectForKey:@"renren_token"] objectForKey:@"session_key"]; + return sessionkey; + } + return nil; +} + + +#pragma mark - Authorize & Logout - + +/* + * 用户oauth2登录请求认证授权 + */ +- (void)authorizationWithPermisson:(NSArray *)permissions andDelegate:(id)delegate { + /*NSLog(@"正在通过OAuth 2.0请求认证授权......"); + self.permissions = permissions; + self.renrenDelegate = delegate; + if (![self isSessionValid]){ + [self authorizeWithRRAppAuth:YES safariAuth:YES]; + }*/ + NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray* graphCookies = [cookies cookiesForURL: + [NSURL URLWithString:@"http://graph.renren.com"]]; + + for (NSHTTPCookie* cookie in graphCookies) { + [cookies deleteCookie:cookie]; + } + NSArray* widgetCookies = [cookies cookiesForURL:[NSURL URLWithString:@"http://widget.renren.com"]]; + + for (NSHTTPCookie* cookie in widgetCookies) { + [cookies deleteCookie:cookie]; + } + if (![self isSessionValid]) { + self.renrenDelegate = [delegate retain]; + self.permissions = nil; + self.permissions = permissions; + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + [parameters setValue:_appKey forKey:@"client_id"]; + [parameters setValue:kRRSuccessURL forKey:@"redirect_uri"]; + [parameters setValue:@"token" forKey:@"response_type"]; + [parameters setValue:@"touch" forKey:@"display"]; + if (nil != self.permissions) { + NSString *permissionScope = [self.permissions componentsJoinedByString:@","]; + [parameters setValue:permissionScope forKey:@"scope"]; + } + + [_rrDialog release]; + NSLog(@"正在通过OAuth 2.0请求认证授权......"); + _rrDialog = [[RODialog alloc] initWithURL:kAuthBaseURL params:parameters delegate:self]; + [_rrDialog show]; + } +} + +- (void)passwordFlowAuthorizationWithParam:(ROPasswordFlowRequestParam *)param andDelegate:(id) delegate{ + self.renrenDelegate = delegate; + + param.apiKey = self.appKey; + + if (![self isSessionValid]){ + [self sendRequestWithUrl:kPasswordFlowBaseURL param:param httpMethod:@"POST" delegate:self]; + } +} + +/** + * 退出用户登录 + * + * @param delegate + * + */ + +- (void)logout:(id)delegate { + self.renrenDelegate = delegate; + NSMutableDictionary * params = [[NSMutableDictionary alloc] init]; + [params release]; + [_accessToken release]; + _accessToken = nil; + [_expirationDate release]; + _expirationDate = nil; + [_secret release]; + _secret=nil; + [_sessionKey release]; + _sessionKey=nil; + [self delUserSessionInfo]; + if ([self.renrenDelegate respondsToSelector:@selector(renrenDidLogout:)]) { + [self.renrenDelegate renrenDidLogout:self]; + } +} + +#pragma mark - Customlized API Request Methods - + +- (RORequest *)requestWithParams:(NSMutableDictionary *)params andDelegate:(id )delegate{ + if (nil == [params objectForKey:@"method"]) { + NSLog(@"API Method must be specified"); + return nil; + } + if ([self isSessionValid]) { + [params setObject:self.sessionKey forKey:@"session_key"]; + }else { + NSLog(@"Session is not valid! Request abort!!"); + return nil; + } + + [params setObject:[ROUtility generateCallId] forKey:@"call_id"];//增加键与值 + [params setObject:_appKey forKey:@"api_key"]; + [params setObject:kSDKversion forKey:@"v"]; + [params setObject:@"json" forKey:@"format"]; + [params setObject:@"1" forKey:@"xn_ss"]; + + NSString *sig = [ROUtility generateSig:params secretKey:self.secret]; + [params setObject:sig forKey:@"sig"]; + + self.renrenDelegate = [delegate retain]; + + return [self openUrl:kRestserverBaseURL params:params httpMethod:@"POST" delegate:self]; +} + +- (void)dialog:(NSString *)action andParams:(NSMutableDictionary *)params andDelegate:(id)delegate{ + NSString *dialogURL = [kDialogBaseURL stringByAppendingString:action]; + [params setObject:_appId forKey:@"app_id"]; + [params setObject:@"touch" forKey:@"display"]; + + if ([params objectForKey:@"redirect_uri"] == nil) { + [params setObject:kRRSuccessURL forKey:@"redirect_uri"]; + } + + if ([self isSessionValid]) { + [params setValue:[self.accessToken stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:@"access_token"]; + } + + _renrenDelegate = delegate; + [_rrDialog release]; + _rrDialog = [[RODialog alloc] initWithURL:dialogURL params:params delegate:self]; + [_rrDialog show]; +} + +#pragma mark - RORequestDelegate - + +/** + * Handle the auth.ExpireSession api call failure + */ +- (void)request:(RORequest *)request didFailWithError:(NSError*)error{ + NSLog(@"Failed to expire the session"); +} + +- (void)request:(RORequest *)request didFailWithROError:(ROError *)error{ + + //password flow授权错误的处理 + if([request.requestParamObject isKindOfClass:[ROPasswordFlowRequestParam class]]) + { + if ([self.renrenDelegate respondsToSelector:@selector(renren:loginFailWithError:)]) { + [self.renrenDelegate renren:self loginFailWithError:error]; + }else{ + // 默认错误处理。 + NSString *title = [NSString stringWithFormat:@"Error code:%d", [error code]]; + NSString *description = [NSString stringWithFormat:@"%@", [error localizedDescription]]; + UIAlertView *alertView =[[[UIAlertView alloc] initWithTitle:title message:description delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil] autorelease]; + [alertView show]; + } + return; + } + + if (self.renrenDelegate && [self.renrenDelegate respondsToSelector:@selector(renren:requestFailWithError:)]) { + [self.renrenDelegate renren:self requestFailWithError:error]; + }else{ + // 默认错误处理。 + NSString *title = [NSString stringWithFormat:@"Error code:%d", [error code]]; + NSString *description = [NSString stringWithFormat:@"%@", [error localizedDescription]]; + UIAlertView *alertView =[[[UIAlertView alloc] initWithTitle:title message:description delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil] autorelease]; + [alertView show]; + } + + return; +} + +- (void)request:(RORequest *)request didLoad:(id)result{ + + //password flow授权请求的处理 + if([request.requestParamObject isKindOfClass:[ROPasswordFlowRequestParam class]]) + { + NSString *token = [request.responseObject.rootObject objectForKey:@"access_token"]; + NSString *date = [request.responseObject.rootObject objectForKey:@"expires_in"]; + + self.accessToken = [request.responseObject.rootObject objectForKey:@"access_token"];; + self.expirationDate = [ROUtility getDateFromString:date]; + self.secret=[self getSecretKeyByToken:token]; + self.sessionKey=[self getSessionKeyByToken:token]; + //用户信息保存到本地 + [self saveUserSessionInfo]; + [self getLoggedInUserId]; + if ([self.renrenDelegate respondsToSelector:@selector(renrenDidLogin:)]) { + [self.renrenDelegate renrenDidLogin:self]; + } + return; + } + if ([request.requestParamObject.method isEqualToString:@"users.getLoggedInUser"]) { + NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; + NSNumber *uid = [(NSDictionary*)result objectForKey:@"uid"]; + if (uid) { + [defaults setObject:[uid stringValue] forKey:@"session_UserId"]; + [defaults synchronize]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"kNotificationDidGetLoggedInUserId" object:nil]; + } + + return; + } + if(self.renrenDelegate && [self.renrenDelegate respondsToSelector:@selector(renren:requestDidReturnResponse:)]){ + [self.renrenDelegate renren:self requestDidReturnResponse:request.responseObject]; + }else{ + // 默认请求成功时的处理。 + + } + + return; +} + +#pragma mark - Packaged API Function Methods - + +-(void)createAlbum:(ROCreateAlbumRequestParam *)param andDelegate:(id)delegate{ + if (![param.method isEqualToString:@"photos.createAlbum"]) { + NSLog(@"API Method Error!"); + return; + } + + self.renrenDelegate = delegate; + + [self requestWithParam:param andDelegate:self]; + + return; +} + +-(void)getAlbums:(ROAlbumsInfoRequestParam *)param andDelegate:(id)delegate{ + if (![param.method isEqualToString:@"photos.getAlbums"]) { + NSLog(@"API Method Error!"); + return; + } + + self.renrenDelegate = delegate; + + [self requestWithParam:param andDelegate:self]; + + return; +} + +-(void)getUsersInfo:(ROUserInfoRequestParam *)param andDelegate:(id)delegate{ + if (![param.method isEqualToString:@"users.getInfo"]) { + NSLog(@"API Method Error!"); + return; + } + + self.renrenDelegate = delegate; + + [self requestWithParam:param andDelegate:self]; + + return; +} + +-(void)publishPhoto:(ROPublishPhotoRequestParam *)param andDelegate:(id)delegate{ + if (![param.method isEqualToString:@"photos.upload"]) { + NSLog(@"API Method Error!"); + return; + } + + self.renrenDelegate = delegate; + + [self requestWithParam:param andDelegate:self]; + + return; +} + +-(void)getFriends:(ROGetFriendsRequestParam *)param andDelegate:(id)delegate +{ + if (![param.method isEqualToString:@"friends.get"]) { + NSLog(@"API Method Error!"); + return; + } + + self.renrenDelegate = delegate; + + [self requestWithParam:param andDelegate:self]; +} + +-(void)getFriendsInfo:(ROGetFriendsInfoRequestParam *)param andDelegate:(id)delegate +{ + if (![param.method isEqualToString:@"friends.getFriends"]) { + NSLog(@"API Method Error!"); + return; + } + + if (![self isSessionValid]) { + //[self delUserSessionInfo]; + NSLog(@"Session not valid!! Request abort!"); + return; + } + + self.renrenDelegate = delegate; + + [self requestWithParam:param andDelegate:self]; +} + +#pragma mark - One-Click API Function Methods - +/** + *一键发布照片流程方法 + *@param image 准备上传图片对象 + *@param caption 上传图片的附加文本,会成为照片的描述 + */ +-(void)publishPhotoSimplyWithImage:(UIImage *)image caption:(NSString *)caption +{ + + ROPublishPhotoDialogModel *dialogModel = [ROPublishPhotoDialogModel modelWithRenren:self]; + dialogModel.photo = image; + dialogModel.caption = caption; + RODialogView *dialogView = [RODialogView dialogViewWithModel:dialogModel]; + //判断用户是否已通过授权认证 + if (![self isSessionValid]) { + [dialogView waitForRenrenAuthorize]; + NSArray *permissions = [NSArray arrayWithObjects:@"photo_upload",nil]; + [self authorizationWithPermisson:permissions andDelegate:dialogModel]; + }else { + [dialogView show:YES]; + } +} + +#pragma mark - discarded Methods should removed in near future - + +/** + * A private function for opening the authorization dialog. + * User-Agent Flow + */ +- (void)authorizeWithRRAppAuth:(BOOL)tryRRAppAuth safariAuth:(BOOL)trySafariAuth { + NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: + _appKey, @"client_id", + @"token", @"response_type", + kRRSuccessURL, @"redirect_uri", + @"touch", @"display", + nil]; + if (_permissions != nil){ + NSString* scope = [_permissions componentsJoinedByString:@","]; + [params setValue:scope forKey:@"scope"]; + } + + [_rrDialog release]; + _rrDialog = [[RODialog alloc] initWithURL:kAuthBaseURL params:params delegate:self]; + [_rrDialog show]; + +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROAlbumsInfoRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROAlbumsInfoRequestParam.h new file mode 100755 index 000000000..82bddaf90 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROAlbumsInfoRequestParam.h @@ -0,0 +1,41 @@ +// ROAlbumsInfoRequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import "RORequestParam.h" + +/** + *封装了获取相册信息请求参数的类 + */ +@interface ROAlbumsInfoRequestParam : RORequestParam { + NSString *_page; + NSString *_count; + NSString *_albumIDs; + NSString *_userID; +} + +/** + *分页的页数 + */ +@property (copy,nonatomic)NSString *page; + +/** + *分页后每页的个数 + */ +@property (copy,nonatomic)NSString *count; + +/** + *相册的ID。多个相册的ID,以逗号分隔,最多支持10个数据 + */ +@property (copy,nonatomic)NSString *albumIDs; + +/** + *相册所有者的用户ID + */ +@property (copy,nonatomic)NSString *userID; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROAlbumsInfoRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROAlbumsInfoRequestParam.m new file mode 100755 index 000000000..e17f4f537 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROAlbumsInfoRequestParam.m @@ -0,0 +1,82 @@ +// ROAlbumsInfoRequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROAlbumsInfoRequestParam.h" +#import "ROAlbumResponseltem.h" +#import "ROError.h" + + +@implementation ROAlbumsInfoRequestParam +@synthesize page = _page; +@synthesize count = _count; +@synthesize albumIDs = _albumIDs; +@synthesize userID = _userID; + +-(id)init +{ + if (self = [super init]) { + self.method = [NSString stringWithFormat:@"photos.getAlbums"]; + self.page = [NSString stringWithFormat:@"1"]; + self.count = [NSString stringWithFormat:@"10"]; + } + + return self; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + if (dictionary == nil) { + return; + } + + if ([self.page intValue] > 0) { + [dictionary setObject:self.page forKey:@"page"]; + } + + if ([self.count intValue] > 0) { + [dictionary setObject:self.count forKey:@"count"]; + } + + if (self.albumIDs != nil && ![self.albumIDs isEqualToString:@""]) { + [dictionary setObject:self.albumIDs forKey:@"aids"]; + } + + [dictionary setObject:self.userID forKey:@"uid"]; +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if ([result isKindOfClass:[NSArray class]]) { + responseObject = [[[NSMutableArray alloc] init] autorelease]; + + for (NSDictionary *item in result) { + ROAlbumResponseltem *responseItem = [[[ROAlbumResponseltem alloc] initWithDictionary:item] autorelease]; + [(NSMutableArray*)responseObject addObject:responseItem]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } else { + if ([result objectForKey:@"error_code"] != nil) { + responseObject = [ROError errorWithRestInfo:result]; + return [ROResponse responseWithError:responseObject]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } +} + +-(void)dealloc +{ + self.page = nil; + self.count = nil; + self.albumIDs = nil; + self.userID = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROCreateAlbumRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROCreateAlbumRequestParam.h new file mode 100755 index 000000000..165ccdc6d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROCreateAlbumRequestParam.h @@ -0,0 +1,47 @@ +// ROCreateAlbumRequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import "RORequestParam.h" + +/** + *封装了创建相册请求参数的类 + */ +@interface ROCreateAlbumRequestParam : RORequestParam { + NSString *_name; + NSString *_location; + NSString *_description; + NSString *_visible; + NSString *_password; +} + +/** + *相册的名称 + */ +@property (copy,nonatomic)NSString *name; + +/** + *相册的地点 + */ +@property (copy,nonatomic)NSString *location; + +/** + *相册的描述 + */ +@property (copy,nonatomic)NSString *description; + +/** + *相册的隐私 + */ +@property (copy,nonatomic)NSString *visible; + +/** + *相册的密码 + */ +@property (copy,nonatomic)NSString *password; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROCreateAlbumRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROCreateAlbumRequestParam.m new file mode 100755 index 000000000..1901b1a40 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROCreateAlbumRequestParam.m @@ -0,0 +1,83 @@ +// ROCreateAlbumRequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROCreateAlbumRequestParam.h" +#import "ROCreateAlbumResponseItem.h" +#import "ROError.h" + + +@implementation ROCreateAlbumRequestParam +@synthesize name = _name; +@synthesize location = _location; +@synthesize description = _description; +@synthesize visible = _visible; +@synthesize password = _password; + +-(id)init +{ + if (self = [super init]) { + self.method = [NSString stringWithFormat:@"photos.createAlbum"]; + } + + return self; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + if (dictionary == nil) { + return; + } + + if (self.name != nil && ![self.name isEqualToString:@""]) { + [dictionary setObject:self.name forKey:@"name"]; + } + + if (self.location != nil && ![self.location isEqualToString:@""]) { + [dictionary setObject:self.location forKey:@"location"]; + } + + if (self.description != nil && ![self.description isEqualToString:@""]) { + [dictionary setObject:self.description forKey:@"description"]; + } + + if (self.visible != nil && ![self.visible isEqualToString:@""]) { + [dictionary setObject:self.visible forKey:@"visible"]; + } + + if (self.password != nil && ![self.password isEqualToString:@""]) { + [dictionary setObject:self.password forKey:@"password"]; + } +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if (![result isKindOfClass:[NSArray class]]) { + if ([result objectForKey:@"error_code"] != nil) { + responseObject = [ROError errorWithRestInfo:result]; + return [ROResponse responseWithError:responseObject]; + } else { + responseObject = [[[ROCreateAlbumResponseItem alloc] initWithDictionary:result] autorelease]; + + return [ROResponse responseWithRootObject:responseObject]; + } + } + + return [ROResponse responseWithRootObject:responseObject]; +} + +-(void)dealloc +{ + self.name = nil; + self.location = nil; + self.description = nil; + self.visible = nil; + self.password = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsInfoRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsInfoRequestParam.h new file mode 100755 index 000000000..07543fd79 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsInfoRequestParam.h @@ -0,0 +1,33 @@ +// +// ROGetFriendsInfoRequestParam.h +// RenrenSDKDemo +// +// Created by xiawenhai on 11-8-31. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "RORequestParam.h" + +@interface ROGetFriendsInfoRequestParam : RORequestParam { + NSString *_page; + NSString *_count; + NSString *_fields; +} + +/** + *分页的页数 + */ +@property (copy,nonatomic)NSString *page; + +/** + *分页后每页的个数 + */ +@property (copy,nonatomic)NSString *count; + +/** + *查询字段 + */ +@property (copy,nonatomic)NSString *fields; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsInfoRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsInfoRequestParam.m new file mode 100755 index 000000000..2bef8d773 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsInfoRequestParam.m @@ -0,0 +1,77 @@ +// +// ROGetFriendsInfoRequestParam.m +// RenrenSDKDemo +// +// Created by xiawenhai on 11-8-31. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROGetFriendsInfoRequestParam.h" +#import "ROFriendResponseItem.h" + +@implementation ROGetFriendsInfoRequestParam +@synthesize page = _page; +@synthesize count = _count; +@synthesize fields = _fields; + +-(id)init +{ + if (self = [super init]) { + self.method = [NSString stringWithFormat:@"friends.getFriends"]; + self.page = [NSString stringWithFormat:@"1"]; + self.count = [NSString stringWithFormat:@"10"]; + } + + return self; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + if (dictionary == nil) { + return; + } + + if (self.count != nil && ![self.count isEqualToString:@""]) { + [dictionary setObject:self.count forKey:@"count"]; + } + + if (self.page != nil && ![self.page isEqualToString:@""]) { + [dictionary setObject:self.page forKey:@"page"]; + } + + if (self.fields != nil && ![self.fields isEqualToString:@""]) { + [dictionary setObject:self.fields forKey:@"fields"]; + } +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if ([result isKindOfClass:[NSArray class]]) { + responseObject = [[[NSMutableArray alloc] init] autorelease]; + + for (NSDictionary *item in result) { + ROFriendResponseItem *responseItem = [[[ROFriendResponseItem alloc] initWithDictionary:item] autorelease]; + [(NSMutableArray*)responseObject addObject:responseItem]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } else { + if ([result objectForKey:@"error_code"] != nil) { + responseObject = [ROError errorWithRestInfo:result]; + return [ROResponse responseWithError:responseObject]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } +} + +-(void)dealloc +{ + self.page = nil; + self.count = nil; + self.fields = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsRequestParam.h new file mode 100755 index 000000000..1c2130818 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsRequestParam.h @@ -0,0 +1,29 @@ +// +// ROGetFriendsRequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-17. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import +#import "RORequestParam.h" + + +@interface ROGetFriendsRequestParam : RORequestParam { + NSString *_page; + NSString *_count; +} + +/** + *分页的页数 + */ +@property (copy,nonatomic)NSString *page; + +/** + *分页后每页的个数 + */ +@property (copy,nonatomic)NSString *count; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsRequestParam.m new file mode 100755 index 000000000..d414f48fd --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROGetFriendsRequestParam.m @@ -0,0 +1,67 @@ +// +// ROGetFriendsRequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-17. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROGetFriendsRequestParam.h" +#import "ROResponse.h" +#import "ROError.h" + + +@implementation ROGetFriendsRequestParam +@synthesize page = _page; +@synthesize count = _count; + +-(id)init +{ + if (self = [super init]) { + self.method = [NSString stringWithFormat:@"friends.get"]; + self.page = [NSString stringWithFormat:@"1"]; + self.count = [NSString stringWithFormat:@"10"]; + } + + return self; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + if (dictionary == nil) { + return; + } + + if (self.count != nil && ![self.count isEqualToString:@""]) { + [dictionary setObject:self.count forKey:@"count"]; + } + + if (self.page != nil && ![self.page isEqualToString:@""]) { + [dictionary setObject:self.page forKey:@"page"]; + } +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if ([result isKindOfClass:[NSArray class]]) { + return [ROResponse responseWithRootObject:result]; + } else { + if ([result objectForKey:@"error_code"] != nil) { + responseObject = [ROError errorWithRestInfo:result]; + return [ROResponse responseWithError:responseObject]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } +} + +-(void)dealloc +{ + self.page = nil; + self.count = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPasswordFlowRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPasswordFlowRequestParam.h new file mode 100755 index 000000000..5fa825e4c --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPasswordFlowRequestParam.h @@ -0,0 +1,47 @@ +// +// ROPasswordFlowRequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-17. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import "RORequestParam.h" + + +@interface ROPasswordFlowRequestParam : RORequestParam { + NSString *_userName; + NSString *_passWord; + NSString *_grantType; + NSString *_secretKey; + NSString *_scope; +} + +/** + *用户名 + */ +@property (copy,nonatomic)NSString *userName; + +/** + *密码 + */ +@property (copy,nonatomic)NSString *passWord; + +/** + *授权的类型 + */ +@property (copy,nonatomic)NSString *grantType; + +/** + *secret key + */ +@property (copy,nonatomic)NSString *secretKey; + +/** + *需要授权的项目 + */ +@property (copy,nonatomic)NSString *scope; + + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPasswordFlowRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPasswordFlowRequestParam.m new file mode 100755 index 000000000..c28c472e6 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPasswordFlowRequestParam.m @@ -0,0 +1,70 @@ +// +// ROPasswordFlowRequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-17. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROPasswordFlowRequestParam.h" +#import "ROError.h" +#import "Renren.h" + +@implementation ROPasswordFlowRequestParam +@synthesize userName = _userName; +@synthesize passWord = _passWord; +@synthesize grantType = _grantType; +@synthesize secretKey = _secretKey; +@synthesize scope = _scope; + +-(id)init +{ + if (self = [super init]) { + self.grantType = [NSString stringWithFormat:@"password"]; + self.secretKey = SHKCONFIG(renrenConsumerSecret); + } + + return self; +} + +-(NSMutableDictionary*)requestParamToDictionary +{ + NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:self.userName,@"username", + self.passWord,@"password", + self.grantType,@"grant_type", + self.apiKey,@"client_id", + self.secretKey,@"client_secret",nil]; + if (self.scope != nil && ![self.scope isEqualToString:@""]) { + [dictionary setObject:self.scope forKey:@"scope"]; + } + + return dictionary; +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if (![result isKindOfClass:[NSArray class]]) { + if ([result objectForKey:@"error"] != nil) { + responseObject = [ROError errorWithOAuthResult:result]; + return [ROResponse responseWithError:responseObject]; + } else { + + return [ROResponse responseWithRootObject:result]; + } + } + + return [ROResponse responseWithRootObject:responseObject]; +} + +-(void)dealloc +{ + self.userName = nil; + self.passWord = nil; + self.grantType = nil; + self.secretKey = nil; + self.scope = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPublishPhotoRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPublishPhotoRequestParam.h new file mode 100755 index 000000000..39ef6996d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPublishPhotoRequestParam.h @@ -0,0 +1,41 @@ +// +// ROPublishPhotoRequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-17. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import +#import "RORequestParam.h" + + +@interface ROPublishPhotoRequestParam : RORequestParam { + UIImage *_imageFile; + NSString *_caption; + NSString *_albumID; + NSString *_placeID; +} + +/** + *照片文件 + */ +@property (retain,nonatomic)UIImage *imageFile; + +/** + *照片的描述信息 + */ +@property (copy,nonatomic)NSString *caption; + +/** + *相册的ID + */ +@property (copy,nonatomic)NSString *albumID; + +/** + *地点的ID + */ +@property (copy,nonatomic)NSString *placeID; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPublishPhotoRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPublishPhotoRequestParam.m new file mode 100755 index 000000000..2af6fcb87 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROPublishPhotoRequestParam.m @@ -0,0 +1,80 @@ +// +// ROPublishPhotoRequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-17. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROPublishPhotoRequestParam.h" +#import "ROPublishPhotoResponseItem.h" +#import "ROResponse.h" +#import "ROError.h" + + +@implementation ROPublishPhotoRequestParam +@synthesize imageFile = _imageFile; +@synthesize caption = _caption; +@synthesize albumID = _albumID; +@synthesize placeID = _placeID; + +-(id)init +{ + if (self = [super init]) { + self.method = [NSString stringWithFormat:@"photos.upload"]; + } + + return self; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + if (dictionary == nil) { + return; + } + + if (self.imageFile != nil) { + [dictionary setObject:self.imageFile forKey:@"upload"]; + } + + if (self.caption != nil && ![self.caption isEqualToString:@""]) { + [dictionary setObject:self.caption forKey:@"caption"]; + } + + if (self.albumID != nil && ![self.albumID isEqualToString:@""]) { + [dictionary setObject:self.albumID forKey:@"aid"]; + } + + if (self.placeID != nil && ![self.placeID isEqualToString:@""]) { + [dictionary setObject:self.placeID forKey:@"place_id"]; + } +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if (![result isKindOfClass:[NSArray class]]) { + if ([result objectForKey:@"error_code"] != nil) { + responseObject = [ROError errorWithRestInfo:result]; + return [ROResponse responseWithError:responseObject]; + } else { + ROPublishPhotoResponseItem *responseItem = [[[ROPublishPhotoResponseItem alloc] initWithDictionary:result] autorelease]; + return [ROResponse responseWithRootObject:responseItem]; + } + } + + return [ROResponse responseWithRootObject:responseObject]; +} + + +-(void)dealloc +{ + self.imageFile = nil; + self.caption = nil; + self.albumID = nil; + self.placeID = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/RORequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/RORequestParam.h new file mode 100755 index 000000000..ac2af664c --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/RORequestParam.h @@ -0,0 +1,83 @@ +// RORequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import "ROResponse.h" + +/** + *封装请求参数的基类 + */ + +@class ROResponse; + +@interface RORequestParam : NSObject { + NSString *_method; + NSString *_format; + NSString *_apiVersion; + NSString *_apiKey; + NSString *_sessionKey; + NSString *_callID; + NSString *_sig; + NSString *_xn_ss; +} + +/** + *请求的API方法 + */ +@property (copy,nonatomic)NSString *method; + +/** + *返回数据的格式 + */ +@property (copy,nonatomic)NSString *format; + +/** + *API的版本号 + */ +@property (copy,nonatomic)NSString *apiVersion; + +/** + *应用的appkey + */ +@property (copy,nonatomic)NSString *apiKey; + +/** + *认证应用和用户的sessionkey + */ +@property (copy,nonatomic)NSString *sessionKey; + +/** + *call_id + */ +@property (copy,nonatomic)NSString *callID; + +/** + *计算得到的签名 + */ +@property (copy,nonatomic)NSString *sig; + +/** + *返回值的格式 + */ +@property (copy,nonatomic)NSString *xn_ss; + +/** + *将封装好的各个参数解析为字典 + */ +-(NSMutableDictionary*)requestParamToDictionary; + +/** + *将返回的数据整理为ROResponse + */ +-(ROResponse *)requestResultToResponse:(id)result; + +/** + *将派生类中封装的各个参数加入字典 + */ +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/RORequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/RORequestParam.m new file mode 100755 index 000000000..95fd9d1b8 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/RORequestParam.m @@ -0,0 +1,83 @@ +// RORequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "RORequestParam.h" +#import "Renren.h" +#import "ROUtility.h" + +@implementation RORequestParam +@synthesize method = _method; +@synthesize format = _format; +@synthesize apiVersion = _apiVersion; +@synthesize apiKey = _apiKey; +@synthesize sessionKey = _sessionKey; +@synthesize callID = _callID; +@synthesize sig = _sig; +@synthesize xn_ss = _xn_ss; + +-(id)init +{ + if (self = [super init]) { + self.format = [NSString stringWithFormat:@"JSON"]; + self.apiVersion = kSDKversion; + self.xn_ss = [NSString stringWithFormat:@"1"]; + } + + return self; +} + +-(NSMutableDictionary*)requestParamToDictionary +{ + NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:self.format,@"format", + self.apiVersion,@"v", + self.method,@"method", + self.apiKey,@"api_key", + self.sessionKey,@"session_key", + self.callID,@"call_id", + self.xn_ss,@"xn_ss",nil]; + + if (self.sig != nil && ![self.sig isEqualToString:@""]) { + [dictionary setObject:self.sig forKey:@"sig"]; + } + + [self addParamToDictionary:dictionary]; + + return dictionary; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + return; +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if (![result isKindOfClass:[NSArray class]]) { + if ([result objectForKey:@"error"] != nil) { + responseObject = [ROError errorWithOAuthResult:result]; + return [ROResponse responseWithError:responseObject]; + } + } + + return [ROResponse responseWithRootObject:result]; +} + +-(void)dealloc +{ + self.method = nil; + self.format = nil; + self.apiVersion = nil; + self.apiKey = nil; + self.sessionKey = nil; + self.callID = nil; + self.sig = nil; + self.xn_ss = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROUserInfoRequestParam.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROUserInfoRequestParam.h new file mode 100755 index 000000000..56819feed --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROUserInfoRequestParam.h @@ -0,0 +1,29 @@ +// ROUserInfoRequestParam.h +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import "RORequestParam.h" + +/** + *封装了用户信息请求参数的类 + */ +@interface ROUserInfoRequestParam : RORequestParam { + NSString *_userIDs; + NSString *_fields; +} + +/** + *用户的ID。多个相册的ID,以逗号分隔 + */ +@property (copy,nonatomic)NSString *userIDs; + +/** + *请求的字段 + */ +@property (copy,nonatomic)NSString *fields; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROUserInfoRequestParam.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROUserInfoRequestParam.m new file mode 100755 index 000000000..a03f3b8ca --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/RequestParam/ROUserInfoRequestParam.m @@ -0,0 +1,70 @@ +// ROUserInfoRequestParam.m +// Renren Open-platform +// +// Created by xiawenhai on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROUserInfoRequestParam.h" +#import "ROUserResponseItem.h" +#import "ROError.h" + + +@implementation ROUserInfoRequestParam +@synthesize userIDs = _userIDs; +@synthesize fields = _fields; + +-(id)init +{ + if (self = [super init]) { + self.method = [NSString stringWithFormat:@"users.getInfo"]; + } + + return self; +} + +-(void)addParamToDictionary:(NSMutableDictionary*)dictionary +{ + if (dictionary == nil) { + return; + } + + if (self.fields != nil && ![self.fields isEqualToString:@""]) { + [dictionary setObject:self.fields forKey:@"fields"]; + } + + if (self.userIDs != nil && ![self.userIDs isEqualToString:@""]) { + [dictionary setObject:self.userIDs forKey:@"uids"]; + } +} + +-(ROResponse*)requestResultToResponse:(id)result +{ + id responseObject = nil; + if ([result isKindOfClass:[NSArray class]]) { + responseObject = [[[NSMutableArray alloc] init] autorelease]; + + for (NSDictionary *item in result) { + ROUserResponseItem *responseItem = [[[ROUserResponseItem alloc] initWithDictionary:item] autorelease]; + [(NSMutableArray*)responseObject addObject:responseItem]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } else { + if ([result objectForKey:@"error_code"] != nil) { + responseObject = [ROError errorWithRestInfo:result]; + return [ROResponse responseWithError:responseObject]; + } + + return [ROResponse responseWithRootObject:responseObject]; + } +} + +-(void)dealloc +{ + self.userIDs = nil; + self.fields = nil; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROAlbumResponseltem.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROAlbumResponseltem.h new file mode 100755 index 000000000..b473d2bef --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROAlbumResponseltem.h @@ -0,0 +1,113 @@ +// +// ROAlbumResponseltem.h +// SimpleDemo +// +// Created by Winston on 11-8-16. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROResponseItem.h" + + +enum { + ROAlbumVisibleTypeEveryone = 99, //所有人可见 + ROAlbumVisibleTypeNeedPassword = 4, //密码保护 + ROAlbumVisibleTypeSameNetwork = 3, //同网络:同城,同校,同公司等 + ROAlbumVisibleTypeFriend = 1, //仅好友可见 + ROAlbumVisibleTypePersonal = -1 //仅自己可见 +}; +typedef NSUInteger ROAlbumVisibleType; //相册的隐私设置类型 + +enum { + ROAlbumTypeNormal = 0, //普通相册 + ROAlbumTypeAvatar= 1, //头像相册 + ROAlbumTypeMMS = 3, //彩信相册 + ROAlbumTypeUpload = 5, //上传相册 + ROAlbumTypePhotoSticker = 7, //大头贴相册 + ROAlbumTypeApplication = 12 //应用相册 +}; +typedef NSUInteger ROAlbumType; //相册的类型 + +//封装的相册Responseltem ,album +@interface ROAlbumResponseltem : ROResponseItem{ + + + NSString* _albumId; + + NSString* _coverUrl; + + NSString* _userId; + + NSString* _name; + + NSString* _createTime; + + NSString* _updateTime; + + NSString* _description; + + NSString* _location; + + NSUInteger _size; + + ROAlbumVisibleType _visibleType; + + NSUInteger _commentCount; + + ROAlbumType _type; + +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/** + *表示相册的ID;aid; + */ +@property(nonatomic, readonly) NSString* albumId; +/** + *表示相册的封面图片地址;url + */ +@property(nonatomic, readonly) NSString* coverUrl; +/** + *表示相册的所有者的id;uid + */ +@property(nonatomic, readonly) NSString* userId; +/** + *表示相册的名字; name + */ +@property(nonatomic, readonly) NSString* name; +/** + *表示相册创建时间;create_time; + *yyyy-mm-dd + */ +@property(nonatomic, readonly) NSString* createTime; +/** + *表示相册更新的时间;upload_time + *yyyy-mm-dd + */ +@property(nonatomic, readonly) NSString* updateTime; +/** + *表示相册的描述;description + */ +@property(nonatomic, readonly) NSString* description; +/** + *表示相册拍摄的地点;location + */ +@property(nonatomic, readonly) NSString* location; +/** + *表示相册的大小,照片的数量;size + */ +@property(nonatomic, readonly) NSUInteger size; +/** + *表示相册的隐私设置;visible + */ +@property(nonatomic, readonly) ROAlbumVisibleType visibleType; +/** + *表示相册的评论数量;comment_count + */ +@property(nonatomic, readonly) NSUInteger commentCount; +/** + *表示相册的类型;type + */ +@property(nonatomic, readonly) ROAlbumType type; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROAlbumResponseltem.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROAlbumResponseltem.m new file mode 100755 index 000000000..530e1f88b --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROAlbumResponseltem.m @@ -0,0 +1,47 @@ +// +// ROAlbumResponseltem.m +// SimpleDemo +// +// Created by Winston on 11-8-16. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROAlbumResponseltem.h" + +@implementation ROAlbumResponseltem + +@synthesize albumId = _albumId; +@synthesize coverUrl = _coverUrl; +@synthesize userId = _userId; +@synthesize name = _name; +@synthesize createTime = _createTime; +@synthesize updateTime = _updateTime; +@synthesize description = _description; +@synthesize location = _location; +@synthesize size = _size; +@synthesize visibleType = _visibleType; +@synthesize commentCount = _commentCount; +@synthesize type = _type; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _albumId = [self valueForItemKey:@"aid"]; + _coverUrl = [self valueForItemKey:@"url"]; + _userId = [self valueForItemKey:@"uid"]; + _name = [self valueForItemKey:@"name"]; + _createTime = [self valueForItemKey:@"create_time"]; + _updateTime = [self valueForItemKey:@"update_time"]; + _description = [self valueForItemKey:@"description"]; + _location = [self valueForItemKey:@"location"]; + _size = [[self valueForItemKey:@"size"] intValue]; + _visibleType = [[self valueForItemKey:@"visible"] intValue]; + _commentCount = [[self valueForItemKey:@"comment_count"] intValue]; + _type = [[self valueForItemKey:@"type"] intValue]; + } + return self; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROCreateAlbumResponseItem.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROCreateAlbumResponseItem.h new file mode 100755 index 000000000..c32286544 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROCreateAlbumResponseItem.h @@ -0,0 +1,23 @@ +// +// ROCreateAlbumResponseItem.h +// SimpleDemo +// +// Created by Winston on 11-8-15. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROResponseItem.h" + +@interface ROCreateAlbumResponseItem : ROResponseItem +{ + NSString* _albumId; +} + +//注释解释:属性描述;JSON字段名;个别属性值含义 +/** + *表示刚创建的相册id;aid + */ +@property(nonatomic,readonly)NSString *albumId; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROCreateAlbumResponseItem.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROCreateAlbumResponseItem.m new file mode 100755 index 000000000..215bd1986 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROCreateAlbumResponseItem.m @@ -0,0 +1,23 @@ +// +// ROCreateAlbumResponseItem.m +// SimpleDemo +// +// Created by Winston on 11-8-15. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROCreateAlbumResponseItem.h" + +@implementation ROCreateAlbumResponseItem +@synthesize albumId = _albumId; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _albumId = [self valueForItemKey:@"aid"]; + } + return self; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROFriendResponseItem.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROFriendResponseItem.h new file mode 100755 index 000000000..2f98f2874 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROFriendResponseItem.h @@ -0,0 +1,46 @@ +// +// ROFriendResponseItem.h +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROResponseItem.h" + +@interface ROFriendResponseItem : ROResponseItem{ + + NSString *_userId; + NSString *_name; + NSString *_headUrl; + NSString *_tinyUrl; + NSString *_headLogoUrl; + NSString *_tinyLogoUrl; +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/** + *表示好友用户id;uid; + */ +@property(nonatomic, readonly)NSString *userId; +/** + *表示好友用户name;name; + */ +@property(nonatomic, readonly)NSString *name; +/** + *表示好友头像地址;headurl; + */ +@property(nonatomic, readonly)NSString *headUrl; +/** + *表示好友小头像地址;tinyurl; + */ +@property(nonatomic, readonly)NSString *tinyUrl; +/** + *表示好友带人人logo的头像地址;headurl_with_logo; + */ +@property(nonatomic, readonly)NSString *headLogoUrl; +/** + *表示好友带人人logo的小头像地址;tinyurl_with_logo; + */ +@property(nonatomic, readonly)NSString *tinyLogoUrl; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROFriendResponseItem.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROFriendResponseItem.m new file mode 100755 index 000000000..0703e0e0b --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROFriendResponseItem.m @@ -0,0 +1,35 @@ +// +// ROFriendResponseItem.m +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROFriendResponseItem.h" + +@implementation ROFriendResponseItem + +@synthesize userId = _userId; +@synthesize name = _name; +@synthesize headUrl = _headUrl; +@synthesize tinyUrl = _tinyUrl; +@synthesize headLogoUrl = _headLogoUrl; +@synthesize tinyLogoUrl = _tinyLogoUrl; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _userId = [self valueForItemKey:@"id"]; + _name = [self valueForItemKey:@"name"]; + _headUrl = [self valueForItemKey:@"headurl"]; + _tinyUrl = [self valueForItemKey:@"tinyurl"]; + _headLogoUrl = [self valueForItemKey:@"headurl_with_logo"]; + _tinyLogoUrl = [self valueForItemKey:@"tinyurl_with_logo"]; + } + return self; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROPublishPhotoResponseItem.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROPublishPhotoResponseItem.h new file mode 100755 index 000000000..98701c502 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROPublishPhotoResponseItem.h @@ -0,0 +1,51 @@ +// +// ROPublishPhotoResponseItem.h +// SimpleDemo +// +// Created by Winston on 11-8-15. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROResponseItem.h" + +@interface ROPublishPhotoResponseItem : ROResponseItem{ + NSString* _photoId; + NSString* _albumId; + NSString* _userId; + NSString* _srcUrl; + NSString* _srcSmallUrl; + NSString* _srcBigUrl; + NSString* _caption; + +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/* + *表示照片的ID;pid + */ +@property(nonatomic,readonly)NSString* photoId; +/* + *表示照片所在相册id;aid + */ +@property(nonatomic,readonly)NSString* albumId; +/* + *表示照片所有者的用户ID;uid + */ +@property(nonatomic,readonly)NSString* userId; +/* + *表示在相册列表的缩略图地址,100*150;src + */ +@property(nonatomic,readonly)NSString* srcUrl; +/* + *表示封面图地址,200*300;src_small + */ +@property(nonatomic,readonly)NSString* srcSmallUrl; +/* + *表示正常照片地址,600*900;src_big + */ +@property(nonatomic,readonly)NSString* srcBigUrl; +/* + *表示照片的描述信息;caption + */ +@property(nonatomic,readonly)NSString* caption; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROPublishPhotoResponseItem.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROPublishPhotoResponseItem.m new file mode 100755 index 000000000..1369046d2 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROPublishPhotoResponseItem.m @@ -0,0 +1,38 @@ +// +// ROPublishPhotoResponseItem.m +// SimpleDemo +// +// Created by Winston on 11-8-15. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROPublishPhotoResponseItem.h" + +@implementation ROPublishPhotoResponseItem + + +@synthesize photoId = _photoId; +@synthesize albumId = _albumId; +@synthesize userId = _userId; +@synthesize srcUrl = _srcUrl; +@synthesize srcSmallUrl = _srcSmallUrl; +@synthesize srcBigUrl = _srcBigUrl; +@synthesize caption = _caption; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _photoId = [self valueForItemKey:@"pid"]; + _albumId = [self valueForItemKey:@"aid"]; + _userId = [self valueForItemKey:@"uid"]; + _srcUrl = [self valueForItemKey:@"src"]; + _srcSmallUrl = [self valueForItemKey:@"src_small"]; + _srcBigUrl = [self valueForItemKey:@"src_big"]; + _caption = [self valueForItemKey:@"caption"]; + } + return self; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROResponseItem.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROResponseItem.h new file mode 100755 index 000000000..19024c377 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROResponseItem.h @@ -0,0 +1,41 @@ +// +// ROResponseItem.h +// SimpleDemo +// +// Created by Winston on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import + +@interface ROResponseItem : NSObject{ + NSDictionary* _responseDictionary; + NSString* _result; +} + +/* + *表示操作的返回码;result;1表示操作成功,其他则为错误码 + *只有操作类的API才回返回此字段,用于表示操作是否成功,无其他含义。 + */ +@property(nonatomic, readonly)NSString *result; + +/** + * 生成一个ROResponseItem + * @param responseDictionary 传入的由json解析完后字典对象 + * 返回一个ROResponseItem + */ ++(ROResponseItem*)itemWithDictionary:(NSDictionary*)responseDictionary; +/* + *初始化ROResponseItem + */ +-(id)initWithDictionary:(NSDictionary*)responseDictionary; + +/* + *表示对应的json字典对象。 + */ +-(NSDictionary*)responseDictionary; + + +-(id)valueForItemKey:(NSString*)key; +@end + diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROResponseItem.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROResponseItem.m new file mode 100755 index 000000000..f9322401b --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROResponseItem.m @@ -0,0 +1,64 @@ +// +// ROResponseItem.m +// SimpleDemo +// +// Created by Winston on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROResponseItem.h" + +@implementation ROResponseItem + +@synthesize result = _result; + +- (id)init +{ + self = [super init]; + if (self) { + // Initialization code here. + } + + return self; +} + ++(ROResponseItem*)itemWithDictionary:(NSDictionary*)responseDictionary +{ + return [[[self alloc] initWithDictionary:responseDictionary] autorelease]; +} + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [self init]; + if (self) { + _responseDictionary = [responseDictionary retain]; + _result = [self valueForItemKey:@"result"]; + } + return self; +} + +-(NSDictionary*)responseDictionary +{ + return _responseDictionary; +} + +-(id)valueForItemKey:(NSString*)key +{ + if (!key) { + return nil; + } + id value = [[self responseDictionary] objectForKey:key]; + if ([value isKindOfClass:[NSNumber class]]) { + return [value stringValue]; + } + return value; + +} + +-(void)dealloc +{ + [_responseDictionary release]; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROUserResponseItem.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROUserResponseItem.h new file mode 100755 index 000000000..f493939fd --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROUserResponseItem.h @@ -0,0 +1,225 @@ +// +// ROUserResponseItem.h +// SimpleDemo +// +// Created by Winston on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROResponseItem.h" + +//家乡信息 +@interface ROUserHometownItem : ROResponseItem { + + NSString *_country; + + NSString *_province; + + NSString *_city; +} + +//注释解释:属性描述;JSON字段名;个别属性值含义 +/* + *表示所在国家;country + */ +@property(nonatomic,readonly)NSString *country; +/* + *表示所在省份;province + */ +@property(nonatomic,readonly)NSString *province; +/* + *表示所在城市;city + */ +@property(nonatomic,readonly)NSString *city; + +@end + +//工作信息 +@interface ROUserWorkInfoItem : ROResponseItem { + + NSString* _companyName; + + NSString* _description; + + NSString* _startDate; + + NSString* _endDate; + +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/* + *表示所在公司;company_name; + */ +@property(nonatomic,readonly)NSString *companyName; +/* + *表示工作描述;description + */ +@property(nonatomic,readonly)NSString *description; +/* + *表示入职时间;start_date; + *yyyy-mm-dd + */ +@property(nonatomic,readonly)NSString *startDate; +/* + *表示离职职时间;end_date; + *yyyy-mm-dd + */ +@property(nonatomic,readonly)NSString *endDate; + +@end + +//大学信息 +@interface ROUserUniversityInfoItem : ROResponseItem { + + NSString *_name; + + NSString *_year; + + NSString *_department; + +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/* + *表示大学名;name; + */ +@property(nonatomic,readonly)NSString *name; +/* + *表示入学时间;year; + */ +@property(nonatomic,readonly)NSString *year; +/* + *表示学院;department; + */ +@property(nonatomic,readonly)NSString *department; + +@end + +//中学信息 +@interface ROUserHighSchoolInfoItem : ROResponseItem { + + NSString *_name; + + NSString *_gradYear; +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/* + *表示中学学校名;name; + */ +@property(nonatomic,readonly)NSString *name; +/* + *表示入学时间;grad_year; + */ +@property(nonatomic,readonly)NSString *gradYear; +@end + +//用户信息 +@interface ROUserResponseItem : ROResponseItem{ + + NSString* _userId; + + NSString* _name; + + NSString* _tinyUrl; + + NSString* _headUrl; + + NSString* _starUser; + + NSString* _vipUser; + + NSString* _sex; + + NSString* _vipLevel; + + NSString* _brithday; + + NSString* _emailHash; + + NSString* _mainUrl; + + ROUserHometownItem *_hometownLocation; + + NSArray* _workHistory; + + NSArray* _universityHistory; + + NSArray* _highSchoolHistory; + +} +//注释解释:属性描述;JSON字段名;个别属性值含义 +/*---默认基本信息---*/ +/* + *表示用户id;uid + */ +@property(nonatomic,readonly)NSString *userId; +/* + *表示用户名;name + */ +@property(nonatomic,readonly)NSString *name; +/* + *表示头像链接;tinyurl; + *50*50大小。 + */ +@property(nonatomic,readonly)NSString *tinyUrl; +/* + *表示头像链接;headurl + *100*100大小 + */ +@property(nonatomic,readonly)NSString *headUrl; +/* + *表示是否为星级用户;star; + *人人用户:1=是,0=不是;开心用户:0=非真实头像和姓名,1=非真实姓名,2=非真实头像,3=真实用户。 + */ +@property(nonatomic,readonly)NSString *starUser; +/* + *表示是否为vip用户;zidou; + *1=是,0=不是。 + */ +@property(nonatomic,readonly)NSString *vipUser; +/*---详细信息---请求时需传fields参数*/ +/* + *表示用户性别;sex; + *1=男性,0=女性。 + */ +@property(nonatomic,readonly)NSString *sex; +/* + *表示vip等级;vip; + *当是vipUser为1时可用此属性。 + */ +@property(nonatomic,readonly)NSString *vipLevel; +/* + *表示出生时间;brithday + *格式:yyyy-mm-dd + */ +@property(nonatomic,readonly)NSString* brithday; +/* + *表示用户经过验证的email信息字符串;email_hash; + *字符串包含的email经过crc32和md5的编码 + */ +@property(nonatomic,readonly)NSString* emailHash; +/* + *表示头像链接;mainurl + *200*200大小 + */ +@property(nonatomic,readonly)NSString* mainUrl; +/* + *表示家乡信息;hometown_location; + */ +@property(nonatomic,readonly)ROUserHometownItem *hometownLocation; +/* + *表示工作经历;work_history; + *其中object:ROUserWorkInfoItem + */ +@property(nonatomic,readonly)NSArray* workHistory; +/* + *表示大学以上教育经历;university_history; + *其中object:ROUserUniversityInfoItem + */ +@property(nonatomic,readonly)NSArray* universityHistory; +/* + *表示中学以下教育经历;hs_history; + *其中object:ROUserHighSchoolInfoItem + */ +@property(nonatomic,readonly)NSArray* highSchoolHistory; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROUserResponseItem.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROUserResponseItem.m new file mode 100755 index 000000000..e5247d837 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/ResponseItem/ROUserResponseItem.m @@ -0,0 +1,166 @@ +// +// ROUserResponseItem.m +// SimpleDemo +// +// Created by Winston on 11-8-12. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROUserResponseItem.h" + +@implementation ROUserHometownItem + +@synthesize country = _country; +@synthesize province = _province; +@synthesize city = _city; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _country = [self valueForItemKey:@"country"]; + _province = [self valueForItemKey:@"province"]; + _city = [self valueForItemKey:@"city"]; + } + return self; +} +@end + +@implementation ROUserWorkInfoItem + +@synthesize companyName = _companyName; +@synthesize description = _description; +@synthesize startDate = _startDate; +@synthesize endDate = _endDate; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _companyName = [self valueForItemKey:@"company_name"]; + _description = [self valueForItemKey:@"desription"]; + _startDate = [self valueForItemKey:@"start_date"]; + _endDate = [self valueForItemKey:@"end_date"]; + } + return self; +} + +@end + +@implementation ROUserUniversityInfoItem + +@synthesize name = _name; +@synthesize year = _year; +@synthesize department = _department; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _name = [self valueForItemKey:@"name"]; + _year = [self valueForItemKey:@"year"]; + _department = [self valueForItemKey:@"department"]; + } + return self; +} +@end + +@implementation ROUserHighSchoolInfoItem + +@synthesize name = _name; +@synthesize gradYear = _gradYear; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _name = [self valueForItemKey:@"name"]; + _gradYear = [self valueForItemKey:@"grad_year"]; + } + return self; +} + +@end + +@implementation ROUserResponseItem + +@synthesize userId = _userId; +@synthesize name = _name; +@synthesize tinyUrl = _tinyUrl; +@synthesize headUrl = _headUrl; +@synthesize starUser = _starUser; +@synthesize vipUser = _vipUser; +@synthesize sex = _sex; +@synthesize vipLevel = _vipLevel; +@synthesize brithday = _brithday; +@synthesize emailHash = _emailHash; +@synthesize mainUrl = _mainUrl; +@synthesize hometownLocation = _hometownLocation; +@synthesize workHistory = _workHistory; +@synthesize universityHistory = _universityHistory; +@synthesize highSchoolHistory = _highSchoolHistory; + +-(id)initWithDictionary:(NSDictionary*)responseDictionary +{ + self = [super initWithDictionary:responseDictionary]; + if (self) { + _userId = [self valueForItemKey:@"uid"]; + _name = [self valueForItemKey:@"name"]; + _sex = [self valueForItemKey:@"sex"]; + _starUser = [self valueForItemKey:@"star"]; + _vipUser = [self valueForItemKey:@"zidou"]; + _vipLevel = [self valueForItemKey:@"vip"]; + _brithday = [self valueForItemKey:@"brithday"]; + _emailHash = [self valueForItemKey:@"email_hash"]; + _tinyUrl = [self valueForItemKey:@"tinyurl"]; + _headUrl = [self valueForItemKey:@"headurl"]; + _mainUrl = [self valueForItemKey:@"mainurl"]; + if ([self valueForItemKey:@"hometown_location"]) { + _hometownLocation = [[ROUserHometownItem alloc] initWithDictionary:[self valueForItemKey:@"hometown_location"]]; + } + if ([self valueForItemKey:@"work_history"]) { + NSMutableArray* wh = [[NSMutableArray alloc] init]; + NSArray* workHistoryArray = (NSArray*)[self valueForItemKey:@"work_history"]; + for (NSDictionary *workInfoDic in workHistoryArray) { + ROUserWorkInfoItem *item = [[ROUserWorkInfoItem alloc] initWithDictionary:workInfoDic]; + [wh addObject:item]; + [item release]; + } + _workHistory = wh; + } + if ([self valueForItemKey:@"university_history"]) { + NSMutableArray* uh = [[NSMutableArray alloc] init]; + NSArray* universityHistoryArray = (NSArray*)[self valueForItemKey:@"university_history"]; + for (NSDictionary *universityInfoDic in universityHistoryArray) { + ROUserUniversityInfoItem *item = [[ROUserUniversityInfoItem alloc] initWithDictionary:universityInfoDic]; + [uh addObject:item]; + [item release]; + } + _universityHistory = uh; + } + if ([self valueForItemKey:@"hs_history"]) { + NSMutableArray* hsh = [[NSMutableArray alloc] init]; + NSArray* highSchoolHistoryArray = (NSArray*)[self valueForItemKey:@"hs_history"]; + for (NSDictionary *highSchoolInfoDic in highSchoolHistoryArray) { + ROUserHighSchoolInfoItem *item = [[ROUserHighSchoolInfoItem alloc] initWithDictionary:highSchoolInfoDic]; + [hsh addObject:item]; + [item release]; + } + _highSchoolHistory = hsh; + } + + } + return self; +} + +-(void)dealloc +{ + [_hometownLocation release]; + [_highSchoolHistory release]; + [_universityHistory release]; + [_workHistory release]; + [super dealloc]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogModel.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogModel.h new file mode 100755 index 000000000..49f855b17 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogModel.h @@ -0,0 +1,99 @@ +// +// RODialogModel.h +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import + +@class RODialogView; +@protocol RODialogModel +@optional +/** + * 由model调用,显示dialog的LoadingView + */ +-(void)dialogShowLoadingView; +/** + * 由model调用,隐藏dialog的LoadingView + */ +-(void)dialogHideLoadingView; +/** + *当dialog的loadingView隐藏的时候 + * + */ +-(void)dialogLoadingViewWasHidden:(RODialogView *)dialogView; + +/** + * dialogView的显示时机,可以做的一些操作,默认什么都不做。 + */ +- (void)dialogViewWillAppear; +- (void)dialogViewDidAppear; +- (void)dialogViewWillDisappear; + +@end + +@class Renren; +@class RODialogViewController; + +@interface RODialogModel : NSObject +{ + Renren *_renren; + RODialogView *_dialogView; + NSString *_title; + NSString *_tips; + BOOL _isLoading; + BOOL _wasLoaded; + BOOL _closeEnable; +} +/** + * SDK的主接口Renren对象 + */ +@property (nonatomic, retain)Renren *renren; +/** + * dialog视图控制器 + */ +@property (nonatomic, assign)RODialogView *dialogView; +/** + * 显示在Dialog上 loading视图上的提示语句。 + */ +@property (nonatomic, copy)NSString *tips; +/** + * 显示在Dialog上 logoBar的标题语句。 + */ +@property (nonatomic, copy)NSString *title; +/** + * 表示是否在Dialog上的 loading视图上显示 动态提示符 + * YES:显示,NO,不显示 + */ +@property (nonatomic) BOOL isLoading; +/** + * 表示在Dialog上的loading视图是否两秒后自动消失 + * YES:显示,NO,不显示 + */ +@property (nonatomic) BOOL wasLoaded; +/** + * 表示在Dialog上的logobar上是否显示关闭按钮 + * YES:显示,NO,不显示 + */ +@property (nonatomic) BOOL closeEnable; + +/** + *用renren生成一个dialogModel + */ ++(id)modelWithRenren:(Renren *)renren; + +/** + *用renren生成一个dialogModel + */ +-(id)initWithRenren:(Renren *)renren; + +/** + *返回每个model生成的Internal。 + * + */ +-(UIView *)dialogInternal; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogModel.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogModel.m new file mode 100755 index 000000000..85944f725 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogModel.m @@ -0,0 +1,103 @@ +// +// RODialogModel.m +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "RODialogModel.h" +#import "RODialogView.h" + +@implementation RODialogModel + +@synthesize renren = _renren; +@synthesize dialogView = _dialogView; +@synthesize wasLoaded = _wasLoaded; +@synthesize isLoading = _isLoading; +@synthesize tips = _tips; +@synthesize title = _title; +@synthesize closeEnable = _closeEnable; + +- (void)dealloc +{ + [_renren release]; + [_title release]; + [_tips release]; + [super dealloc]; +} + +- (id)init +{ + self = [super init]; + if (self) { + // Initialization code here. + } + return self; +} + + ++(id)modelWithRenren:(Renren *)renren +{ + return [[[self alloc] initWithRenren:renren] autorelease]; +} + +-(id)initWithRenren:(Renren *)renren +{ + self = [self init]; + if (self) { + self.renren = renren; + } + return self; +} + + + +-(UIView *)dialogInternal +{ + //子类必须实现这个方法 + return nil; +} +#pragma mark --protocol RODialogModel + +-(void)dialogShowLoadingView +{ + BOOL autoHidden = self.wasLoaded; + BOOL animated = self.isLoading; + NSString *tipsText = self.tips; + if (tipsText && tipsText.length > 0) { + if (autoHidden) { + [self.dialogView loadingViewShowAndAutoHideWithTips:tipsText]; + }else { + [self.dialogView loadingViewShow:animated tips:tipsText]; + } + } +} + +-(void)dialogHideLoadingView +{ + [self.dialogView loadingViewHide]; +} + +-(void)dialogLoadingViewWasHidden:(RODialogView *)dialogView +{ + +} + +- (void)dialogViewWillAppear +{ + +} + +- (void)dialogViewDidAppear +{ + +} + +- (void)dialogViewWillDisappear +{ + +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogView.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogView.h new file mode 100755 index 000000000..408f9c767 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogView.h @@ -0,0 +1,123 @@ +// +// RODialogView.h +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import +#import "ROGlobalStyle.h" + +@class RODialogModel; +@protocol RODialogInternalDelegate; + + +@interface RODialogView : UIView { + RODialogModel *_dialogModel; + UIView *_internalView; + UIView *_backgroundView; + UIView *_logoBarView; + UIView *_loadingView; + UIButton *_closeButton; + UIDeviceOrientation _orientation; + UIView *_dialogBackgroundView; +} + +/** + * dialog视图业务model + */ +@property(nonatomic, retain)RODialogModel *dialogModel; +/** + * dialog内部视图,对应不同业务model + */ +@property(nonatomic, retain)UIView *internalView; +/** + * dialog的背景视图,圆角的灰黑色边框 + */ +@property(nonatomic, retain)UIView *backgroundView; +/** + * dialog需要执行加载的动画提示视图 + */ +@property(nonatomic, retain)UIView *loadingView; +/** + * dialog的关闭按钮 + */ +@property(nonatomic, retain)UIButton *closeButton; +/** + * dialog的带logo的标题栏视图,含renrenlogo,dialog标题, + */ +@property(nonatomic, retain)UIView *logoBarView; + +/** + * 便利构造一个dialogView + * @param model 内部的业务Model。 + */ ++(RODialogView *)dialogViewWithModel:(RODialogModel *)model; +/** + * 初始化一个dialog + * @param internalView 内部的业务视图。 + * @param visible :YES/NO ,显示/不显示关闭按钮 + * @param title: logoBar的标题 + */ +-(id)initWithInternalView:(UIView *)internalView + closeButton:(BOOL)visible + logoBarTitle:(NSString *)title; +/** + * 返回一个标题为title的logoBarView + * @param title: logoBar的标题 + */ +-(UIView*)logoBarViewWithTitle:(NSString *)title; +/** + * 显示dialog + * @param animated: 是否动画 + */ +-(void)show:(BOOL)animated; +/** + * 关闭dialog + * @param animated: 是否动画 + */ +-(void)dismiss:(BOOL)animated; +/** + * 显示loading视图 + * @param animated: 是否动画 + * @param tipsText: 文本提示,最好不要超过4个字 + */ +-(void)loadingViewShow:(BOOL)animated tips:(NSString *)tipsText; +/** + * 隐藏loading视图 + */ +-(void)loadingViewHide; +/** + * 显示loading视图,并再两秒后自动隐藏 + * @param tipsText: 文本提示,最好不要超过4个字 + */ +-(void)loadingViewShowAndAutoHideWithTips:(NSString *)tipsText; +/** + * 动画结束隐藏loading视图 + * @param tipsText: 文本提示,最好不要超过4个字 + */ +-(void)loadingViewAutoHide:(void *)object; +/** + * dialog是否要响应旋转 + */ +- (BOOL)shouldRotateToOrientation:(UIInterfaceOrientation)orientation; +/** + * dialog的size适配方向 + */ +- (void)sizeToFitOrientation:(BOOL)transform; +/** + * 设置dialog内部视图的方向,让视图适配新的方向 + */ +- (void)setInternalOrientaion; +/** + * 当dialogView未授权时,等待人人授权验证时 + */ +- (void)waitForRenrenAuthorize; +/** + * 当dialogView授权结束时后,执行相关操作。 + */ +- (void)didRenrenAuthorizeSuccess:(BOOL)success; +@end + diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogView.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogView.m new file mode 100755 index 000000000..fdf693067 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/RODialogView.m @@ -0,0 +1,537 @@ +// +// RODialogView.m +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "RODialogView.h" +#import "RODialogModel.h" + + +#define kTransitionDuration 0.3 +#define kPadding 10.0 +#define kBorderWidth 10.0 + + +#define kTagBarLogoImageView 901 +#define kTagBarTitleLabel 902 + +@interface RODialogView() + +- (void)setVerticalFrame; +- (void)setHorizontalFrame; + + +- (CGAffineTransform)transformForOrientation; +- (void)bounce1AnimationStopped; +- (void)bounce2AnimationStopped; + +@end + +@implementation RODialogView + + +@synthesize internalView = _internalView; +@synthesize backgroundView = _backgroundView; +@synthesize logoBarView = _logoBarView; +@synthesize loadingView = _loadingView; +@synthesize closeButton = _closeButton; +@synthesize dialogModel = _dialogModel; + +- (void)dealloc +{ + [_internalView release]; + [_backgroundView release]; + [_logoBarView release]; + [self loadingViewHide]; + [_closeButton release]; + [_dialogModel release]; + [_dialogBackgroundView release]; + [super dealloc]; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + } + return self; +} + +- (id)init { + if (self = [self initWithFrame:CGRectZero]) { + + _orientation = UIDeviceOrientationUnknown; + self.backgroundColor = [UIColor clearColor]; + self.autoresizesSubviews = YES; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.contentMode = UIViewContentModeRedraw; + _dialogBackgroundView = [[UIView alloc] init]; + } + return self; +} + ++(RODialogView *)dialogViewWithModel:(RODialogModel *)model +{ + RODialogView *dialogView = [[RODialogView alloc] initWithInternalView:[model dialogInternal] + closeButton:model.closeEnable + logoBarTitle:model.title]; + dialogView.dialogModel = model; + model.dialogView = dialogView; + return [dialogView autorelease]; +} + +-(id)initWithInternalView:(UIView *)internalView + closeButton:(BOOL)visible + logoBarTitle:(NSString *)title +{ + self = [self init]; + if (self) { + self.internalView = internalView; + if (visible) { + [self.closeButton addTarget:self action:@selector(touchCloseButton:) forControlEvents:UIControlEventTouchDown]; + } + if (title) { + self.logoBarView = [self logoBarViewWithTitle:title]; + } + } + return self; +} + +-(void)touchCloseButton:(id)sender +{ + [self dismiss:YES]; +} + +-(UIButton *)closeButton +{ + if(!_closeButton) { + _closeButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + [_closeButton setTitle:@"关闭" forState:UIControlStateNormal]; + [_closeButton.titleLabel setFont:[UIFont systemFontOfSize:12]]; + [_closeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [_closeButton setBackgroundColor:[ROGlobalStyle renrenBlueColor]]; + } + return _closeButton; +} + +-(UIView *)backgroundView +{ + if (!_backgroundView) { + _backgroundView = [[UIView alloc] init]; + _backgroundView.backgroundColor = [ROGlobalStyle borderBlackColor]; + _backgroundView.alpha = 0.8; + _backgroundView.layer.cornerRadius = 10.0; + } + return _backgroundView; +} + +-(UIView *)logoBarViewWithTitle:(NSString *)title +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + view.backgroundColor = [ROGlobalStyle renrenBlueColor]; + view.autoresizesSubviews = YES; + view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin + | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + UIImageView *logoImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"renren-logo-top-bar.png"]]; + logoImageView.contentMode = UIViewContentModeScaleAspectFit; + logoImageView.tag = kTagBarLogoImageView; + [view addSubview:logoImageView]; + [logoImageView release]; + + UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + titleLabel.backgroundColor = view.backgroundColor; + titleLabel.textColor = [UIColor whiteColor]; + titleLabel.font = [UIFont systemFontOfSize:14]; + titleLabel.text = title; + titleLabel.tag = kTagBarTitleLabel; + [view addSubview:titleLabel]; + [titleLabel release]; + + return [view autorelease]; +} + +-(void)loadingViewShow:(BOOL)animated tips:(NSString *)tipsText +{ + [self loadingViewHide]; + _closeButton.hidden = YES; + _logoBarView.hidden = YES; + _internalView.hidden = YES; + _backgroundView.hidden = YES; + UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 120)]; + [view setAutoresizingMask : UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin]; + view.backgroundColor = [UIColor blackColor]; + view.alpha = 0.8; + view.layer.cornerRadius = 10.0; + + UILabel *tipsLabel = nil; + if (tipsText && tipsText.length != 0) { + tipsLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 20)]; + tipsLabel.font = [UIFont boldSystemFontOfSize:18]; + tipsLabel.backgroundColor = [UIColor clearColor]; + tipsLabel.textColor = [UIColor whiteColor]; + tipsLabel.textAlignment = UITextAlignmentCenter; + tipsLabel.text = tipsText; + } + UIActivityIndicatorView *activity = nil; + if (animated) { + activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + [activity startAnimating]; + } + CGPoint c = CGPointMake(view.frame.size.width*0.5, view.frame.size.height*0.5); + if (tipsLabel && activity) { + activity.center = CGPointMake(c.x,c.y*0.6); + tipsLabel.center = CGPointMake(c.x, c.y+activity.frame.size.width*0.5+tipsLabel.frame.size.height*0.5); + [view addSubview:activity]; + [view addSubview:tipsLabel]; + }else if (activity) { + activity.center = c; + [view addSubview:activity]; + } + if (activity) { + [activity release]; + activity = nil; + } + if (tipsLabel) { + [tipsLabel release]; + tipsLabel = nil; + } + self.loadingView = view; + [view release]; + self.loadingView.center = CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5); + [self addSubview:self.loadingView]; +} + +-(void)loadingViewShowAndAutoHideWithTips:(NSString *)tipsText +{ + [self loadingViewHide]; + _closeButton.hidden = YES; + _logoBarView.hidden = YES; + _internalView.hidden = YES; + _backgroundView.hidden = YES; + UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 120)]; + [view setAutoresizingMask : UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin]; + view.backgroundColor = [UIColor blackColor]; + view.alpha = 0.8; + view.layer.cornerRadius = 10.0; + + UILabel *tipsLabel = nil; + if (tipsText && tipsText.length != 0) { + tipsLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 80, 80, 20)]; + tipsLabel.backgroundColor = [UIColor clearColor]; + tipsLabel.numberOfLines = 0; + // tipsLabel.minimumFontSize = 10.0; + // tipsLabel.adjustsFontSizeToFitWidth = YES; + tipsLabel.font = [UIFont boldSystemFontOfSize:18]; + tipsLabel.textColor = [UIColor whiteColor]; + tipsLabel.textAlignment = UITextAlignmentCenter; + tipsLabel.text = tipsText; + } + CGPoint c = CGPointMake(view.frame.size.width*0.5, view.frame.size.height*0.5); + if (tipsLabel) { + tipsLabel.center = c; + [view addSubview:tipsLabel]; + [tipsLabel release]; + } + self.loadingView = view; + [view release]; + self.loadingView.center = CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5); + [self addSubview:self.loadingView]; + //自动延时消失 + + [UIView beginAnimations:@"lodeHidden" context:nil]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDuration:0.8]; + [UIView setAnimationDidStopSelector:@selector(loadingViewAutoHide:)]; + self.loadingView.alpha = 0.1; + [UIView commitAnimations]; + + // [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(loadingViewAutoHide:) userInfo:nil repeats:NO]; +} + +-(void)loadingViewAutoHide:(void *)object +{ + // [timer invalidate]; + // [self loadingViewHide]; + if ([_dialogModel respondsToSelector:@selector(dialogLoadingViewWasHidden:)]) { + [_dialogModel performSelector:@selector(dialogLoadingViewWasHidden:) withObject:self]; + } +} + + +-(void)loadingViewHide +{ + if (_loadingView != nil) { + if (_loadingView.superview) { + [_loadingView removeFromSuperview]; + } + self.loadingView = nil; + } + _closeButton.hidden = NO; + _logoBarView.hidden = NO; + _internalView.hidden = NO; + _backgroundView.hidden = NO; +} + +-(void)show:(BOOL)animated +{ + [self sizeToFitOrientation:NO]; + [self addSubview:self.backgroundView]; + if (self.logoBarView) { + [self addSubview:self.logoBarView]; + } + if (_closeButton) { + [self addSubview:self.closeButton]; + } + [self addSubview:self.internalView]; + + [_dialogModel performSelector:@selector(dialogViewWillAppear)]; + UIWindow* window = [UIApplication sharedApplication].keyWindow; + if (!window) { + window = [[UIApplication sharedApplication].windows objectAtIndex:0]; + } + _dialogBackgroundView.frame = window.frame; + [window addSubview:_dialogBackgroundView]; + [window addSubview:self]; + if (animated) { + self.transform = CGAffineTransformScale([self transformForOrientation], 0.001, 0.001); + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration/1.5]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(bounce1AnimationStopped)]; + self.transform = CGAffineTransformScale([self transformForOrientation], 1.1, 1.1); + [UIView commitAnimations]; + } + [_dialogModel performSelector:@selector(dialogViewDidAppear)]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(deviceOrientationDidChange:) + name:@"UIDeviceOrientationDidChangeNotification" + object:nil]; +} + +- (void)deviceOrientationDidChange:(NSNotification*)notifition { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if ([self shouldRotateToOrientation:orientation]) { + CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:duration]; + [self sizeToFitOrientation:YES]; + [self setInternalOrientaion]; + [UIView commitAnimations]; + } +} + +-(void)dismiss:(BOOL)animated; +{ + if ([_dialogModel respondsToSelector:@selector(dialogViewWillDisappear)]) { + [_dialogModel performSelector:@selector(dialogViewWillDisappear)]; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)]; + self.alpha = 0; + [UIView commitAnimations]; + } else { + [self removeFromSuperview]; + } +} + +-(void)removeFromSuperview{ + [_dialogBackgroundView removeFromSuperview]; + [super removeFromSuperview]; +} +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect +{ + // Drawing code +} +*/ + + +- (BOOL)shouldRotateToOrientation:(UIInterfaceOrientation)orientation { + if (_orientation == (UIDeviceOrientation)orientation) { + return NO; + } else { + return (UIDeviceOrientation)orientation == UIDeviceOrientationLandscapeLeft + || (UIDeviceOrientation)orientation == UIDeviceOrientationLandscapeRight + || (UIDeviceOrientation)orientation == UIDeviceOrientationPortrait + || (UIDeviceOrientation)orientation == UIDeviceOrientationPortraitUpsideDown; + } +} + +- (CGAffineTransform)transformForOrientation { + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + if (orientation == UIInterfaceOrientationLandscapeLeft) { + return CGAffineTransformMakeRotation(M_PI*1.5); + } else if (orientation == UIInterfaceOrientationLandscapeRight) { + return CGAffineTransformMakeRotation(M_PI/2); + } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { + return CGAffineTransformMakeRotation(-M_PI); + } else { + return CGAffineTransformIdentity; + } +} + +- (void)sizeToFitOrientation:(BOOL)transform { + if (transform) { + self.transform = CGAffineTransformIdentity; + } + + CGRect frame = [UIScreen mainScreen].applicationFrame; + CGPoint center = CGPointMake( + frame.origin.x + frame.size.width/2.0, + frame.origin.y + frame.size.height/2.0); +// CGFloat scale_factor = 1.0f; +// if ([ROGlobalStyle isPad]) { +// // On the iPad the dialog's dimensions should only be 60% of the screen's +// scale_factor = 0.6f; +// } +// +// CGFloat width = floor(scale_factor * frame.size.width) - kPadding * 2; +// CGFloat height = floor(scale_factor * frame.size.height) - kPadding * 2; + + CGFloat width,height; + _orientation = (UIDeviceOrientation)([UIApplication sharedApplication].statusBarOrientation); + if (UIInterfaceOrientationIsLandscape(_orientation)) { + width = 460; + height = 280; + self.frame = CGRectMake(kPadding, kPadding, width,height); + } else { + width = 300; + height = 440; + self.frame = CGRectMake(kPadding, kPadding, width, height); + } + self.center = center; + + if (transform) { + self.transform = [self transformForOrientation]; + } +} + +- (void)bounce1AnimationStopped { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration/2]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(bounce2AnimationStopped)]; + self.transform = CGAffineTransformScale([self transformForOrientation], 0.9, 0.9); + [UIView commitAnimations]; +} + +- (void)bounce2AnimationStopped { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:kTransitionDuration/2]; + self.transform = [self transformForOrientation]; + [UIView commitAnimations]; +} + +- (void)layoutSubviews{ + [super layoutSubviews]; + if (UIInterfaceOrientationIsLandscape(_orientation)) { + //设置横屏时布局 + [self setHorizontalFrame]; + } else { + //设置竖屏时布局 + [self setVerticalFrame]; + } + +} + +-(void)setVerticalFrame +{ + CGRect viewFrame = self.bounds; + if (self.loadingView) { + self.loadingView.center = CGPointMake(viewFrame.size.width*0.5, viewFrame.size.height*0.5); + } + self.backgroundView.frame = viewFrame; + CGRect logoBarFrame = CGRectZero; + if (self.logoBarView) { + _logoBarView.frame = CGRectMake(kPadding, + kPadding, + viewFrame.size.width-3*kPadding, + 25); + UIImageView *logo = (UIImageView *)[_logoBarView viewWithTag:kTagBarLogoImageView]; + logo.frame = CGRectMake(0, 0,43,24); + UILabel *title = (UILabel *)[_logoBarView viewWithTag:kTagBarTitleLabel]; + title.frame = CGRectMake(logo.frame.size.width+10, + 0, + _logoBarView.frame.size.width - logo.frame.size.width, + _logoBarView.frame.size.height); + logoBarFrame = _logoBarView.frame; + + } + if (_closeButton) { + _closeButton.frame = CGRectMake(viewFrame.size.width - kPadding - 30, kPadding, 30, 25); + [self bringSubviewToFront:_closeButton]; + } + self.internalView.frame = CGRectMake(kPadding, + kPadding + logoBarFrame.size.height, + viewFrame.size.width - 2*kPadding, + viewFrame.size.height - 2*kPadding - logoBarFrame.size.height); +} + +-(void)setHorizontalFrame +{ + CGRect viewFrame = self.bounds; + self.backgroundView.frame = viewFrame; + if (self.loadingView) { + self.loadingView.center = CGPointMake(viewFrame.size.width*0.5, viewFrame.size.height*0.5); + } + CGRect logoBarFrame = CGRectZero; + if (self.logoBarView) { + _logoBarView.frame = CGRectMake(kPadding, + kPadding, + viewFrame.size.width-2*kPadding, + 25); + UIImageView *logo = (UIImageView *)[_logoBarView viewWithTag:kTagBarLogoImageView]; + //logo.frame = CGRectMake(0, 0, logo.image.size.width, logo.image.size.height); + logo.frame = CGRectMake(0, 0,43,24); + UILabel *title = (UILabel *)[_logoBarView viewWithTag:kTagBarTitleLabel]; + title.frame = CGRectMake(logo.frame.size.width+10, + 0, + _logoBarView.frame.size.width - logo.frame.size.width-10, + _logoBarView.frame.size.height); + logoBarFrame = _logoBarView.frame; + + } + if (_closeButton) { + _closeButton.frame = CGRectMake(viewFrame.size.width - kPadding - 30, kPadding, 30, 25); + [self bringSubviewToFront:_closeButton]; + } + self.internalView.frame = CGRectMake(kPadding, + kPadding + logoBarFrame.size.height, + viewFrame.size.width - 2*kPadding, + viewFrame.size.height - 2*kPadding - logoBarFrame.size.height); +} + +- (void)setInternalOrientaion +{ + [self.internalView setNeedsLayout]; +} + +- (void)waitForRenrenAuthorize +{ + [self retain];//保证等待过程中不被release掉。 +} + +- (void)didRenrenAuthorizeSuccess:(BOOL)success +{ + [self autorelease]; + if (success) { + [self show:YES]; + } + else + { + //认证失败默认不做什么 + } +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoDialogModel.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoDialogModel.h new file mode 100755 index 000000000..a0c1b2ffa --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoDialogModel.h @@ -0,0 +1,44 @@ +// +// ROPublishPhotoDialogModal.h +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "RODialogModel.h" +#import "Renren.h" +@class ROPublishPhotoInternal; +@protocol RenrenDelegate; + +@interface ROPublishPhotoDialogModel : RODialogModel { + UIImage *_photo; + NSString *_caption; + NSString *_userName; + NSString *_headUrl; + + ROPublishPhotoInternal *_internal; +} +/** + *准备上传的照片photo + */ +@property (nonatomic ,retain)UIImage *photo; +/** + *上传照片的描述caption + */ +@property (nonatomic ,copy)NSString *caption; +/** + *上传者的姓名 + */ +@property (nonatomic ,copy)NSString *userName; +/** + *上传者的头像 + */ +@property (nonatomic ,copy)NSString *headUrl; + +- (void)upload; + +- (void)cancel; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoDialogModel.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoDialogModel.m new file mode 100755 index 000000000..b6a57caef --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoDialogModel.m @@ -0,0 +1,267 @@ +// +// ROPublishPhotoDialogModal.m +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROConnect.h" +#import "Renren.h" +#import "ROPublishPhotoDialogModel.h" + +@interface ROPublishPhotoDialogModel () + +- (void)setInteralUserInfo; +- (void)requestUserInfo; +- (void)uploadSuccess; +- (void)uploadFail; +- (void)dealWithError:(ROError *)error; + + +@end + +@implementation ROPublishPhotoDialogModel + +@synthesize photo = _photo; +@synthesize userName = _userName; +@synthesize headUrl = _headUrl; +@synthesize caption = _caption; + +- (void)dealloc +{ + [_photo release]; + [_userName release]; + [_headUrl release]; + [_caption release]; + [_internal release]; + [super dealloc]; +} + +-(id)initWithRenren:(Renren *)renren +{ + self = [super initWithRenren:renren]; + if (self) { + self.title = @"上传照片至人人"; + self.closeEnable = YES; + } + return self; +} +- (id)init +{ + self = [super init]; + if (self) { + // Initialization code here. + } + + return self; +} + +-(UIView *)dialogInternal +{ + if(_internal == nil){ + _internal = [[ROPublishPhotoInternal alloc] initWithFrame:CGRectZero]; + _internal.dialogModel = self; + [self setInteralUserInfo]; + } + return _internal; +} + +-(void)dialogLoadingViewWasHidden:(RODialogView *)dialogView +{ + if (self.dialogView == dialogView) { + //还可以做一些其他的操作 + [self.dialogView dismiss:YES]; + } +} + +- (void)setInteralUserInfo +{ + if (!_headUrl || !_userName) { + [self requestUserInfo]; + }else { + _internal.userNameLabel.text = self.userName; + _internal.headImageView.imageUrl = self.headUrl; + } +} + +- (void)requestUserInfo +{ + ROUserInfoRequestParam *param = [[ROUserInfoRequestParam alloc] init]; + [_renren getUsersInfo:param andDelegate:self]; + [param release]; +} + +- (void)upload +{ + self.caption = _internal.captionTextView.text; + if (self.caption.length > 140) { + UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"照片描述不能超过140字符" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; + [alert show]; + [alert release]; + return; + } + self.tips = @"上传中..."; + self.isLoading = YES; + self.wasLoaded = NO; + [self dialogShowLoadingView]; + ROPublishPhotoRequestParam *param = [[ROPublishPhotoRequestParam alloc] init]; + param.caption = _caption; + param.imageFile = _photo; + [_renren publishPhoto:param andDelegate:self]; + [param release]; +} + +- (void)cancel +{ + [self.dialogView dismiss:YES]; +} + +- (void)uploadSuccess +{ + self.tips = @"上传成功"; + self.wasLoaded = YES; + [self dialogShowLoadingView]; +} + +- (void)uploadFail +{ + self.tips = @"上传失败"; + self.wasLoaded = YES; + [self dialogShowLoadingView]; +} + +- (void)dialogViewWillAppear +{ + [super dialogViewWillAppear]; + [self setInteralUserInfo]; +} + +- (void)dealWithError:(ROError *)error +{ + int errorCode = error.code; + NSString *errorAlertString = error.localizedDescription; + switch (errorCode) { + case 20100: + errorAlertString = @"您所选择的相册已删除,请重新选择相册"; + break; + case 20101: + errorAlertString = @"上传照片失败,请稍后重试"; + break; + case 20102: + errorAlertString = @"暂不支持此格式照片,请重新选择(20102)"; + break; + case 20103: + errorAlertString = @"暂不支持此格式照片,请重新选择(20103)"; + break; + case 20105: + errorAlertString = @"请输入相册密码"; + break; + default: + break; + } + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:errorAlertString delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; + [alert show]; + [alert release]; +} + +#pragma mark -- RenrenDelegate Method +/** + * 接口请求成功,第三方开发者实现这个方法 + */ +- (void)renren:(Renren *)renren requestDidReturnResponse:(ROResponse*)response +{ + + if (response.error) { + if ([response.param isKindOfClass:[ROPublishPhotoRequestParam class]]) { + [self renren:renren requestFailWithError:response.error]; + } + return; + } + if ([response.rootObject isKindOfClass:[NSArray class]]) { + if ([(NSArray *)response.rootObject count] == 0) { + return; + } + ROUserResponseItem *item = [(NSArray *)response.rootObject objectAtIndex:0]; + self.userName = item.name; + self.headUrl = item.tinyUrl; + [self setInteralUserInfo]; + } + if ([response.rootObject isKindOfClass:[ROPublishPhotoResponseItem class]]) { + ROPublishPhotoResponseItem *item = (ROPublishPhotoResponseItem *)response.rootObject; + NSLog(@"%@",item.responseDictionary); + [self uploadSuccess]; + } + +} + +/** + * 接口请求失败,第三方开发者实现这个方法 + */ +- (void)renren:(Renren *)renren requestFailWithError:(ROError*)error +{ + /* + self.tips = [error localizedDescription]; + self.wasLoaded = YES; + */ + if (renren == self.renren) { + if ([error.domain isEqualToString:kROErrorDomain]) { + NSString* apiMethod = [error methodForRestApi]; + if ([apiMethod isEqualToString:@"photos.upload"]) { + [self dialogHideLoadingView]; + [self dealWithError:error]; + } + } + else + { + [self dialogHideLoadingView]; + [self dealWithError:error]; + } + } + NSLog(@"Upload Photo Dialog View Error:%@",[error localizedDescription]); + + + +} + + + +/** + * 授权登录成功,第三方开发者实现这个方法 + */ +- (void)renrenDidLogin:(Renren *)renren +{ + if (renren == self.renren) { + //登陆成功了 + [self.dialogView didRenrenAuthorizeSuccess:YES]; + } + +} +/** + * renren取消Dialog时调用,第三方开发者实现这个方法 + */ +- (void)renrenDialogDidCancel:(Renren *)renren +{ + if (renren == self.renren) { + //登陆失败 + [self.dialogView didRenrenAuthorizeSuccess:NO]; + } + +} + +/** + * 授权登录失败,第三方开发者实现这个方法 + */ +- (void)renren:(Renren *)renren loginFailWithError:(ROError*)error + +{ + if (renren == self.renren) { + //登陆失败 + [self.dialogView didRenrenAuthorizeSuccess:NO]; + NSLog(@"%@",error.localizedDescription); + } + +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoInternal.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoInternal.h new file mode 100755 index 000000000..b27ace214 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoInternal.h @@ -0,0 +1,42 @@ +// +// ROPublishPhotoInternal.h +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import +#import "ROConnect.h" + +@class ROImageView; +@class ROPublishPhotoDialogModel; + +@interface ROPublishPhotoInternal : UIView { + ROPublishPhotoDialogModel * _dialogModel; + UILabel *_userNameLabel; + ROImageView *_headImageView; + UIImageView *_photoImageView; + UITextView *_captionTextView; + UILabel *_captionLimitLabel; + UIButton *_uploadButton; + UIButton *_cancelButton; + + UIImageView *_headBackgroundView; + UIImageView *_captionBackgroundView; + UIImageView *_photoBackgroundView; + UIImageView *_optionBackgroundView; + BOOL _isKeywordHidden; +} +@property (nonatomic ,assign)ROPublishPhotoDialogModel *dialogModel; +@property (nonatomic ,retain)UILabel *userNameLabel; +@property (nonatomic ,retain)ROImageView *headImageView; +@property (nonatomic ,retain)UIImageView *photoImageView; +@property (nonatomic ,retain)UITextView *captionTextView; +@property (nonatomic ,retain)UILabel *captionLimitLabel; + +- (void)setCaptionLimitTips; +- (void)setVerticalFrame; +- (void)setHorizontalFrame; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoInternal.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoInternal.m new file mode 100755 index 000000000..df0bdb072 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Sample UI/UploadPhotoDialog/ROPublishPhotoInternal.m @@ -0,0 +1,237 @@ +// +// ROPublishPhotoInternal.m +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROPublishPhotoInternal.h" + +@implementation ROPublishPhotoInternal + +@synthesize dialogModel = _dialogModel; +@synthesize userNameLabel = _userNameLabel; +@synthesize headImageView = _headImageView; +@synthesize photoImageView = _photoImageView; +@synthesize captionTextView = _captionTextView; +@synthesize captionLimitLabel = _captionLimitLabel; +- (void)dealloc +{ + self.dialogModel = nil; + [_userNameLabel release]; + [_headImageView release]; + [_photoImageView release]; + [_captionTextView release]; + [_cancelButton release]; + [_uploadButton release]; + [_captionLimitLabel release]; + [_photoBackgroundView release]; + [_captionBackgroundView release]; + [_headBackgroundView release]; + [_optionBackgroundView release]; + [super dealloc]; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + self.autoresizesSubviews = YES; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.contentMode = UIViewContentModeRedraw; + self.backgroundColor = [ROGlobalStyle renrenPageColor]; + + _optionBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"bottom-bar.png"]stretchableImageWithLeftCapWidth:1 topCapHeight:5]]; + [self addSubview:_optionBackgroundView]; + + _userNameLabel = [[UILabel alloc] init]; + _userNameLabel.font = [UIFont systemFontOfSize:18.0]; + _userNameLabel.backgroundColor = [UIColor clearColor]; + [self addSubview:_userNameLabel]; + + _headImageView = [[ROImageView alloc] init]; + [self addSubview:_headImageView]; + + _photoBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"photo-frame.png"] stretchableImageWithLeftCapWidth:4 topCapHeight:4]]; + _photoBackgroundView.contentMode = UIViewContentModeScaleToFill; + [self addSubview:_photoBackgroundView]; + _photoImageView = [[UIImageView alloc] init]; + _photoImageView.contentMode = UIViewContentModeScaleAspectFit; + [self addSubview:_photoImageView]; + + _captionBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"input-frame.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]]; + _captionBackgroundView.contentMode = UIViewContentModeScaleToFill; + [self addSubview:_captionBackgroundView]; + _captionTextView = [[UITextView alloc] init]; + _captionTextView.delegate = self; + _captionTextView.backgroundColor = [UIColor clearColor]; + _captionTextView.font = [UIFont systemFontOfSize:14.0]; + [self addSubview:_captionTextView]; + + _uploadButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + [_uploadButton setTitle:@"上传" forState:UIControlStateNormal]; + [_uploadButton addTarget:self action:@selector(doUpload:) forControlEvents:UIControlEventTouchUpInside]; + _uploadButton.titleLabel.font = [UIFont systemFontOfSize:15]; + [_uploadButton setBackgroundImage:[UIImage imageNamed:@"small-button-normal.png"] forState:UIControlStateNormal]; + [self addSubview:_uploadButton]; + _cancelButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; + [_cancelButton setTitle:@"取消" forState:UIControlStateNormal]; + [_cancelButton addTarget:self action:@selector(doCancel:) forControlEvents:UIControlEventTouchUpInside]; + _cancelButton.titleLabel.font = [UIFont systemFontOfSize:15]; + [_cancelButton setBackgroundImage:[UIImage imageNamed:@"small-button-normal.png"] forState:UIControlStateNormal]; + [self addSubview:_cancelButton]; + + _captionLimitLabel = [[UILabel alloc] init]; + _captionLimitLabel.backgroundColor = [UIColor clearColor]; + _captionLimitLabel.font = [UIFont systemFontOfSize:12]; + _captionLimitLabel.textColor = [UIColor darkGrayColor]; + _captionLimitLabel.textAlignment = UITextAlignmentRight; + [self addSubview:_captionLimitLabel]; + + _headBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"head-frame.png"]]; + _headBackgroundView.contentMode = UIViewContentModeScaleToFill; + [self addSubview:_headBackgroundView]; + + + + + } + return self; +} + +#pragma mark UITextView Delegate +- (BOOL)textViewShouldBeginEditing:(UITextView *)textView +{ + _isKeywordHidden = NO; + return YES; +} + +- (BOOL)textViewShouldEndEditing:(UITextView *)textView +{ + + [_captionTextView resignFirstResponder]; + return YES; +} + +- (void)textViewDidChange:(UITextView *)textView +{ + [self setCaptionLimitTips]; +} + +- (void)textViewDidBeginEditing:(UITextView *)textView +{ + _isKeywordHidden = NO; +} + +- (void)textViewDidEndEditing:(UITextView *)textView +{ + _isKeywordHidden = YES; + [textView scrollRangeToVisible:NSMakeRange(0, 0)]; +} + +- (void)setCaptionLimitTips +{ + int captionLen = 0; + if (_captionTextView.text) { + captionLen = _captionTextView.text.length; + } + _captionLimitLabel.text = [NSString stringWithFormat:@"%d/140",captionLen]; + _captionLimitLabel.textColor = [UIColor darkGrayColor]; + if (captionLen > 140) { + _captionLimitLabel.textColor = [UIColor redColor]; + } +} + +- (void)setDialogModel:(ROPublishPhotoDialogModel *)dialogModel +{ + _dialogModel = dialogModel; + self.captionTextView.text = dialogModel.caption; + self.photoImageView.image = dialogModel.photo; + [self setCaptionLimitTips]; +} + +- (void)doUpload:(id)sender +{ + [self.dialogModel upload]; +} + +- (void)doCancel:(id)sender +{ + [self.dialogModel cancel]; +} + +- (void)layoutSubviews{ + [super layoutSubviews]; + + if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) { + //设置横屏时布局 + [self setHorizontalFrame]; + } else { + //设置竖屏时布局 + [self setVerticalFrame]; + } +} + //设置竖屏时布局 +-(void)setVerticalFrame +{ + _userNameLabel.frame = CGRectMake(70, 10, 200, 23); + + _headImageView.frame = CGRectMake(10,10, 50, 50); + _headBackgroundView.frame = CGRectInset(_headImageView.frame, -8, -8); + + + _captionBackgroundView.frame = CGRectMake(10, 70, 260, 120); + _captionTextView.frame = CGRectInset(_captionBackgroundView.frame, 2, 2); + _captionTextView.contentSize = _captionTextView.bounds.size; + + _photoBackgroundView.frame = CGRectMake(10, 202.5, 260, 130); + _photoImageView.frame = CGRectInset(_photoBackgroundView.frame, 4, 4); + + _uploadButton.frame = CGRectMake(140, 355, 60, 30); + _cancelButton.frame = CGRectMake(210, 355, 60, 30); + _captionLimitLabel.frame = CGRectMake(190, 50, 80, 20); + _optionBackgroundView.frame = CGRectMake(0, self.frame.size.height-50, self.frame.size.width, 50); +} + //设置横屏时布局 +-(void)setHorizontalFrame +{ + _userNameLabel.frame = CGRectMake(70, 0, 340, 23); + + _headImageView.frame = CGRectMake(10,5, 50, 50); + _headBackgroundView.frame = CGRectInset(_headImageView.frame, -8, -8); + + _captionBackgroundView.frame = CGRectMake(70, 25, 355, 55); + _captionTextView.frame = CGRectInset(_captionBackgroundView.frame, 4, 4); + _captionTextView.contentSize = _captionTextView.bounds.size; + + _photoBackgroundView.frame = CGRectMake(70, 87.5, 200, 100); + _photoImageView.frame = CGRectInset(_photoBackgroundView.frame, 4, 4); + + _uploadButton.frame = CGRectMake(290, 200, 60, 30); + _cancelButton.frame = CGRectMake(360, 200, 60, 30); + _captionLimitLabel.frame = CGRectMake(345, 5, 80, 20); + _optionBackgroundView.frame = CGRectMake(0, self.frame.size.height-40, self.frame.size.width, 40); +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + UITouch *touch = [touches anyObject]; + if (!CGRectContainsPoint(_captionTextView.frame,[touch locationInView:self])) { + if (!_isKeywordHidden) { + [self textViewShouldEndEditing:_captionTextView]; + } + } +} +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect +{ + // Drawing code +} +*/ + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/ROUtility.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/ROUtility.h new file mode 100755 index 000000000..5488d8c90 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/ROUtility.h @@ -0,0 +1,67 @@ +// +// ROUtility.h +// RenrenSDKDemo +// +// Created by Tora on 11-8-23. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import + +/** + * Renren SDK中的工具类。 + * 包含了主要用于数据处理和转换的工具方法集。 + * 所有方法均以类方法形式调用,使用时,类型本身没有实例化的必要。 + */ + +@interface ROUtility : NSObject + +/** + * 解析URL参数的工具方法。 + */ ++ (NSDictionary *)parseURLParams:(NSString *)query; + +/* + * 使用传入的baseURL地址和参数集合构造含参数的请求URL的工具方法。 + */ ++ (NSURL*)generateURL:(NSString*)baseURL params:(NSDictionary*)params; + +/* + * 根据指定的参数名,从URL中找出并返回对应的参数值。 + */ ++ (NSString *)getValueStringFromUrl:(NSString *)url forParam:(NSString *)param; + +/** + * 对输入的字符串进行MD5计算并输出验证码的工具方法。 + */ ++ (NSString *)md5HexDigest:(NSString *)input; + +/** + * 针对人人开放平台接口传参需求生成随机CallId的工具方法。 + */ ++ (NSString *)generateCallId; + +/** + * 针对人人开放平台接口传参需求计算sig码的工具方法。 + */ ++ (NSString *)generateSig:(NSMutableDictionary *)paramsDict secretKey:(NSString *)secretKey; + +/** + * 对字符串进行URL编码转换。 + */ ++ (NSString*)encodeString:(NSString*)string urlEncode:(NSStringEncoding)encoding; + +/** + * 将日期字符串转换为字符串类型。 + */ ++ (NSDate *)getDateFromString:(NSString *)dateTime; + +/** + * 将传入的图像加文字水印。 + */ ++ (UIImage *)getImageWithWatermark:(UIImage *)inImage; + +@end + + diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/ROUtility.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/ROUtility.m new file mode 100755 index 000000000..01f2c5c03 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/ROUtility.m @@ -0,0 +1,190 @@ +// +// ROUtility.m +// RenrenSDKDemo +// +// Created by Tora on 11-8-23. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROUtility.h" +#import +#import "JSON.h" + +// 给上传图像加的水印文字常量 +#define kWatermarkString @"renren-inc.com" + +@implementation ROUtility + +- (void)dealloc { + [super dealloc]; +} + +- (id)init +{ + return nil; +} + +/** + * 解析URL参数的工具方法。 + */ ++ (NSDictionary *)parseURLParams:(NSString *)query{ + NSArray *pairs = [query componentsSeparatedByString:@"&"]; + NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; + for (NSString *pair in pairs) { + NSArray *kv = [pair componentsSeparatedByString:@"="]; + if (kv.count == 2) { + NSString *val =[[kv objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + [params setObject:val forKey:[kv objectAtIndex:0]]; + } + } + return [params autorelease]; +} + +/* + * 使用传入的baseURL地址和参数集合构造含参数的请求URL的工具方法。 + */ ++ (NSURL*)generateURL:(NSString*)baseURL params:(NSDictionary*)params { + if (params) { + NSMutableArray* pairs = [NSMutableArray array]; + for (NSString* key in params.keyEnumerator) { + NSString* value = [params objectForKey:key]; + NSString* escaped_value = (NSString *)CFURLCreateStringByAddingPercentEscapes( + NULL, /* allocator */ + (CFStringRef)value, + NULL, /* charactersToLeaveUnescaped */ + (CFStringRef)@"!*'();:@&=+$,/?%#[]", + kCFStringEncodingUTF8); + + [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, escaped_value]]; + [escaped_value release]; + } + + NSString* query = [pairs componentsJoinedByString:@"&"]; + NSString* url = [NSString stringWithFormat:@"%@?%@", baseURL, query]; + return [NSURL URLWithString:url]; + } else { + return [NSURL URLWithString:baseURL]; + } +} + +/* + * 根据指定的参数名,从URL中找出并返回对应的参数值。 + */ ++ (NSString *)getValueStringFromUrl:(NSString *)url forParam:(NSString *)param { + NSString * str = nil; + NSRange start = [url rangeOfString:[param stringByAppendingString:@"="]]; + if (start.location != NSNotFound) { + NSRange end = [[url substringFromIndex:start.location + start.length] rangeOfString:@"&"]; + NSUInteger offset = start.location+start.length; + str = end.location == NSNotFound + ? [url substringFromIndex:offset] + : [url substringWithRange:NSMakeRange(offset, end.location)]; + str = [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + } + + return str; +} + +/** + * 对输入的字符串进行MD5计算并输出验证码的工具方法。 + */ ++ (NSString *)md5HexDigest:(NSString *)input{ + const char* str = [input UTF8String]; + unsigned char result[CC_MD5_DIGEST_LENGTH]; + CC_MD5(str, strlen(str), result); + NSMutableString *returnHashSum = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2]; + for (int i=0; i" withString:@"%3E" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [escaped length])]; + [escaped replaceOccurrencesOfString:@"\"" withString:@"%22" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [escaped length])]; + [escaped replaceOccurrencesOfString:@"\n" withString:@"%0A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [escaped length])]; + + return escaped; +} + ++ (NSDate *)getDateFromString:(NSString *)dateTime +{ + NSDate *expirationDate =nil; + if (dateTime != nil) { + int expVal = [dateTime intValue]; + if (expVal == 0) { + expirationDate = [NSDate distantFuture]; + } else { + expirationDate = [NSDate dateWithTimeIntervalSinceNow:expVal]; + } + } + + return expirationDate; +} + ++ (UIImage *)getImageWithWatermark:(UIImage *)inImage{ + CGRect imageViewFrame = CGRectMake(0, 0, inImage.size.width, inImage.size.height); + UIImageView *imageView = [[UIImageView alloc] initWithImage:inImage]; + imageView.frame = imageViewFrame; + UILabel *label = [[UILabel alloc] init]; + CGRect labelFrame = CGRectMake(10, imageViewFrame.size.height-40, imageViewFrame.size.width-20, 30); + label.frame = labelFrame; + label.text = kWatermarkString; + label.textAlignment = UITextAlignmentRight; + label.backgroundColor = [UIColor clearColor]; + [imageView addSubview:label]; + + UIGraphicsBeginImageContext(imageViewFrame.size); + [imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; + UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return outImage; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROCloseButton.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROCloseButton.h new file mode 100755 index 000000000..a83b6d180 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROCloseButton.h @@ -0,0 +1,15 @@ +// +// ROCloseButton.h +// RenrenSDKDemo +// +// Created by Winston on 11-8-24. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import + +@interface ROCloseButton : UIButton + ++(ROCloseButton *)closeButtonForRODialog; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROCloseButton.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROCloseButton.m new file mode 100755 index 000000000..b453e35b2 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROCloseButton.m @@ -0,0 +1,48 @@ +// +// ROCloseButton.m +// RenrenSDKDemo +// +// Created by Winston on 11-8-24. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROCloseButton.h" + +@implementation ROCloseButton + +- (id)init +{ + self = [super init]; + if (self) { + // Initialization code here. + } + + return self; +} + ++(ROCloseButton *)closeButtonForRODialog +{ + return [[[ROCloseButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)] autorelease]; +} + +-(void)drawRect:(CGRect)rect +{ + + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); + CGContextSetLineWidth(context, 2.0); + CGContextStrokeEllipseInRect(context, CGRectMake(2.5, 2.5, 25.0, 25.0)); + CGContextFillEllipseInRect(context, CGRectMake(2.5+0.5, 2.5+0.5, 24.0, 24.0)); + CGContextDrawPath(context, kCGPathFillStroke); + CGContextMoveToPoint(context, 2.5+3.5,2.5+3.5); + CGContextAddLineToPoint(context, 2.5+21.5, 2.5+21.5); + CGContextStrokePath(context); + CGContextMoveToPoint(context, 2.5+3.5, 2.5+21.5); + CGContextAddLineToPoint(context,2.5+ 21.5,2.5+ 3.5); + CGContextStrokePath(context); + +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROGlobalStyle.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROGlobalStyle.h new file mode 100755 index 000000000..6f337a3df --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROGlobalStyle.h @@ -0,0 +1,35 @@ +// +// ROGlobalStyle.h +// SimpleDemo +// +// Created by Winston on 11-8-19. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import +#import +#import + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Color helpers + +#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] +#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f \ +alpha:(a)] + +#define HSVCOLOR(h,s,v) [UIColor colorWithHue:(h) saturation:(s) value:(v) alpha:1] +#define HSVACOLOR(h,s,v,a) [UIColor colorWithHue:(h) saturation:(s) value:(v) alpha:(a)] + +#define RGBA(r,g,b,a) (r)/255.0f, (g)/255.0f, (b)/255.0f, (a) + + +@interface ROGlobalStyle : NSObject + ++(UIColor *)renrenBlueColor; ++(UIColor *)renrenPageColor; ++(UIColor *)borderGrayColor; ++(UIColor *)borderBlackColor; ++(UIColor *)borderBlueColor; ++(BOOL)isPad; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROGlobalStyle.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROGlobalStyle.m new file mode 100755 index 000000000..e6042e7ad --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROGlobalStyle.m @@ -0,0 +1,41 @@ +// +// ROGlobalStyle.m +// SimpleDemo +// +// Created by Winston on 11-8-19. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import "ROGlobalStyle.h" + +@implementation ROGlobalStyle + ++(UIColor *)renrenBlueColor{ + return RGBCOLOR(0, 94, 172); +} + ++(UIColor *)renrenPageColor{ + return RGBCOLOR(243, 250, 255); +} + ++(UIColor *)borderGrayColor{ + return RGBACOLOR(76.5, 76.5, 76.5, 0.8); +} + ++(UIColor *)borderBlackColor{ + return RGBCOLOR(76.5, 76.5, 76.5); +} + ++(UIColor *)borderBlueColor{ + return RGBCOLOR(58.7, 89.3, 153.0); +} + ++(BOOL)isPad{ +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200 + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + return YES; + } +#endif + return NO; +} +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROImageView.h b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROImageView.h new file mode 100755 index 000000000..87bb5e98d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROImageView.h @@ -0,0 +1,31 @@ +// +// ROImageView.h +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// +#import +#import + +@interface ROImageView : UIView{ + + UIImageView *_imageView; + UIActivityIndicatorView *_activityIndcator; + NSString *_imageUrl; + NSMutableData *_imageData; + NSURLResponse *_imageResponse; + NSURLConnection *_imageConnection; +} +@property (nonatomic ,retain)UIImageView *imageView; +@property (nonatomic ,copy)NSString *imageUrl; +@property (nonatomic ,retain)UIActivityIndicatorView *activityIndcator; +@property (nonatomic ,retain)NSMutableData *imageData; +@property (nonatomic ,retain)NSURLResponse *imageResponse; +@property (nonatomic ,retain)NSURLConnection *imageConnection; + +- (void)setImageUrl:(NSString *)imageUrl; +- (void)setImage:(UIImage *)image; +- (UIImage *)image; +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROImageView.m b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROImageView.m new file mode 100755 index 000000000..a9f39c578 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/RRConnect/Renren/Tools/UI/ROImageView.m @@ -0,0 +1,127 @@ +// +// ROImageView.m +// SimpleDemo +// +// Created by Winston on 11-8-18. +// Copyright 2011年 Renren Inc. All rights reserved. +// - Powered by Team Pegasus. - +// + +#import "ROImageView.h" + +@implementation ROImageView + +@synthesize imageUrl = _imageUrl; +@synthesize imageView = _imageView; +@synthesize activityIndcator = _activityIndcator; +@synthesize imageData = _imageData; +@synthesize imageResponse = _imageResponse; +@synthesize imageConnection = _imageConnection; + +- (void)dealloc +{ + [_imageData release]; + [_imageUrl release]; + [_imageView release]; + [_activityIndcator release]; + [_imageResponse release]; + [_imageConnection release]; + [super dealloc]; + +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + self.backgroundColor = [UIColor lightGrayColor]; + _imageView = [[UIImageView alloc] initWithFrame:self.bounds]; + _imageView.contentMode = UIViewContentModeScaleAspectFill; + _imageView.clearsContextBeforeDrawing = YES; + [self addSubview:_imageView]; + self.clearsContextBeforeDrawing = YES; + } + return self; +} + +- (UIActivityIndicatorView *)activityIndcator +{ + if (!_activityIndcator) { + _activityIndcator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + _activityIndcator.hidesWhenStopped = YES; + [self addSubview:_activityIndcator]; + } + _activityIndcator.center = CGPointMake(self.bounds.size.width*0.5,self.bounds.size.height*0.5 ); + return _activityIndcator; +} + +- (void)setImageUrl:(NSString *)imageUrl +{ + + [_imageUrl release]; + _imageUrl = [imageUrl copy]; + [self.activityIndcator startAnimating]; + self.imageData = [NSMutableData dataWithCapacity:1000]; + NSURLRequest *request = [[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:imageUrl]] autorelease]; + self.imageConnection = [NSURLConnection connectionWithRequest:request delegate:self]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ + //保存接收到的响应对象,以便响应完毕后的状态。 + self.imageResponse = response; +} +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ + + //也可以从此委托中获取到图片加载的进度。 + [self.imageData appendData:data]; +} +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ + //请求异常,在此可以进行出错后的操作,如给UIImageView设置一张默认的图片等。 + [self.activityIndcator stopAnimating]; + self.imageData = nil; + self.imageResponse = nil; + self.imageConnection = nil; + if (![self image]) { + [self setImageUrl:_imageUrl]; + } + +} +- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ + [self.activityIndcator stopAnimating]; + //加载成功,在此的加载成功并不代表图片加载成功,需要判断HTTP返回状态。 + if (_imageData && _imageData.length > 0) { + UIImage *img=[UIImage imageWithData:_imageData]; + [self setImage:img]; + }else { + if (![self image]) { + [self setImageUrl:_imageUrl]; + } + } + self.imageData = nil; + self.imageResponse = nil; + self.imageConnection = nil; +} + +- (void)setImage:(UIImage *)image +{ + _imageView.image = image; + _imageView.frame = self.bounds; + [_imageView setNeedsDisplay]; + [self setNeedsDisplay]; +} + +- (UIImage *)image +{ + return _imageView.image; +} +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect +{ + // Drawing code +} +*/ + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/SHKRenRen.h b/Classes/ShareKit/Sharers/Services/Renren/SHKRenRen.h new file mode 100644 index 000000000..fa44d1eee --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/SHKRenRen.h @@ -0,0 +1,49 @@ +// +// SHKRenRen.h +// ShareKit +// +// Created by icyleaf on 11-11-15. +// Copyright (c) 2011 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "SHKSharer.h" +#import "SHKFormControllerLargeTextField.h" +#import "ROConnect.h" + + +@interface SHKRenRen : SHKSharer +{ + Renren *renren; +} + +@property (retain) Renren *renren; + + +#pragma mark - +#pragma mark UI Implementation + +- (void)showRenRenForm; +- (void)showRenRenPublishPhotoDialog; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Renren/SHKRenRen.m b/Classes/ShareKit/Sharers/Services/Renren/SHKRenRen.m new file mode 100644 index 000000000..849875263 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Renren/SHKRenRen.m @@ -0,0 +1,254 @@ +// +// SHKRenRen.m +// ShareKit +// +// Created by icyleaf on 11-11-15. +// Copyright (c) 2011 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "SHKRenRen.h" +#import "SHKConfiguration.h" +#import "NSMutableDictionary+NSNullsToEmptyStrings.h" + +@implementation SHKRenRen +@synthesize renren = _renren; + + +static SHKRenRen *sharedRenRen = nil; + ++ (SHKRenRen *)sharedSHKRenren +{ + if ( ! sharedRenRen) + { + sharedRenRen = [[SHKRenRen alloc] init]; + } + + return sharedRenRen; +} + +- (id)init +{ + if ((self = [super init])) + { + _renren = [Renren sharedRenren]; + } + + return self; +} + + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"人人网"; +} + ++ (BOOL)canShareURL +{ + return YES; +} + ++ (BOOL)canShareText +{ + return YES; +} + ++ (BOOL)canShareImage +{ + return YES; +} + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + + +#pragma mark - +#pragma mark Authentication + +- (BOOL)isAuthorized +{ + return [_renren isSessionValid]; +} + +- (void)promptAuthorization +{ + NSArray *permissions = [NSArray arrayWithObjects:@"status_update", @"photo_upload", nil]; + [_renren authorizationWithPermisson:permissions andDelegate:self]; +} + ++ (void)logout +{ + [[Renren sharedRenren] logout:[SHKRenRen sharedSHKRenren]]; +} + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { + [item setCustomValue:[item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] + forKey:@"status"]; + + [self showRenRenForm]; + } + + else if (item.shareType == SHKShareTypeImage) + { + [self showRenRenPublishPhotoDialog]; + } + + else if (item.shareType == SHKShareTypeText) + { + [item setCustomValue:item.text forKey:@"status"]; + [self showRenRenForm]; + } +} + +- (void)showRenRenForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil + bundle:nil + delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + [item setCustomValue:form.textView.text forKey:@"status"]; + [self tryToSend]; +} + +- (void)showRenRenPublishPhotoDialog +{ + [_renren publishPhotoSimplyWithImage:item.image + caption:item.title]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem +{ + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + if ( ! [self validateItemAfterUserEdit]) + return NO; + + else + { + if (item.shareType == SHKShareTypeImage) + { + [self showRenRenPublishPhotoDialog]; + } + else + { + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:10]; + [params setObject:@"status.set" forKey:@"method"]; + [params setObject:[item customValueForKey:@"status"] forKey:@"status"]; + [_renren requestWithParams:params andDelegate:self]; + } + + // Notify delegate + [self sendDidStart]; + + return YES; + } + + return NO; +} + +#pragma mark - RenrenDelegate methods + +-(void)renrenDidLogin:(Renren *)renren +{ + [self show]; +} + +- (void)renren:(Renren *)renren loginFailWithError:(ROError*)error +{ + [self sendDidFailWithError:error]; +} + +- (void)renren:(Renren *)renren requestDidReturnResponse:(ROResponse*)response +{ + NSDictionary* params = (NSDictionary *)response.rootObject; + if (params != nil && [params objectForKey:@"result"] != nil && [[params objectForKey:@"result"] intValue] == 1) + { + [self sendDidFinish]; + } + else + { + [self sendDidFailWithError:[SHK error:SHKLocalizedString([params objectForKey:@"error_msg"])]]; + } +} + +- (void)renren:(Renren *)renren requestFailWithError:(ROError*)error +{ + [self sendDidFailWithError:[SHK error:SHKLocalizedString([error localizedDescription])]]; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKSinaWeibo.h b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKSinaWeibo.h new file mode 100644 index 000000000..d08090e47 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKSinaWeibo.h @@ -0,0 +1,38 @@ +// +// SHKSinaWeibo.h +// ShareKit +// +// Created by icyleaf on 12-03-16. +// Copyright 2012 icyleaf.com. All rights reserved. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import +#import "SHKOAuthSharer.h" +#import "SHKFormControllerLargeTextField.h" +#import "SinaWeibo.h" +#import "SinaWeiboRequest.h" + +@interface SHKSinaWeibo : SHKOAuthSharer + ++ (BOOL)handleOpenURL:(NSURL*)url; +@end diff --git a/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKSinaWeibo.m b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKSinaWeibo.m new file mode 100644 index 000000000..60d9d4f0d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKSinaWeibo.m @@ -0,0 +1,478 @@ +// +// SHKSinaWeibo.m +// ShareKit +// +// Created by icyleaf on 12-03-16. +// Copyright 2012 icyleaf.com. All rights reserved. + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +#import "SHKSinaWeibo.h" +#import "SHKConfiguration.h" +#import "NSMutableDictionary+NSNullsToEmptyStrings.h" +#import "JSONKit.h" +#import "SHKiOS6SinaWeibo.h" + +#import + +#define API_DOMAIN @"http://api.t.sina.com.cn" + +static NSString *const kSHKStoredItemKey=@"kSHKSinaWeiboStoredItem"; +static NSString *const kSHKSinaWeiboAccessTokenKey=@"AccessTokenKey"; +static NSString *const kSHKSinaWeiboExpiryDateKey=@"ExpirationDateKey"; +static NSString *const kSHKSinaWeiboUserIdKey =@"UserIDKey"; +static NSString *const kSHKSinaWeiboRefreshTokenKey =@"refresh_token"; + +static NSString *const kSHKSinaWeiboUserInfo = @"kSHKSinaWeiboUserInfo"; + +@interface SHKSinaWeibo () + ++ (SinaWeibo *)sinaWeibo; ++ (void)storeAuthData; +- (BOOL)prepareItem; +- (BOOL)shortenURL; +- (void)shortenURLFinished:(SHKRequest *)aRequest; +- (BOOL)validateItemAfterUserEdit; +- (BOOL)socialFrameworkAvailable; + +- (void)showSinaWeiboForm; + +@end + +@implementation SHKSinaWeibo + ++ (SinaWeibo *)sinaWeibo +{ + static SinaWeibo *sinaWeibo = nil; + @synchronized([SHKSinaWeibo class]) { + if (! sinaWeibo) + { + sinaWeibo = [[SinaWeibo alloc] initWithAppKey:SHKCONFIG(sinaWeiboConsumerKey) + appSecret:SHKCONFIG(sinaWeiboConsumerSecret) + appRedirectURI:SHKCONFIG(sinaWeiboCallbackUrl) + andDelegate:nil]; + + NSDictionary *sinaweiboInfo = [[NSUserDefaults standardUserDefaults] objectForKey:kSHKStoredItemKey]; + if ([sinaweiboInfo objectForKey:kSHKSinaWeiboAccessTokenKey] + && [sinaweiboInfo objectForKey:kSHKSinaWeiboExpiryDateKey] + && [sinaweiboInfo objectForKey:kSHKSinaWeiboUserIdKey]) + { + sinaWeibo.accessToken = [sinaweiboInfo objectForKey:kSHKSinaWeiboAccessTokenKey]; + sinaWeibo.expirationDate = [sinaweiboInfo objectForKey:kSHKSinaWeiboExpiryDateKey]; + sinaWeibo.userID = [sinaweiboInfo objectForKey:kSHKSinaWeiboUserIdKey]; + } + } + } + + return sinaWeibo; +} + ++ (void)storeAuthData +{ + SinaWeibo *sinaweibo = [SHKSinaWeibo sinaWeibo]; + + [[NSUserDefaults standardUserDefaults] setObject:[NSDictionary dictionaryWithObjectsAndKeys: + sinaweibo.accessToken, kSHKSinaWeiboAccessTokenKey, + sinaweibo.expirationDate, kSHKSinaWeiboExpiryDateKey, + sinaweibo.userID, kSHKSinaWeiboUserIdKey, + sinaweibo.refreshToken, kSHKSinaWeiboRefreshTokenKey, nil] + forKey:kSHKStoredItemKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + ++ (BOOL)handleOpenURL:(NSURL*)url +{ + SinaWeibo *sinaWeibo = [SHKSinaWeibo sinaWeibo]; + + // If app has "Application does not run in background" = YES, + // or was killed before it could return from Facebook SSO callback (from Safari or Facebook app) + if ( ! sinaWeibo.delegate) + { + SHKSinaWeibo *sinaWeiboSharer = [[[SHKSinaWeibo alloc] init] autorelease]; //released in sinaweiboDidLogIn + + if ([[NSUserDefaults standardUserDefaults] objectForKey:kSHKStoredItemKey]) + { + sinaWeiboSharer.pendingAction = SHKPendingShare; + } + + [sinaWeibo setDelegate:sinaWeiboSharer]; + } + + return [sinaWeibo handleOpenURL:url]; +} + + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"新浪微博"; +} + ++ (BOOL)canShareURL +{ + return YES; +} + ++ (BOOL)canShareText +{ + return YES; +} + ++ (BOOL)canShareImage +{ + return YES; +} + ++ (BOOL)canGetUserInfo +{ + return YES; +} + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + +#pragma mark - +#pragma mark Authentication + +- (BOOL)isAuthorized +{ + SinaWeibo *sinaWeibo = [SHKSinaWeibo sinaWeibo]; + if ([sinaWeibo isAuthValid]) return YES; + + NSDictionary *sinaweiboInfo = [[NSUserDefaults standardUserDefaults] objectForKey:kSHKSinaWeiboAccessTokenKey]; + sinaWeibo.accessToken = [sinaweiboInfo objectForKey:kSHKSinaWeiboAccessTokenKey]; + sinaWeibo.expirationDate = [sinaweiboInfo objectForKey:kSHKSinaWeiboExpiryDateKey]; + sinaWeibo.userID = [sinaweiboInfo objectForKey:kSHKSinaWeiboUserIdKey]; + + return [sinaWeibo isAuthValid]; +} + +- (void)promptAuthorization +{ + [[SHKSinaWeibo sinaWeibo] setDelegate:self]; + [self retain]; // must retain, because SinaWeibo does not retain its delegates. Released in callback. + [[SHKSinaWeibo sinaWeibo] logIn]; +} + ++ (void)logout +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kSHKStoredItemKey]; + [[SHKSinaWeibo sinaWeibo] logOut]; +} + +#pragma mark - +#pragma mark Commit Share + +- (void)share +{ + if ([self socialFrameworkAvailable]) + { + SHKSharer *sharer =[SHKiOS6SinaWeibo shareItem:self.item]; + sharer.quiet = self.quiet; + sharer.shareDelegate = self.shareDelegate; + [SHKSinaWeibo logout];// to clean credentials - we will not need them anymore + return; + } + + BOOL itemPrepared = [self prepareItem]; + + // the only case item is not prepared is when we wait for URL to be shortened on background thread. + // In this case [super share] is called in callback method + if (itemPrepared) { + [super share]; + } +} + +- (BOOL)socialFrameworkAvailable +{ + if ([SHKCONFIG(forcePreSinaWeiboAccess) boolValue]) + { + return NO; + } + + if(NSClassFromString(@"SLComposeViewController") && [SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo]) { + return YES; + } + + return NO; +} + +#pragma mark - + +- (BOOL)prepareItem +{ + BOOL result = YES; + + if (item.shareType == SHKShareTypeURL) + { + BOOL isURLAlreadyShortened = [self shortenURL]; + result = isURLAlreadyShortened; + } + + else if (item.shareType == SHKShareTypeImage) + { + [item setCustomValue:item.title forKey:@"status"]; + } + + else if (item.shareType == SHKShareTypeText) + { + [item setCustomValue:item.text forKey:@"status"]; + } + + return result; +} + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeUserInfo) + { + [self setQuiet:YES]; + [self tryToSend]; + } + + else + { + [self showSinaWeiboForm]; + } +} + +- (void)showSinaWeiboForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil bundle:nil delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + [item setCustomValue:form.textView.text forKey:@"status"]; + [self tryToSend]; +} + +#pragma mark - + +- (BOOL)shortenURL +{ + if ([SHKCONFIG(sinaWeiboConsumerKey) isEqualToString:@""] || SHKCONFIG(sinaWeiboConsumerKey) == nil) + NSAssert(NO, @"ShareKit: Could not shorting url with empty sina weibo consumer key."); + + if (![SHK connected]) + { + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title, [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] forKey:@"status"]; + return YES; + } + + if (!quiet) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Shortening URL...")]; + + self.request = [[[SHKRequest alloc] initWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"http://api.t.sina.com.cn/short_url/shorten.json?source=%@&url_long=%@", + SHKCONFIG(sinaWeiboConsumerKey), + SHKEncodeURL(item.URL) + ]] + params:nil + delegate:self + isFinishedSelector:@selector(shortenURLFinished:) + method:@"GET" + autostart:YES] autorelease]; + + return NO; +} + +- (void)shortenURLFinished:(SHKRequest *)aRequest +{ + [[SHKActivityIndicator currentIndicator] hide]; + + @try + { + NSArray *result = [[aRequest getResult] objectFromJSONString]; + item.URL = [NSURL URLWithString:[[result objectAtIndex:0] objectForKey:@"url_short"]]; + } + @catch (NSException *exception) + { + // TODO - better error message + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Shorten URL Error") + message:SHKLocalizedString(@"We could not shorten the URL.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; + } + + [item setCustomValue:[NSString stringWithFormat:@"%@: %@", item.title, item.URL.absoluteString] + forKey:@"status"]; + + [super share]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem +{ + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + if ( ! [self validateItemAfterUserEdit]) + return NO; + + else + { + SinaWeibo *sinaweibo = [SHKSinaWeibo sinaWeibo]; + + if (item.shareType == SHKShareTypeImage && item.image) + { + [sinaweibo requestWithURL:@"statuses/upload.json" + params:[NSMutableDictionary dictionaryWithObjectsAndKeys: + [item customValueForKey:@"status"], @"status", + item.image, @"pic", nil] + httpMethod:@"POST" + delegate:self]; + } + + else + { + [sinaweibo requestWithURL:@"statuses/update.json" + params:[NSMutableDictionary dictionaryWithObjectsAndKeys:[item customValueForKey:@"status"], @"status", nil] + httpMethod:@"POST" + delegate:self]; + } + + [self retain]; // must retain, because SinaWeibo does not retain its delegates. Released in callback. + + // Notify delegate + [self sendDidStart]; + + return YES; + } + + return NO; +} + +#pragma mark - Sina Weibo delegate methods + +- (void)sinaweiboDidLogIn:(SinaWeibo *)sinaweibo +{ + [SHKSinaWeibo storeAuthData]; + + [self authDidFinish:true]; + + if (self.item) + [self tryPendingAction]; +} + +- (void)sinaweiboDidLogOut:(SinaWeibo *)sinaweibo +{ + SHKLog(@"sinaweiboDidLogOut"); + [SHKSinaWeibo logout]; + + [self release]; // see [self send] +} + +- (void)sinaweiboLogInDidCancel:(SinaWeibo *)sinaweibo +{ + SHKLog(@"sinaweiboLogInDidCancel"); + + [self authDidFinish:NO]; + [self release]; // see [self send] +} + +- (void)sinaweibo:(SinaWeibo *)sinaweibo logInDidFailWithError:(NSError *)error +{ + SHKLog(@"sinaweibo logInDidFailWithError %@", error); + [self authDidFinish:NO]; + + [self release]; // see [self send] +} + +- (void)sinaweibo:(SinaWeibo *)sinaweibo accessTokenInvalidOrExpired:(NSError *)error +{ + SHKLog(@"sinaweiboAccessTokenInvalidOrExpired %@", error); + [SHKSinaWeibo logout]; + + [self authDidFinish:NO]; + + [self release]; // see [self send] +} + +#pragma mark - SinaWeiboRequest Delegate + +- (void)request:(SinaWeiboRequest *)aRequest didFailWithError:(NSError *)error +{ + if ([aRequest.url hasSuffix:@"statuses/update.json"]) + { + SHKLog(@"Post status failed with error : %@", error); + } + + [self sendDidFailWithError:error]; + + [self release]; // see [self send] +} + +- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result +{ + [self sendDidFinish]; + [self release]; // see [self send] +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKiOS6SinaWeibo.h b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKiOS6SinaWeibo.h new file mode 100644 index 000000000..264c684c6 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKiOS6SinaWeibo.h @@ -0,0 +1,35 @@ +// +// SHKiOS6SinaWeibo.h +// ShareKit +// +// Created by icyleaf on 12-10-23. +// Copyright 2012 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +#import "SHKSharer.h" + +@interface SHKiOS6SinaWeibo : SHKSharer + +@end diff --git a/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKiOS6SinaWeibo.m b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKiOS6SinaWeibo.m new file mode 100644 index 000000000..56ee3ab9f --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Sina Weibo/SHKiOS6SinaWeibo.m @@ -0,0 +1,129 @@ +// +// SHKiOS6SinaWeibo.m +// ShareKit +// +// Created by icyleaf on 12-10-23. +// Copyright 2012 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "SHKiOS6SinaWeibo.h" +#import + + +@interface SHKiOS6SinaWeibo () + +@property (retain) UIViewController *currentTopViewController; + +- (void)callUI:(NSNotification *)notif; +- (void)presentUI; + +@end + +@implementation SHKiOS6SinaWeibo + +@synthesize currentTopViewController; + +- (void)dealloc { + + [currentTopViewController release]; + [super dealloc]; +} + ++ (NSString *)sharerTitle +{ + return @"新浪微博"; +} + ++ (NSString *)sharerId +{ + return @"SHKSinaWeibo"; +} + +- (void)share { + + if ([[SHK currentHelper] currentView]) { //user is sharing from SHKShareMenu + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUI:) + name:SHKHideCurrentViewFinishedNotification + object:nil]; + [self retain]; //must retain, so that it is still around for SHKShareMenu hide callback. Menu hides asynchronously when sharer is chosen. + + } else { + + [self presentUI]; + } +} + +#pragma mark - + +- (void)callUI:(NSNotification *)notif { + + [[NSNotificationCenter defaultCenter] removeObserver:self name:SHKHideCurrentViewFinishedNotification object:nil]; + [self presentUI]; + [self release]; //see share +} + +- (void)presentUI { + + if ([self.item shareType] == SHKShareTypeUserInfo) { + SHKLog(@"User info not possible to download on iOS5+. You can get Twitter enabled user info from Accounts framework"); + return; + } + + SLComposeViewController *socialController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo]; + + NSString *statusBody = [NSString stringWithString:(self.item.shareType == SHKShareTypeText ? item.text : item.title)]; + + NSString *tagString = [self tagStringJoinedBy:@" " allowedCharacters:[NSCharacterSet alphanumericCharacterSet] tagPrefix:@"#" forChina:YES]; + if ([tagString length] > 0) statusBody = [statusBody stringByAppendingFormat:@" %@", tagString]; + + // Trim string to fit 140 character max. + NSUInteger textLength = [statusBody length] > 140 ? 140 : [statusBody length]; + + while ([socialController setInitialText:[statusBody substringToIndex:textLength]] == NO && textLength > 0) { + textLength--; + } + [socialController addURL:self.item.URL]; + [socialController addImage:self.item.image]; + + socialController.completionHandler = ^(SLComposeViewControllerResult result){ + switch (result) { + case SLComposeViewControllerResultCancelled: + [self sendDidCancel]; + break; + case SLComposeViewControllerResultDone: + default: + [self sendDidFinish]; + break; + } + + [socialController dismissViewControllerAnimated:YES completion:Nil]; + }; + + self.currentTopViewController = [[SHK currentHelper] rootViewForCustomUIDisplay]; + [self.currentTopViewController presentViewController:socialController animated:YES completion:nil]; +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weibo/SHKTencentWeibo.h b/Classes/ShareKit/Sharers/Services/Tencent Weibo/SHKTencentWeibo.h new file mode 100644 index 000000000..f600fe1ee --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weibo/SHKTencentWeibo.h @@ -0,0 +1,53 @@ +// +// SHKTencentWeibo.h +// ShareKit +// +// Created by icyleaf on 12-5-3. +// Copyright (c) 2012年 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +#import +#import "SHKOAuthSharer.h" +#import "SHKFormControllerLargeTextField.h" + +@interface SHKTencentWeibo : SHKOAuthSharer + +#pragma mark - +#pragma mark UI Implementation + +- (void)showTencentWeiboForm; + +#pragma mark - +#pragma mark Share API Methods + +- (void)sendStatus; +- (void)sendStatusTicket:(OAServiceTicket *)ticket finishedWithData:(NSMutableData *)data; +- (void)sendStatusTicket:(OAServiceTicket *)ticket failedWithError:(NSError *)error; + +- (void)sendImage; +- (void)sendImageTicket:(OAServiceTicket *)ticket finishedWithData:(NSMutableData *)data; +- (void)sendImageTicket:(OAServiceTicket *)ticket failedWithError:(NSError *)error; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weibo/SHKTencentWeibo.m b/Classes/ShareKit/Sharers/Services/Tencent Weibo/SHKTencentWeibo.m new file mode 100644 index 000000000..2decbab9e --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weibo/SHKTencentWeibo.m @@ -0,0 +1,590 @@ +// +// SHKTencentWeibo.m +// ShareKit +// +// Created by icyleaf on 12-5-3. +// Copyright (c) 2012年 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#include +#include + +#import "SHKTencentWeibo.h" +#import "SHKConfiguration.h" +#import "NSMutableDictionary+NSNullsToEmptyStrings.h" +#import "TencentOAMutableURLRequest.h" +#import "TencentOAuthView.h" +#import "JSONKit.h" + +static NSString *const kSHKTencentWeiboUserInfo = @"kSHKTencentWeiboUserInfo"; + + +@interface SHKTencentWeibo (Private) +- (NSString *)getIPAddress; +- (void)handleUnsuccessfulTicket:(NSData *)data; +@end + + +@implementation SHKTencentWeibo + +- (id)init +{ + if ((self = [super init])) + { + // OAuth + self.consumerKey = SHKCONFIG(tencentWeiboConsumerKey); + self.secretKey = SHKCONFIG(tencentWeiboConsumerSecret); + self.authorizeCallbackURL = [NSURL URLWithString:SHKCONFIG(tencentWeiboCallbackUrl)]; + + // -- // + + // You do not need to edit these, they are the same for everyone + self.authorizeURL = [NSURL URLWithString:@"https://open.t.qq.com/cgi-bin/authorize"]; + self.requestURL = [NSURL URLWithString:@"https://open.t.qq.com/cgi-bin/request_token"]; + self.accessURL = [NSURL URLWithString:@"https://open.t.qq.com/cgi-bin/access_token"]; + } + return self; +} + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"腾讯微博"; +} + ++ (BOOL)canShareURL +{ + return YES; +} + ++ (BOOL)canShareText +{ + return YES; +} + ++ (BOOL)canShareImage +{ + return YES; +} + + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + +#pragma mark - +#pragma mark Commit Share + +- (void)share +{ + BOOL itemPrepared = [self prepareItem]; + + //the only case item is not prepared is when we wait for URL to be shortened on background thread. In this case [super share] is called in callback method + if (itemPrepared) { + [super share]; + } +} + + +#pragma mark - + +- (BOOL)prepareItem +{ + BOOL result = YES; + + if (item.shareType == SHKShareTypeURL) + { + BOOL isURLAlreadyShortened = [self shortenURL]; + result = isURLAlreadyShortened; + } + + else if (item.shareType == SHKShareTypeImage) + { + [item setCustomValue:item.title forKey:@"status"]; + } + + else if (item.shareType == SHKShareTypeText) + { + [item setCustomValue:item.text forKey:@"status"]; + } + + return result; +} + + +#pragma mark - +#pragma mark Authorization + ++ (void)logout { + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kSHKTencentWeiboUserInfo]; + [super logout]; +} + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { + [self showTencentWeiboForm]; + } + + else if (item.shareType == SHKShareTypeImage) + { + [self showTencentWeiboForm]; + } + + else if (item.shareType == SHKShareTypeText) + { + [self showTencentWeiboForm]; + } + + else if (item.shareType == SHKShareTypeUserInfo) + { + [self setQuiet:YES]; + [self tryToSend]; + } +} + +- (void)showTencentWeiboForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil bundle:nil delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + [item setCustomValue:form.textView.text forKey:@"status"]; + [self tryToSend]; +} + +#pragma mark - + +- (BOOL)shortenURL +{ + if ([SHKCONFIG(sinaWeiboConsumerKey) isEqualToString:@""] || SHKCONFIG(sinaWeiboConsumerKey) == nil) + NSAssert(NO, @"ShareKit: Could not shorting url with empty sina weibo consumer key."); + + if (![SHK connected]) + { + [item setCustomValue:[NSString stringWithFormat:@"%@ %@", item.title, [item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] forKey:@"status"]; + return YES; + } + + if (!quiet) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Shortening URL...")]; + + self.request = [[[SHKRequest alloc] initWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"http://api.t.sina.com.cn/short_url/shorten.json?source=%@&url_long=%@", + SHKCONFIG(sinaWeiboConsumerKey), + SHKEncodeURL(item.URL) + ]] + params:nil + delegate:self + isFinishedSelector:@selector(shortenURLFinished:) + method:@"GET" + autostart:YES] autorelease]; + + return NO; +} + +- (void)shortenURLFinished:(SHKRequest *)aRequest +{ + [[SHKActivityIndicator currentIndicator] hide]; + + @try + { + NSArray *result = [[aRequest getResult] objectFromJSONString]; + item.URL = [NSURL URLWithString:[[result objectAtIndex:0] objectForKey:@"url_short"]]; + } + @catch (NSException *exception) + { + // TODO - better error message + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Shorten URL Error") + message:SHKLocalizedString(@"We could not shorten the URL.") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Continue") + otherButtonTitles:nil] autorelease] show]; + } + + [item setCustomValue:[NSString stringWithFormat:@"%@: %@", item.title, item.URL.absoluteString] + forKey:@"status"]; + + [super share]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem +{ + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + if (![self validateItemAfterUserEdit]) + return NO; + + switch (item.shareType) { + + case SHKShareTypeImage: + [self sendImage]; + break; + + case SHKShareTypeUserInfo: + // [self sendUserInfo]; + break; + + default: + [self sendStatus]; + break; + } + + // Notify delegate + [self sendDidStart]; + + return YES; +} + +- (void)sendStatus +{ + TencentOAMutableURLRequest *oRequest = [[TencentOAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://open.t.qq.com/api/t/add"] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:signatureProvider]; + + + [oRequest setHTTPMethod:@"POST"]; + + OARequestParameter *format = [[OARequestParameter alloc] initWithName:@"format" + value:@"json"]; + + OARequestParameter *clientip = [[OARequestParameter alloc] initWithName:@"clientip" + value:[self getIPAddress]]; + + OARequestParameter *content = [[OARequestParameter alloc] initWithName:@"content" + value:[item customValueForKey:@"status"]]; + + NSArray *params = [NSArray arrayWithObjects:format, clientip, content, nil]; + [oRequest setParameters:params]; + [format release]; + [clientip release]; + [content release]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendStatusTicket:finishedWithData:) + didFailSelector:@selector(sendStatusTicket:failedWithError:)]; + + [fetcher start]; + [oRequest release]; +} + + +- (void)sendStatusTicket:(OAServiceTicket *)ticket finishedWithData:(NSMutableData *)data +{ + if (SHKDebugShowLogs) // check so we don't have to alloc the string with the data if we aren't logging + SHKLog(@"sendStatusTicket Response Body: %@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + if (ticket.didSucceed) + { + NSDictionary *result = [data objectFromJSONData]; + + if ([[result valueForKey:@"ret"] intValue] == 0) + [self sendDidFinish]; + else + [self handleUnsuccessfulTicket:data]; + } + else + { + [self handleUnsuccessfulTicket:data]; + } +} + +- (void)sendStatusTicket:(OAServiceTicket *)ticket failedWithError:(NSError*)error +{ + [self sendDidFailWithError:error]; +} + + +- (void)sendImage +{ + TencentOAMutableURLRequest *oRequest = [[TencentOAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://open.t.qq.com/api/t/add_pic"] + consumer:consumer + token:accessToken + realm:nil + signatureProvider:signatureProvider]; + + + [oRequest setHTTPMethod:@"POST"]; + + OARequestParameter *format = [[OARequestParameter alloc] initWithName:@"format" + value:@"json"]; + + OARequestParameter *clientip = [[OARequestParameter alloc] initWithName:@"clientip" + value:[self getIPAddress]]; + + OARequestParameter *content = [[OARequestParameter alloc] initWithName:@"content" + value:[item customValueForKey:@"status"]]; + + NSArray *params = [NSArray arrayWithObjects:format, clientip, content, nil]; + [oRequest setParameters:params]; + [format release]; + [clientip release]; + [content release]; + + [oRequest prepare]; + + + CGFloat compression = 0.9f; + NSData *imageData = UIImageJPEGRepresentation([item image], compression); + + // TODO + // Note from Nate to creator of sendImage method - This seems like it could be a source of sluggishness. + // For example, if the image is large (say 3000px x 3000px for example), it would be better to resize the image + // to an appropriate size (max of img.ly) and then start trying to compress. + + while ([imageData length] > 700000 && compression > 0.1) { + // NSLog(@"Image size too big, compression more: current data size: %d bytes",[imageData length]); + compression -= 0.1; + imageData = UIImageJPEGRepresentation([item image], compression); + + } + + NSString *boundary = @"0xKhTmLbOuNdArY"; + NSString *contentType =[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary]; + [oRequest setValue: contentType forHTTPHeaderField:@"Content-Type"]; + + NSMutableData *body =[NSMutableData data]; + NSString *dispKey = @"Content-Disposition: form-data; name=\"pic\"; filename=\"pic\"\r\n"; + + [body appendData: [[NSString stringWithFormat: @"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData: [dispKey dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData: [@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:imageData]; + [body appendData: [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + + [body appendData: [[NSString stringWithFormat: @"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + + [body appendData: [@"Content-Disposition: form-data; name=\"content\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData: [[item customValueForKey:@"status"] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData: [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + + [body appendData: [[NSString stringWithFormat: @"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + + [oRequest setHTTPBody:body]; + + + // Notify delegate + [self sendDidStart]; + + // Start the request + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendImageTicket:finishedWithData:) + didFailSelector:@selector(sendImageTicket:failedWithError:)]; + + [fetcher start]; + [oRequest release]; +} + +- (void)sendImageTicket:(OAServiceTicket *)ticket finishedWithData:(NSMutableData *)data +{ + // TODO better error handling here + SHKLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + if (ticket.didSucceed) + { + NSDictionary *result = [data objectFromJSONData]; + + if ([[result valueForKey:@"ret"] intValue] == 0) + [self sendDidFinish]; + else + [self handleUnsuccessfulTicket:data]; + } + else + { + [self handleUnsuccessfulTicket:data]; + } +} + +- (void)sendImageTicket:(OAServiceTicket *)ticket failedWithError:(NSError*)error +{ + [self sendDidFailWithError:error]; +} + + +#pragma mark - + +- (void)handleUnsuccessfulTicket:(NSData *)data +{ + if (SHKDebugShowLogs) + SHKLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + + [self sendDidFailWithError:nil]; +} + + +#pragma mark Request + +- (void)tokenRequest +{ + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Connecting...")]; + + TencentOAMutableURLRequest *oRequest = [[TencentOAMutableURLRequest alloc] initWithURL:requestURL + consumer:consumer + token:nil + realm:nil + signatureProvider:signatureProvider]; + + + [oRequest setHTTPMethod:@"GET"]; + + OARequestParameter *callback = [[OARequestParameter alloc] initWithName:@"oauth_callback" + value:[authorizeCallbackURL absoluteString]]; + NSArray *params = [NSArray arrayWithObjects:callback, nil]; + [oRequest setParameters:params]; + [callback release]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(tokenRequestTicket:didFinishWithData:) + didFailSelector:@selector(tokenRequestTicket:didFailWithError:)]; + [fetcher start]; + [oRequest release]; +} + +- (void)tokenAuthorize +{ + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?oauth_token=%@", + authorizeURL.absoluteString, + requestToken.key]]; + + TencentOAuthView *auth = [[TencentOAuthView alloc] initWithURL:url delegate:self]; + [[SHK currentHelper] showViewController:auth]; + [auth release]; +} + +- (void)tokenAccess:(BOOL)refresh +{ + if (!refresh) + [[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Authenticating...")]; + + TencentOAMutableURLRequest *oRequest = [[TencentOAMutableURLRequest alloc] initWithURL:accessURL + consumer:consumer + token:(refresh ? accessToken : requestToken) + realm:nil + signatureProvider:signatureProvider]; + + [oRequest setHTTPMethod:@"GET"]; + + OARequestParameter *verifier = [[OARequestParameter alloc] initWithName:@"oauth_verifier" + value:[authorizeResponseQueryVars valueForKey:@"v"]]; + NSArray *params = [NSArray arrayWithObjects:verifier, nil]; + [oRequest setParameters:params]; + [verifier release]; + + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(tokenAccessTicket:didFinishWithData:) + didFailSelector:@selector(tokenAccessTicket:didFailWithError:)]; + [fetcher start]; + [oRequest release]; +} + + +#pragma mark - +#pragma mark Hepler Functions + +- (NSString *)getIPAddress +{ + NSString *address = @"error"; + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + int success = 0; + + //retrieve the current interfaces - returns 0 on success + success = getifaddrs(&interfaces); + if (success == 0) { + //Loop through linked list of interfaces + temp_addr = interfaces; + while (temp_addr != NULL) { + if (temp_addr->ifa_addr->sa_family == AF_INET) { + //Check if interface is en0 which is the wifi connection on the iPhone + if ([[NSString stringWithUTF8String: temp_addr->ifa_name] isEqualToString:@"en0"]) { + //Get NSString from C String + address =[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *) temp_addr->ifa_addr)->sin_addr)]; + } + } + temp_addr = temp_addr->ifa_next; + } + } + //Free memory + freeifaddrs(interfaces); + SHKLog(@"current address: %@", address); + return address; +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAMutableURLRequest.h b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAMutableURLRequest.h new file mode 100644 index 000000000..000de78fd --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAMutableURLRequest.h @@ -0,0 +1,35 @@ +// +// TencentOAMutableURLRequest.h +// ShareKit +// +// Created by icyleaf on 12-5-3. +// Copyright (c) 2012年 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +#import "OAMutableURLRequest.h" + +@interface TencentOAMutableURLRequest : OAMutableURLRequest + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAMutableURLRequest.m b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAMutableURLRequest.m new file mode 100644 index 000000000..efefe2f79 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAMutableURLRequest.m @@ -0,0 +1,138 @@ +// +// TencentOAMutableURLRequest.m +// ShareKit +// +// Created by icyleaf on 12-5-3. +// Copyright (c) 2012年 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +#import +#import "TencentOAMutableURLRequest.h" +#import "OAConsumer.h" +#import "OAToken.h" +#import "OAHMAC_SHA1SignatureProvider.h" +#import "OASignatureProviding.h" +#import "NSMutableURLRequest+Parameters.h" +#import "NSURL+Base.h" +#import "SHKConfiguration.h" + + +@interface TencentOAMutableURLRequest (Private) +- (void)_generateTimestamp; +- (void)_generateNonce; +- (NSString *)_signatureBaseString; +- (NSString *)normalizeRequestParameters; +@end + + +@implementation TencentOAMutableURLRequest + +- (void)prepare +{ + if (didPrepare) { + return; + } + didPrepare = YES; + + // sign + // Secrets must be urlencoded before concatenated with '&' + // TODO: if later RSA-SHA1 support is added then a little code redesign is needed + signature = [signatureProvider signClearText:[self _signatureBaseString] + withSecret:[NSString stringWithFormat:@"%@&%@", + [consumer.secret URLEncodedString], + [token.secret URLEncodedString]]]; + + NSURL *aUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@&oauth_signature=%@", + [[self URL] URLStringWithoutQuery], + [self normalizeRequestParameters], + [signature URLEncodedString]]]; + if (SHKDebugShowLogs) + SHKLog(@"Requset URL: %@", aUrl); + + [self setURL:aUrl]; +} + +#pragma mark - +#pragma mark Private + +- (void)_generateTimestamp +{ + timestamp = [[NSString stringWithFormat:@"%ld", time(NULL)] retain]; +} + +- (void)_generateNonce +{ + nonce = [[NSString stringWithFormat:@"%u", arc4random() % (9999999 - 123400) + 123400] retain]; +} + +- (NSString *)_signatureBaseString +{ + NSString *normalizedRequestParameters = [self normalizeRequestParameters]; + + // OAuth Spec, Section 9.1.2 "Concatenate Request Elements" + NSString *ret = [NSString stringWithFormat:@"%@&%@&%@", + [self HTTPMethod], + [[[self URL] URLStringWithoutQuery] URLEncodedString], + [normalizedRequestParameters URLEncodedString]]; + + if (SHKDebugShowLogs) + SHKLog(@"normalizedRequestParameters: %@ \nret: %@", normalizedRequestParameters, ret); + + return ret; +} + +- (NSString *)normalizeRequestParameters +{ + // OAuth Spec, Section 9.1.1 "Normalize Request Parameters" + // build a sorted array of both request parameters and OAuth header parameters + NSMutableArray *parameterPairs = [NSMutableArray arrayWithCapacity:(6)]; // 6 being the number of OAuth params in the Signature Base String + + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_consumer_key" value:consumer.key] URLEncodedNameValuePair]]; + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_signature_method" value:[signatureProvider name]] URLEncodedNameValuePair]]; + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_timestamp" value:timestamp] URLEncodedNameValuePair]]; + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_nonce" value:nonce] URLEncodedNameValuePair]]; + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_version" value:@"1.0"] URLEncodedNameValuePair]]; + + if (![token.key isEqualToString:@""]) { + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_token" value:token.key] URLEncodedNameValuePair]]; + } + + for(NSString *parameterName in [[extraOAuthParameters allKeys] sortedArrayUsingSelector:@selector(compare:)]) { + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:[parameterName URLEncodedString] value: [[extraOAuthParameters objectForKey:parameterName] URLEncodedString]] URLEncodedNameValuePair]]; + } + + if (![[self valueForHTTPHeaderField:@"Content-Type"] hasPrefix:@"multipart/form-data"]) { + for (OARequestParameter *param in [self parameters]) { + [parameterPairs addObject:[param URLEncodedNameValuePair]]; + } + } + + NSArray *sortedPairs = [parameterPairs sortedArrayUsingSelector:@selector(compare:)]; + NSString *normalizedRequestParameters = [sortedPairs componentsJoinedByString:@"&"]; + + return normalizedRequestParameters; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAuthView.h b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAuthView.h new file mode 100644 index 000000000..1f52a95ba --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAuthView.h @@ -0,0 +1,34 @@ +// +// TencentOAuthView.h +// ShareKit +// +// Created by icyleaf on 12-5-3. +// Copyright (c) 2012年 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "SHKOAuthView.h" + +@interface TencentOAuthView : SHKOAuthView + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAuthView.m b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAuthView.m new file mode 100644 index 000000000..50b0720d8 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weibo/TencentOAuthView.m @@ -0,0 +1,63 @@ +// +// TencentOAuthView.m +// ShareKit +// +// Created by icyleaf on 12-5-3. +// Copyright (c) 2012年 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "TencentOAuthView.h" + +@implementation TencentOAuthView + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + if ([request.URL.absoluteString rangeOfString:@"authorize"].location != NSNotFound + && [request.URL.absoluteString rangeOfString:@"checkType=verifycode"].location != NSNotFound) + { + // Get query + NSMutableDictionary *queryParams = nil; + if (request.URL.query != nil) + { + queryParams = [NSMutableDictionary dictionaryWithCapacity:0]; + NSArray *vars = [request.URL.query componentsSeparatedByString:@"&"]; + NSArray *parts; + for(NSString *var in vars) + { + parts = [var componentsSeparatedByString:@"="]; + if (parts.count == 2) + [queryParams setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]]; + } + } + + [delegate tokenAuthorizeView:self didFinishWithSuccess:YES queryParams:queryParams error:nil]; + self.delegate = nil; + + return NO; + } + + return YES; +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/WXApi.h b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/WXApi.h new file mode 100644 index 000000000..d31b265dc --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/WXApi.h @@ -0,0 +1,120 @@ +// +// MMApi.h +// ApiClient +// +// Created by Tencent on 12-2-28. +// Copyright (c) 2012年 Tencent. All rights reserved. +// + +#import + +#import "WXApiObject.h" + +#pragma mark - +/*! @brief 接收并处理来至微信终端程序的事件消息 + * + * 接收并处理来至微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。 + * WXApiDelegate 会在handleOpenURL中使用并触发。 + */ +@protocol WXApiDelegate + +@optional + +/*! @brief 收到一个来自微信的请求,处理完后调用sendResp + * + * 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。 + * 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。 + * @param req 具体请求内容,是自动释放的 + */ +-(void) onReq:(BaseReq*)req; + +/*! @brief 发送一个sendReq后,收到微信的回应 + * + * 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。 + * 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。 + * @param resp具体的回应内容,是自动释放的 + */ +-(void) onResp:(BaseResp*)resp; + +@end + +#pragma mark - + +/*! @brief 微信Api接口函数 + * + * 该类封装了微信终端SDK的所有接口 + */ +@interface WXApi : NSObject + +/*! @brief WXApi的成员函数,在微信终端程序中注册第三方应用。 + * + * 需要在每次启动第三方应用程序时调用。第一次调用后,会在微信的可用应用列表中出现。 + * @param appid 微信开发者ID + * @return 成功返回YES,失败返回NO。 + */ ++(BOOL) registerApp:(NSString *) appid; + +/*! @brief 处理微信通过URL启动App时传递的数据 + * + * 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。 + * @param url 启动App的URL + * @param delegate WXApiDelegate对象,用来接收微信触发的消息。 + * @return 成功返回YES,失败返回NO。 + */ ++(BOOL) handleOpenURL:(NSURL *) url delegate:(id) delegate; + +/*! @brief 检查微信是否已被用户安装 + * + * @return 微信已安装返回YES,未安装返回NO。 + */ ++(BOOL) isWXAppInstalled; + +/*! @brief 判断当前微信的版本是否支持OpenApi + * + * @return 支持返回YES,不支持返回NO。 + */ ++(BOOL) isWXAppSupportApi; + +/*! @brief 获取当前微信的版本所支持的API最高版本 + * + * @return 返回微信支持的最高API版本号。 + */ ++(NSString *) getWXAppSupportMaxApiVersion; + +/*! @brief 获取当前微信SDK的版本号 + * + * @return 返回当前微信SDK的版本号 + */ ++(NSString *) getApiVersion; + +/*! @brief 获取微信的itunes安装地址 + * + * @return 微信的安装地址字符串。 + */ ++(NSString *) getWXAppInstallUrl; + +/*! @brief 打开微信 + * + * @return 成功返回YES,失败返回NO。 + */ ++(BOOL) openWXApp; + +/*! @brief 发送请求到微信,等待微信返回onResp + * + * 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。可能发送的请求有 + * SendMessageToWXReq、SendAuthReq等。 + * @param req 具体的发送请求,在调用函数后,请自己释放。 + * @return 成功返回YES,失败返回NO。 + */ ++(BOOL) sendReq:(BaseReq*)req; + +/*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面 + * + * 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有 + * GetMessageFromWXResp、ShowMessageFromWXResp等。 + * @param resp 具体的应答内容,调用函数后,请自己释放 + * @return 成功返回YES,失败返回NO。 + */ ++(BOOL) sendResp:(BaseResp*)resp; + +@end \ No newline at end of file diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/WXApiObject.h b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/WXApiObject.h new file mode 100644 index 000000000..e7082b1d0 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/WXApiObject.h @@ -0,0 +1,360 @@ +// +// MMApiObject.h +// ApiClient +// +// Created by Tencent on 12-2-28. +// Copyright (c) 2012年 Tencent. All rights reserved. +// + +#import + +///////////////////////////////////////////////////////////// + +enum WXErrCode { + WXSuccess = 0, + WXErrCodeCommon = -1, + WXErrCodeUserCancel = -2, + WXErrCodeSentFail = -3, + WXErrCodeAuthDeny = -4, + WXErrCodeUnsupport = -5, +}; + +enum WXScene { + + WXSceneSession = 0, + WXSceneTimeline = 1, +}; + +enum WXAPISupport { + + WXAPISupportSession = 0, +}; + +/*! @brief 该类为微信终端SDK所有请求类的基类 + * + */ +@interface BaseReq : NSObject + +/** 请求类型 */ +@property (nonatomic, assign) int type; + +@end + +/*! @brief 该类为微信终端SDK所有响应类的基类 + * + */ +@interface BaseResp : NSObject +/** 错误码 */ +@property (nonatomic, assign) int errCode; +/** 错误提示字符串 */ +@property (nonatomic, retain) NSString *errStr; +/** 响应类型 */ +@property (nonatomic, assign) int type; + +@end + + +@class WXMediaMessage; +/*! @brief 第三方程序发送消息至微信终端程序的消息结构体 + * + * 第三方程序向微信发送信息需要传入SendMessageToWXReq结构体,信息类型包括文本消息和多媒体消息, + * 分别对应于text和message成员。调用该方法后,微信处理完信息会向第三方程序发送一个处理结果。 + * @see SendMessageToWXResp + */ +@interface SendMessageToWXReq : BaseReq +/** 发送消息的文本内容 + * @note 文本长度必须大于0且小于10K + */ +@property (nonatomic, retain) NSString* text; +/** 发送消息的多媒体内容 + * @see WXMediaMessage + */ +@property (nonatomic, retain) WXMediaMessage* message; +/** 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */ +@property (nonatomic, assign) BOOL bText; + +/** 发送的目标场景, 可以选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)。 默认发送到会话。 + * @see WXScene + */ +@property (nonatomic, assign) int scene; + +@end + +/*! @brief 微信终端向第三方程序返回的SendMessageToWXReq处理结果。 + * + * 第三方程序向微信终端发送SendMessageToWXReq后,微信发送回来的处理结果,该结果用SendMessageToWXResp表示。 + */ +@interface SendMessageToWXResp : BaseResp +@end + + +/*! @brief 第三方程序向微信终端请求认证的消息结构 + * + * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数, + * 向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。 + * @see SendAuthResp + */ +@interface SendAuthReq : BaseReq +/** 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。 + * @see SendAuthResp + * @note scope字符串长度不能超过1K + */ +@property (nonatomic, retain) NSString* scope; +/** 第三方程序本身用来标识其请求的唯一性,最后跳转回第三方程序时,由微信终端回传。 + * @note state字符串长度不能超过1K + */ +@property (nonatomic, retain) NSString* state; +@end + +/*! @brief 微信处理完第三方程序的认证和权限申请后向第三方程序回送的处理结果。 + * + * 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。 + * 微信终端处理完后会向第三方程序发送一个SendAuthResp。 + * @see onResp + */ +@interface SendAuthResp : BaseResp +/** 用户名 */ +@property (nonatomic, retain) NSString* userName; +/** 认证口令 */ +@property (nonatomic, retain) NSString* token; +/** 认证过期时间 */ +@property (nonatomic, retain) NSDate* expireDate; +/** 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传 + * @note state字符串长度不能超过1K + */ +@property (nonatomic, retain) NSString* state; +@end + + +/*! @brief 微信终端向第三方程序请求提供内容的消息结构体。 + * + * 微信终端向第三方程序请求提供内容,微信终端会向第三方程序发送GetMessageFromWXReq消息结构体, + * 需要第三方程序调用sendResp返回一个GetMessageFromWXResp消息结构体。 + */ +@interface GetMessageFromWXReq : BaseReq +@end + +/*! @brief 微信终端向第三方程序请求提供内容,第三方程序向微信终端返回的消息结构体。 + * + * 微信终端向第三方程序请求提供内容,第三方程序调用sendResp向微信终端返回一个GetMessageFromWXResp消息结构体。 + */ +@interface GetMessageFromWXResp : BaseResp +/** 向微信终端提供的文本内容 + @note 文本长度必须大于0且小于10K + */ +@property (nonatomic, retain) NSString* text; +/** 向微信终端提供的多媒体内容。 + * @see WXMediaMessage + */ +@property (nonatomic, retain) WXMediaMessage* message; +/** 向微信终端提供内容的消息类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */ +@property (nonatomic, assign) BOOL bText; +@end + +/*! @brief 微信通知第三方程序,要求第三方程序显示的消息结构体。 + * + * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。 + * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。 + */ +@interface ShowMessageFromWXReq : BaseReq +/** 微信终端向第三方程序发送的要求第三方程序处理的多媒体内容 + * @see WXMediaMessage + */ +@property (nonatomic, retain) WXMediaMessage* message; +@end + +/*! @brief 微信通知第三方程序,要求第三方程序显示或处理某些消息,第三方程序处理完后向微信终端发送的处理结果。 + * + * 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。 + * 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。 + */ +@interface ShowMessageFromWXResp : BaseResp +@end + + +#pragma mark - WXMediaMessage + +/*! @brief 多媒体消息结构体 + * + * 用于微信终端和第三方程序之间传递消息的多媒体消息内容 + */ +@interface WXMediaMessage : NSObject + ++(WXMediaMessage *) message; + +/** 标题 + * @note 长度不能超过512字节 + */ +@property (nonatomic, retain) NSString *title; +/** 描述内容 + * @note 长度不能超过1K + */ +@property (nonatomic, retain) NSString *description; +/** 缩略图数据 + * @note 大小不能超过32K + */ +@property (nonatomic, retain) NSData *thumbData; +/** 多媒体数据对象,可以为WXWebpageObject,WXImageObject,WXMusicObject等。 */ +@property (nonatomic, retain) id mediaObject; + +/*! @brief 设置消息缩略图的方法 + * + * @param image 缩略图 + * @note 大小不能超过32K + */ +- (void) setThumbImage:(UIImage *)image; + +@end + + +#pragma mark - +/*! @brief 多媒体消息中包含的图片数据对象 + * + * 微信终端和第三方程序之间传递消息中包含的图片数据对象。 + * @note imageData和imageUrl成员不能同时为空 + * @see WXMediaMessage + */ +@interface WXImageObject : NSObject +/*! @brief 返回一个WXImageObject对象 + * + * @note 返回的WXImageObject对象是自动释放的 + */ ++(WXImageObject *) object; + +/** 图片真实数据内容 + * @note 大小不能超过10M + */ +@property (nonatomic, retain) NSData *imageData; +/** 图片url + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *imageUrl; + +@end + +/*! @brief 多媒体消息中包含的音乐数据对象 + * + * 微信终端和第三方程序之间传递消息中包含的音乐数据对象。 + * @note musicUrl和musicLowBandUrl成员不能同时为空。 + * @see WXMediaMessage + */ +@interface WXMusicObject : NSObject +/*! @brief 返回一个WXMusicObject对象 + * + * @note 返回的WXMusicObject对象是自动释放的 + */ ++(WXMusicObject *) object; + +/** 音乐网页的url地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *musicUrl; +/** 音乐lowband网页的url地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *musicLowBandUrl; +/** 音乐数据url地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *musicDataUrl; + +/**音乐lowband数据url地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *musicLowBandDataUrl; + +@end + +/*! @brief 多媒体消息中包含的视频数据对象 + * + * 微信终端和第三方程序之间传递消息中包含的视频数据对象。 + * @note videoUrl和videoLowBandUrl不能同时为空。 + * @see WXMediaMessage + */ +@interface WXVideoObject : NSObject +/*! @brief 返回一个WXVideoObject对象 + * + * @note 返回的WXVideoObject对象是自动释放的 + */ ++(WXVideoObject *) object; + +/** 视频网页的url地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *videoUrl; +/** 视频lowband网页的url地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *videoLowBandUrl; + +@end + +/*! @brief 多媒体消息中包含的网页数据对象 + * + * 微信终端和第三方程序之间传递消息中包含的网页数据对象。 + * @see WXMediaMessage + */ +@interface WXWebpageObject : NSObject +/*! @brief 返回一个WXWebpageObject对象 + * + * @note 返回的WXWebpageObject对象是自动释放的 + */ ++(WXWebpageObject *) object; + +/** 网页的url地址 + * @note 不能为空且长度不能超过10K + */ +@property (nonatomic, retain) NSString *webpageUrl; + +@end + +/*! @brief 多媒体消息中包含的App扩展数据对象 + * + * 第三方程序向微信终端发送包含WXAppExtendObject的多媒体消息, + * 微信需要处理该消息时,会调用该第三方程序来处理多媒体消息内容。 + * @note url,extInfo和fileData不能同时为空 + * @see WXMediaMessage + */ +@interface WXAppExtendObject : NSObject +/*! @brief 返回一个WXAppExtendObject对象 + * + * @note 返回的WXAppExtendObject对象是自动释放的 + */ ++(WXAppExtendObject *) object; + +/** 若第三方程序不存在,微信终端会打开该url所指的App下载地址 + * @note 长度不能超过10K + */ +@property (nonatomic, retain) NSString *url; +/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理 + * @note 长度不能超过2K + */ +@property (nonatomic, retain) NSString *extInfo; +/** App文件数据,该数据发送给微信好友,微信好友需要点击后下载数据,微信终端会回传给第三方程序处理 + * @note 大小不能超过10M + */ +@property (nonatomic, retain) NSData *fileData; + +@end + +/*! @brief 多媒体消息中包含的表情数据对象 + * + * 微信终端和第三方程序之间传递消息中包含的表情数据对象。 + * @see WXMediaMessage + */ +@interface WXEmoticonObject : NSObject + +/*! @brief 返回一个WXEmoticonObject对象 + * + * @note 返回的WXEmoticonObject对象是自动释放的 + */ ++(WXEmoticonObject *) object; + +/** 表情真实数据内容 + * @note 大小不能超过10M + */ +@property (nonatomic, retain) NSData *emoticonData; + +@end + + diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/libWeChatSDK_armv7_armv7s.a b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/libWeChatSDK_armv7_armv7s.a new file mode 100644 index 000000000..ae98edb15 Binary files /dev/null and b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK/libWeChatSDK_armv7_armv7s.a differ diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weixin/SHKTencentWeixin.h b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SHKTencentWeixin.h new file mode 100644 index 000000000..b0b2f3b1e --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SHKTencentWeixin.h @@ -0,0 +1,54 @@ +// +// SHKTencentWeixin.h +// ShareKit +// +// Created by icyleaf on 12-11-2. +// Copyright 2012 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import +#import "SHKOAuthSharer.h" +#import "SHKCustomFormControllerLargeTextField.h" +#import "WXApi.h" + + +@interface SHKTencentWeixin : SHKOAuthSharer + +#pragma mark - Handle WX SDK Methods + ++ (void)registerApp; ++ (BOOL)handleOpenURL:(NSURL*)url; + + +#pragma mark - UI Implementation + +- (void)showTencentWeixinForm; + + +#pragma mark - Share API Methods + +- (void)sendStatus; +- (void)sendImage; + +@end diff --git a/Classes/ShareKit/Sharers/Services/Tencent Weixin/SHKTencentWeixin.m b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SHKTencentWeixin.m new file mode 100644 index 000000000..707032476 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/Tencent Weixin/SHKTencentWeixin.m @@ -0,0 +1,288 @@ +// +// SHKTencentWeixin.m +// ShareKit +// +// Created by icyleaf on 12-11-2. +// Copyright 2012 icyleaf.com. All rights reserved. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#import "SHKTencentWeixin.h" +#import "SHKConfiguration.h" + +@interface SHKTencentWeixin () + +- (NSData *)resizeWithImage:(UIImage*)image scale:(CGFloat)scale compression:(CGFloat)compression; + +@end + +static NSString *const kSHKTencentWeixinUserInfo = @"kSHKTencentWeixinUserInfo"; + +@implementation SHKTencentWeixin + + ++ (SHKTencentWeixin *)sharedInstance +{ + static SHKTencentWeixin *weixin = nil; + @synchronized([SHKTencentWeixin class]) { + if ( ! weixin) + { + weixin = [[SHKTencentWeixin alloc] init]; + } + } + + return weixin; +} + + +#pragma mark - Handle Wx SDK Methods + ++ (void)registerApp +{ + [WXApi registerApp:SHKCONFIG(tencentWeixinAppId)]; +} + ++ (BOOL)handleOpenURL:(NSURL*)url +{ + return [WXApi handleOpenURL:url delegate:[SHKTencentWeixin sharedInstance]]; +} + + +#pragma mark - +#pragma mark Configuration : Service Defination + ++ (NSString *)sharerTitle +{ + return @"微信"; +} + ++ (BOOL)canShareURL +{ + return ([WXApi isWXAppInstalled] && [WXApi isWXAppSupportApi]); +} + ++ (BOOL)canShareText +{ + return ([WXApi isWXAppInstalled] && [WXApi isWXAppSupportApi]); +} + ++ (BOOL)canShareImage +{ + return ([WXApi isWXAppInstalled] && [WXApi isWXAppSupportApi]); +} + + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +- (BOOL)shouldAutoShare +{ + return NO; +} + +#pragma mark - +#pragma mark Authorization + ++ (void)logout +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kSHKTencentWeixinUserInfo]; + [super logout]; +} + +- (BOOL)isAuthorized +{ + return YES; +} + +#pragma mark - +#pragma mark UI Implementation + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { + [item setCustomValue:[NSString stringWithFormat:@"%@: %@", item.title, [item.URL absoluteString]] forKey:@"status"]; + [self showTencentWeixinForm]; + } + + else if (item.shareType == SHKShareTypeText) + { + [item setCustomValue:[item text] forKey:@"status"]; + [self showTencentWeixinForm]; + } + + else if (item.shareType == SHKShareTypeImage) + { + [self send]; + } +} + +- (void)showTencentWeixinForm +{ + SHKFormControllerLargeTextField *rootView = [[SHKFormControllerLargeTextField alloc] initWithNibName:nil bundle:nil delegate:self]; + + rootView.text = [item customValueForKey:@"status"]; + rootView.maxTextLength = 140; + rootView.image = item.image; + rootView.imageTextLength = 25; + + self.navigationBar.tintColor = SHKCONFIG_WITH_ARGUMENT(barTintForView:,self); + + [self pushViewController:rootView animated:NO]; + [rootView release]; + + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKFormControllerLargeTextField *)form +{ + item.text = form.textView.text; + [self tryToSend]; +} + + +#pragma mark - +#pragma mark Share API Methods + +- (BOOL)validateItem +{ + if (self.item.shareType == SHKShareTypeUserInfo) { + return YES; + } + + NSString *status = [item customValueForKey:@"status"]; + return status != nil; +} + +- (BOOL)validateItemAfterUserEdit +{ + BOOL result = NO; + + BOOL isValid = [self validateItem]; + NSString *status = [item customValueForKey:@"status"]; + + if (isValid && status.length <= 140) { + result = YES; + } + + return result; +} + +- (BOOL)send +{ + if (item.shareType != SHKShareTypeImage && ! [self validateItemAfterUserEdit]) + return NO; + + switch (item.shareType) { + + case SHKShareTypeURL: + case SHKShareTypeText: + [self sendStatus]; + break; + + case SHKShareTypeImage: + [self sendImage]; + break; + default: + break; + } + + // Notify delegate + [self sendDidStart]; + + return YES; +} + +- (void)sendStatus +{ + SendMessageToWXReq *req = [[[SendMessageToWXReq alloc] init] autorelease]; + [req setBText:YES]; + [req setText:[item customValueForKey:@"status"]]; + + [WXApi sendReq:req]; +} + +- (void)sendImage +{ + CGFloat compression = 0.9f; + NSData *imageData = [self resizeWithImage:[item image] scale:compression compression:compression]; + + // Webchat limit thumb image size is 32kb, so if the image is bigger than that, it will process + // for resize and compression. + while ([imageData length] > 32768 && compression > 0.1) + { + compression -= 0.1; + imageData = [self resizeWithImage:[item image] scale:compression compression:compression]; + } + + UIImage *thumb = [UIImage imageWithData:imageData]; + + WXMediaMessage *message = [WXMediaMessage message]; + [message setThumbImage:thumb]; + + WXImageObject *ext = [WXImageObject object]; + [ext setImageData:UIImagePNGRepresentation([item image])]; + [message setMediaObject:ext]; + + SendMessageToWXReq* req = [[[SendMessageToWXReq alloc] init] autorelease]; + [req setBText:NO]; + [req setMessage:message]; + + [WXApi sendReq:req]; +} + +#pragma mark - Image process + +- (NSData *)resizeWithImage:(UIImage*)image scale:(CGFloat)scale compression:(CGFloat)compression +{ + CGSize newSize = CGSizeMake(image.size.width * scale, image.size.height * scale); + + UIGraphicsBeginImageContext(newSize); + [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; + UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return UIImageJPEGRepresentation(newImage, compression); +} + + +#pragma mark - Weixin delegate methods + + +- (void)onResp:(BaseResp *)resp +{ + switch ([resp errCode]) + { + case WXSuccess: + [self sendDidFinish]; + break; + case WXErrCodeUserCancel: + [self sendDidCancel]; + break; + default: + [self sendDidFailWithError:nil]; + break; + } +} +@end + diff --git a/Classes/ShareKit/UI/SHKOAuthView.m b/Classes/ShareKit/UI/SHKOAuthView.m index 736dcd316..431803492 100644 --- a/Classes/ShareKit/UI/SHKOAuthView.m +++ b/Classes/ShareKit/UI/SHKOAuthView.m @@ -80,7 +80,9 @@ - (void)viewDidDisappear:(BOOL)animated - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { - if ([request.URL.absoluteString rangeOfString:[delegate authorizeCallbackURL].absoluteString options:NSCaseInsensitiveSearch].location != NSNotFound) + if ([request.URL.absoluteString rangeOfString:@"authorize"].location == NSNotFound + && [request.URL.absoluteString rangeOfString:@"authenticate"].location == NSNotFound + && [request.URL.absoluteString rangeOfString:[delegate authorizeCallbackURL].absoluteString options:NSCaseInsensitiveSearch].location != NSNotFound) { // Get query NSMutableDictionary *queryParams = nil; diff --git a/README.md b/README.md index f37590400..9ca7167c9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,60 @@ +# 关于 ShareKit + +> 项目**不再**维护开发。 + +[Sharekit](https://github.com/ShareKit/ShareKit) 在社区的驱动下迎来了 2.0 版本的重生(原开发者已不再维护)。 + +`develop` 分支是基于社区驱动的基础上支持开发,因此今后的更新都是在当前分支。 + +> 迁移有风险,操作需谨慎。 + +# 服务 + +## 可用服务 + +1. 新浪微博 (支持新浪微博官方 SSO OAuth 及 iOS 6 特性) +2. 微信(仅支持分享到朋友) +3. 网易微博 +4. 腾讯微博 +5. 豆瓣 +6. 人人网 +7. Plurk (融合自[polydice/ShareKit-Sharers](https://github.com/polydice/ShareKit-Sharers)) + +## 快速链接 + +* [新功能](https://github.com/icyleaf/ShareKit/issues?labels=enhancement) +* [修复缺陷](https://github.com/icyleaf/ShareKit/issues?labels=bug) +* [答疑解惑](https://github.com/icyleaf/ShareKit/issues?labels=question) + +没有发现我想要的,希望[提交新需求](https://github.com/icyleaf/ShareKit/issues/new) + + +# 未来特性 + +当前的代码还是比较混乱,我不清楚社区是否会进行进行重构(以目前社区 Issue 看来是没有的),当国内服务整合差不多了,就开始对代码进行优化和重构,之后再进行更多特性的支持。下面是一个初步的计划。 + +* 优化代码(KISS) +* 多重分享 +* 额外服务端支持 + + +# 中文文档 + +> [Wiki](https://github.com/icyleaf/ShareKit/wiki) 计划中,尽情期待。 + + +# 技术支持 + +仅用于持续改进项目代码沟通(疑难杂症概不回复) + + > 不要私下咨询我为什么服务已经开发,到现在还没有完成,是不是因为私心不愿意公布。 + > 线上的代码就是全部! + +* Email: icyleaf.cn@gmail.com +* Twitter: @icyleaf +* 新浪微博: @icyleaf + + ShareKit 2.0 ============ @@ -19,4 +76,4 @@ Documentation The latest documentation and installation instructions can be found on the [ShareKit Wiki](https://github.com/ShareKit/ShareKit/wiki). -!!! Updated new service creation guidelines for contributors are [here](https://github.com/ShareKit/ShareKit/wiki/New-service-creator's-guidelines) !!! \ No newline at end of file +!!! Updated new service creation guidelines for contributors are [here](https://github.com/ShareKit/ShareKit/wiki/New-service-creator's-guidelines) !!! diff --git a/ShareKit-Info.plist b/ShareKit-Info.plist index d81f0e8e0..2bf9d399b 100644 --- a/ShareKit-Info.plist +++ b/ShareKit-Info.plist @@ -2,6 +2,8 @@ + CFBundleAllowMixedLocalizations + CFBundleDevelopmentRegion English CFBundleDisplayName @@ -14,8 +16,6 @@ com.yourcompany.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 - CFBundleAllowMixedLocalizations - CFBundleName ${PRODUCT_NAME} CFBundlePackageType @@ -25,10 +25,14 @@ CFBundleURLTypes + CFBundleTypeRole + Editor CFBundleURLName CFBundleURLSchemes + wx59794006e6eb35f5 + sinaweibosso.1631351849 fb232705466797125 app://flickr diff --git a/ShareKit.xcodeproj/project.pbxproj b/ShareKit.xcodeproj/project.pbxproj index 67d486181..9e9dbaa67 100755 --- a/ShareKit.xcodeproj/project.pbxproj +++ b/ShareKit.xcodeproj/project.pbxproj @@ -84,7 +84,6 @@ 7A16F38C161341570019645D /* OARequestParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A5369D11DBE3B9004A1712 /* OARequestParameter.m */; }; 7A16F38D161341570019645D /* OAServiceTicket.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A5369F11DBE3B9004A1712 /* OAServiceTicket.m */; }; 7A16F38E161341570019645D /* OAToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536A211DBE3B9004A1712 /* OAToken.m */; }; - 7A16F3B016134A790019645D /* SHKInstagram.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A16F3AE16134A790019645D /* SHKInstagram.h */; }; 7A16F3B216134A790019645D /* SHKInstagram.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A16F3AF16134A790019645D /* SHKInstagram.m */; }; 7A16F3B816134A890019645D /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; 7A16F3B916134A890019645D /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; @@ -258,20 +257,6 @@ 7AB5350A1552BE7D00171BCE /* SHKDiigo.m in Sources */ = {isa = PBXBuildFile; fileRef = B7EFCD8B14C6B966004910F1 /* SHKDiigo.m */; }; 7AB5350B1552BE7D00171BCE /* SHKVkontakteOAuthView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA5AA3B6149625460064DB24 /* SHKVkontakteOAuthView.m */; }; 7AB5350D1552BE7D00171BCE /* SHKVkontakte.m in Sources */ = {isa = PBXBuildFile; fileRef = FA5AA3BA149625460064DB24 /* SHKVkontakte.m */; }; - 7AB535101552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535121552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535141552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535161552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535181552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB5351A1552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB5351D1552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535201552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535221552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535241552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB535281552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB5352A1552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB5352D1552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; - 7AB5352F1552BE7D00171BCE /* (null) in Sources */ = {isa = PBXBuildFile; }; 7AB535311552BE7D00171BCE /* SHKEvernote.m in Sources */ = {isa = PBXBuildFile; fileRef = 4379F2B11291AC9700D2A41E /* SHKEvernote.m */; }; 7AB535351552BE7D00171BCE /* NSObject+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AC22D2814580A2000126878 /* NSObject+SBJSON.m */; }; 7AB535371552BE7D00171BCE /* NSString+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AC22D2A14580A2000126878 /* NSString+SBJSON.m */; }; @@ -523,6 +508,162 @@ 7AEE044F160E1DB600FEC06E /* SHKPinboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536E311DBE3B9004A1712 /* SHKPinboard.m */; }; 7AEE0450160E1DC500FEC06E /* SHKReadItLater.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536E611DBE3B9004A1712 /* SHKReadItLater.m */; }; 7AEE0451160E1DD200FEC06E /* SHKTumblr.m in Sources */ = {isa = PBXBuildFile; fileRef = 43C91DF411EBAE4800F31FAE /* SHKTumblr.m */; }; + AC42D795163645CF002FD7C6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC42D796163645CF002FD7C6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC42D797163645CF002FD7C6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC42D798163645CF002FD7C6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC42D799163645CF002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC42D79A163645CF002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC42D79B163645CF002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC42D7A0163645E8002FD7C6 /* SHKDouban.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6E5163638C7002FD7C6 /* SHKDouban.m */; }; + AC42D7A6163645F2002FD7C6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC42D7A7163645F2002FD7C6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC42D7A8163645F2002FD7C6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC42D7A9163645F2002FD7C6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC42D7AA163645F2002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC42D7AB163645F2002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC42D7AC163645F2002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC42D7CC16364628002FD7C6 /* SHKRenRen.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D73D163638C7002FD7C6 /* SHKRenRen.m */; }; + AC42D7D216364633002FD7C6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC42D7D316364633002FD7C6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC42D7D416364633002FD7C6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC42D7D516364633002FD7C6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC42D7D616364633002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC42D7D716364633002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC42D7D816364633002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC42D7DE1636464E002FD7C6 /* SHKNetEaseWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6E8163638C7002FD7C6 /* SHKNetEaseWeibo.m */; }; + AC42D7E416364656002FD7C6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC42D7E516364656002FD7C6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC42D7E616364656002FD7C6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC42D7E716364656002FD7C6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC42D7E816364656002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC42D7E916364656002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC42D7EA16364656002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC42D7F416364664002FD7C6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC42D7F516364664002FD7C6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC42D7F616364664002FD7C6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC42D7F716364664002FD7C6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC42D7F816364664002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC42D7F916364664002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC42D7FA16364664002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC42D7FF16364688002FD7C6 /* SHKTencentWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D743163638C7002FD7C6 /* SHKTencentWeibo.m */; }; + AC42D80016364691002FD7C6 /* SHKSinaWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D740163638C7002FD7C6 /* SHKSinaWeibo.m */; }; + AC42D8071636476A002FD7C6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC42D8081636476A002FD7C6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC42D8091636476A002FD7C6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC42D80A1636476A002FD7C6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC42D80B1636476A002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC42D80C1636476A002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC42D80D1636476A002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC42D815163648AB002FD7C6 /* RRConnect.bundle in Resources */ = {isa = PBXBuildFile; fileRef = AC42D814163648AB002FD7C6 /* RRConnect.bundle */; }; + AC42D816163648E0002FD7C6 /* ROError.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6F2163638C7002FD7C6 /* ROError.m */; }; + AC42D817163648E0002FD7C6 /* Renren.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D701163638C7002FD7C6 /* Renren.m */; }; + AC42D818163648E0002FD7C6 /* ROAlbumsInfoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D704163638C7002FD7C6 /* ROAlbumsInfoRequestParam.m */; }; + AC42D819163648E0002FD7C6 /* ROCreateAlbumRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D706163638C7002FD7C6 /* ROCreateAlbumRequestParam.m */; }; + AC42D81A163648E0002FD7C6 /* ROGetFriendsInfoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D708163638C7002FD7C6 /* ROGetFriendsInfoRequestParam.m */; }; + AC42D81B163648E0002FD7C6 /* ROGetFriendsRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D70A163638C7002FD7C6 /* ROGetFriendsRequestParam.m */; }; + AC42D81C163648E0002FD7C6 /* ROPasswordFlowRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D70C163638C7002FD7C6 /* ROPasswordFlowRequestParam.m */; }; + AC42D81D163648E0002FD7C6 /* ROPublishPhotoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D70E163638C7002FD7C6 /* ROPublishPhotoRequestParam.m */; }; + AC42D81E163648E0002FD7C6 /* RORequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D710163638C7002FD7C6 /* RORequestParam.m */; }; + AC42D81F163648E0002FD7C6 /* ROUserInfoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D712163638C7002FD7C6 /* ROUserInfoRequestParam.m */; }; + AC42D820163648E0002FD7C6 /* ROAlbumResponseltem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D715163638C7002FD7C6 /* ROAlbumResponseltem.m */; }; + AC42D821163648E0002FD7C6 /* ROCreateAlbumResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D717163638C7002FD7C6 /* ROCreateAlbumResponseItem.m */; }; + AC42D822163648E0002FD7C6 /* ROFriendResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D719163638C7002FD7C6 /* ROFriendResponseItem.m */; }; + AC42D823163648E0002FD7C6 /* ROPublishPhotoResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D71B163638C7002FD7C6 /* ROPublishPhotoResponseItem.m */; }; + AC42D824163648E0002FD7C6 /* ROResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D71D163638C7002FD7C6 /* ROResponseItem.m */; }; + AC42D825163648E0002FD7C6 /* ROUserResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D71F163638C7002FD7C6 /* ROUserResponseItem.m */; }; + AC42D826163648E0002FD7C6 /* RODialog.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D722163638C7002FD7C6 /* RODialog.m */; }; + AC42D827163648E0002FD7C6 /* RORequest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D724163638C7002FD7C6 /* RORequest.m */; }; + AC42D828163648E0002FD7C6 /* ROResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D726163638C7002FD7C6 /* ROResponse.m */; }; + AC42D829163648E0002FD7C6 /* RODialogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D729163638C7002FD7C6 /* RODialogModel.m */; }; + AC42D82A163648E0002FD7C6 /* RODialogView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D72B163638C7002FD7C6 /* RODialogView.m */; }; + AC42D82B163648E0002FD7C6 /* ROPublishPhotoDialogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D72E163638C7002FD7C6 /* ROPublishPhotoDialogModel.m */; }; + AC42D82C163648E0002FD7C6 /* ROPublishPhotoInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D730163638C7002FD7C6 /* ROPublishPhotoInternal.m */; }; + AC42D82D163648E0002FD7C6 /* ROUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D733163638C7002FD7C6 /* ROUtility.m */; }; + AC42D82E163648E0002FD7C6 /* ROCloseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D736163638C7002FD7C6 /* ROCloseButton.m */; }; + AC42D82F163648E0002FD7C6 /* ROGlobalStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D738163638C7002FD7C6 /* ROGlobalStyle.m */; }; + AC42D830163648E0002FD7C6 /* ROImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D73A163638C7002FD7C6 /* ROImageView.m */; }; + AC42D83616364BBF002FD7C6 /* SHKDouban.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6E5163638C7002FD7C6 /* SHKDouban.m */; }; + AC42D83C16364CA2002FD7C6 /* SHKNetEaseWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6E8163638C7002FD7C6 /* SHKNetEaseWeibo.m */; }; + AC42D83D16364CA2002FD7C6 /* SHKPlurk.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6EC163638C7002FD7C6 /* SHKPlurk.m */; }; + AC42D83E16364CA2002FD7C6 /* ROError.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D6F2163638C7002FD7C6 /* ROError.m */; }; + AC42D83F16364CA2002FD7C6 /* Renren.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D701163638C7002FD7C6 /* Renren.m */; }; + AC42D84016364CA2002FD7C6 /* ROAlbumsInfoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D704163638C7002FD7C6 /* ROAlbumsInfoRequestParam.m */; }; + AC42D84116364CA2002FD7C6 /* ROCreateAlbumRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D706163638C7002FD7C6 /* ROCreateAlbumRequestParam.m */; }; + AC42D84216364CA2002FD7C6 /* ROGetFriendsInfoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D708163638C7002FD7C6 /* ROGetFriendsInfoRequestParam.m */; }; + AC42D84316364CA2002FD7C6 /* ROGetFriendsRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D70A163638C7002FD7C6 /* ROGetFriendsRequestParam.m */; }; + AC42D84416364CA2002FD7C6 /* ROPasswordFlowRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D70C163638C7002FD7C6 /* ROPasswordFlowRequestParam.m */; }; + AC42D84516364CA2002FD7C6 /* ROPublishPhotoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D70E163638C7002FD7C6 /* ROPublishPhotoRequestParam.m */; }; + AC42D84616364CA2002FD7C6 /* RORequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D710163638C7002FD7C6 /* RORequestParam.m */; }; + AC42D84716364CA2002FD7C6 /* ROUserInfoRequestParam.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D712163638C7002FD7C6 /* ROUserInfoRequestParam.m */; }; + AC42D84816364CA2002FD7C6 /* ROAlbumResponseltem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D715163638C7002FD7C6 /* ROAlbumResponseltem.m */; }; + AC42D84916364CA2002FD7C6 /* ROCreateAlbumResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D717163638C7002FD7C6 /* ROCreateAlbumResponseItem.m */; }; + AC42D84A16364CA2002FD7C6 /* ROFriendResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D719163638C7002FD7C6 /* ROFriendResponseItem.m */; }; + AC42D84B16364CA2002FD7C6 /* ROPublishPhotoResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D71B163638C7002FD7C6 /* ROPublishPhotoResponseItem.m */; }; + AC42D84C16364CA2002FD7C6 /* ROResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D71D163638C7002FD7C6 /* ROResponseItem.m */; }; + AC42D84D16364CA2002FD7C6 /* ROUserResponseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D71F163638C7002FD7C6 /* ROUserResponseItem.m */; }; + AC42D84E16364CA2002FD7C6 /* RODialog.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D722163638C7002FD7C6 /* RODialog.m */; }; + AC42D84F16364CA2002FD7C6 /* RORequest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D724163638C7002FD7C6 /* RORequest.m */; }; + AC42D85016364CA2002FD7C6 /* ROResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D726163638C7002FD7C6 /* ROResponse.m */; }; + AC42D85116364CA2002FD7C6 /* RODialogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D729163638C7002FD7C6 /* RODialogModel.m */; }; + AC42D85216364CA2002FD7C6 /* RODialogView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D72B163638C7002FD7C6 /* RODialogView.m */; }; + AC42D85316364CA2002FD7C6 /* ROPublishPhotoDialogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D72E163638C7002FD7C6 /* ROPublishPhotoDialogModel.m */; }; + AC42D85416364CA2002FD7C6 /* ROPublishPhotoInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D730163638C7002FD7C6 /* ROPublishPhotoInternal.m */; }; + AC42D85516364CA2002FD7C6 /* ROUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D733163638C7002FD7C6 /* ROUtility.m */; }; + AC42D85616364CA2002FD7C6 /* ROCloseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D736163638C7002FD7C6 /* ROCloseButton.m */; }; + AC42D85716364CA2002FD7C6 /* ROGlobalStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D738163638C7002FD7C6 /* ROGlobalStyle.m */; }; + AC42D85816364CA2002FD7C6 /* ROImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D73A163638C7002FD7C6 /* ROImageView.m */; }; + AC42D85916364CA2002FD7C6 /* SHKRenRen.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D73D163638C7002FD7C6 /* SHKRenRen.m */; }; + AC42D85A16364CA2002FD7C6 /* SHKSinaWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D740163638C7002FD7C6 /* SHKSinaWeibo.m */; }; + AC42D85B16364CA2002FD7C6 /* SHKTencentWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D743163638C7002FD7C6 /* SHKTencentWeibo.m */; }; + AC42D85C16364CA2002FD7C6 /* TencentOAMutableURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D746163638C7002FD7C6 /* TencentOAMutableURLRequest.m */; }; + AC42D85D16364CA2002FD7C6 /* TencentOAuthView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D749163638C7002FD7C6 /* TencentOAuthView.m */; }; + AC42D85E16364CC5002FD7C6 /* TencentOAMutableURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D746163638C7002FD7C6 /* TencentOAMutableURLRequest.m */; }; + AC42D85F16364CC5002FD7C6 /* TencentOAuthView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D749163638C7002FD7C6 /* TencentOAuthView.m */; }; + AC42D89E163661DE002FD7C6 /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AC42D89D163661DE002FD7C6 /* Social.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + AC42D8A1163669F3002FD7C6 /* SHKiOS6SinaWeibo.h in Headers */ = {isa = PBXBuildFile; fileRef = AC42D89F163669F3002FD7C6 /* SHKiOS6SinaWeibo.h */; }; + AC42D8A2163669F3002FD7C6 /* SHKiOS6SinaWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D8A0163669F3002FD7C6 /* SHKiOS6SinaWeibo.m */; }; + AC42D8A316366F4F002FD7C6 /* SHKiOS6SinaWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC42D8A0163669F3002FD7C6 /* SHKiOS6SinaWeibo.m */; }; + AC67CE581643A4C800C74ECE /* SHKTencentWeixin.m in Sources */ = {isa = PBXBuildFile; fileRef = AC67CE561643A4C800C74ECE /* SHKTencentWeixin.m */; }; + AC91A950163908C00055FEF6 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + AC91A951163908C00055FEF6 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + AC91A952163908C00055FEF6 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + AC91A953163908C00055FEF6 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + AC91A954163908C00055FEF6 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + AC91A955163908C00055FEF6 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + AC91A956163908C00055FEF6 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + AC91A957163908C00055FEF6 /* SHKiOS6SinaWeibo.h in Headers */ = {isa = PBXBuildFile; fileRef = AC42D89F163669F3002FD7C6 /* SHKiOS6SinaWeibo.h */; }; + AC91A966163908E60055FEF6 /* SinaWeibo.bundle in Resources */ = {isa = PBXBuildFile; fileRef = AC91A95E163908E60055FEF6 /* SinaWeibo.bundle */; }; + AC91A968163908E60055FEF6 /* SinaWeibo.h in Headers */ = {isa = PBXBuildFile; fileRef = AC91A95F163908E60055FEF6 /* SinaWeibo.h */; }; + AC91A969163908E60055FEF6 /* SinaWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC91A960163908E60055FEF6 /* SinaWeibo.m */; }; + AC91A96B163908E60055FEF6 /* SinaWeibo.m in Sources */ = {isa = PBXBuildFile; fileRef = AC91A960163908E60055FEF6 /* SinaWeibo.m */; }; + AC91A96D163908E60055FEF6 /* SinaWeiboAuthorizeView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC91A961163908E60055FEF6 /* SinaWeiboAuthorizeView.h */; }; + AC91A96E163908E60055FEF6 /* SinaWeiboAuthorizeView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC91A962163908E60055FEF6 /* SinaWeiboAuthorizeView.m */; }; + AC91A970163908E60055FEF6 /* SinaWeiboAuthorizeView.m in Sources */ = {isa = PBXBuildFile; fileRef = AC91A962163908E60055FEF6 /* SinaWeiboAuthorizeView.m */; }; + AC91A972163908E60055FEF6 /* SinaWeiboConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AC91A963163908E60055FEF6 /* SinaWeiboConstants.h */; }; + AC91A974163908E60055FEF6 /* SinaWeiboRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = AC91A964163908E60055FEF6 /* SinaWeiboRequest.h */; }; + AC91A975163908E60055FEF6 /* SinaWeiboRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC91A965163908E60055FEF6 /* SinaWeiboRequest.m */; }; + AC91A977163908E60055FEF6 /* SinaWeiboRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC91A965163908E60055FEF6 /* SinaWeiboRequest.m */; }; + ACF7F8061643B2B6002947F0 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + ACF7F8071643B2B6002947F0 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + ACF7F8081643B2B6002947F0 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + ACF7F8091643B2B6002947F0 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + ACF7F80A1643B2B6002947F0 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + ACF7F80B1643B2B6002947F0 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + ACF7F80C1643B2B6002947F0 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + ACF7F80D1643B2B6002947F0 /* SHKiOS6SinaWeibo.h in Headers */ = {isa = PBXBuildFile; fileRef = AC42D89F163669F3002FD7C6 /* SHKiOS6SinaWeibo.h */; }; + ACF7F8231643B45B002947F0 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B4156CD8A70011E15F /* Base64Transcoder.h */; }; + ACF7F8241643B45B002947F0 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B6156CD8A70011E15F /* hmac.h */; }; + ACF7F8251643B45B002947F0 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A26E5B8156CD8A70011E15F /* sha1.h */; }; + ACF7F8261643B45B002947F0 /* SHKFormFieldCellText.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A164DC0157662ED00D55DB4 /* SHKFormFieldCellText.h */; }; + ACF7F8271643B45B002947F0 /* SHKFormFieldCellSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBA71577528B003BBFFD /* SHKFormFieldCellSwitch.h */; }; + ACF7F8281643B45B002947F0 /* SHKFormFieldCellOptionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ABCDBAE157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h */; }; + ACF7F8291643B45B002947F0 /* SHKFormFieldCell_PrivateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A4CAA161577BEF90010E6B3 /* SHKFormFieldCell_PrivateProperties.h */; }; + ACF7F82E1643B48E002947F0 /* SHKTencentWeixin.m in Sources */ = {isa = PBXBuildFile; fileRef = AC67CE561643A4C800C74ECE /* SHKTencentWeixin.m */; }; + ACF7F82F1643B497002947F0 /* WXApi.h in Sources */ = {isa = PBXBuildFile; fileRef = AC67CE4D1643A46200C74ECE /* WXApi.h */; }; + ACF7F8301643B497002947F0 /* WXApiObject.h in Sources */ = {isa = PBXBuildFile; fileRef = AC67CE4E1643A46200C74ECE /* WXApiObject.h */; }; + ACF7F8331643B543002947F0 /* libWeChatSDK_armv7_armv7s.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AC67CE4C1643A46200C74ECE /* libWeChatSDK_armv7_armv7s.a */; }; + ACF7F8341643B563002947F0 /* libWeChatSDK_armv7_armv7s.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AC67CE4C1643A46200C74ECE /* libWeChatSDK_armv7_armv7s.a */; }; C0D3077B147BDC8100E74EA3 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0D3077A147BDC8100E74EA3 /* CoreLocation.framework */; }; /* End PBXBuildFile section */ @@ -838,6 +979,103 @@ AAACE01A13CCB1F500A2118F /* SHKConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKConfiguration.m; sourceTree = ""; }; AAACE06013CCBED400A2118F /* SHKFlickr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKFlickr.h; sourceTree = ""; }; AAACE06113CCBED400A2118F /* SHKFlickr.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKFlickr.m; sourceTree = ""; }; + AC42D6E3163638C7002FD7C6 /* SHKDouban.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKDouban.h; sourceTree = ""; }; + AC42D6E5163638C7002FD7C6 /* SHKDouban.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKDouban.m; sourceTree = ""; }; + AC42D6E7163638C7002FD7C6 /* SHKNetEaseWeibo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKNetEaseWeibo.h; sourceTree = ""; }; + AC42D6E8163638C7002FD7C6 /* SHKNetEaseWeibo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKNetEaseWeibo.m; sourceTree = ""; }; + AC42D6EA163638C7002FD7C6 /* SHKPlurk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKPlurk.h; sourceTree = ""; }; + AC42D6EC163638C7002FD7C6 /* SHKPlurk.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKPlurk.m; sourceTree = ""; }; + AC42D6F1163638C7002FD7C6 /* ROError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROError.h; sourceTree = ""; }; + AC42D6F2163638C7002FD7C6 /* ROError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROError.m; sourceTree = ""; }; + AC42D700163638C7002FD7C6 /* Renren.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Renren.h; sourceTree = ""; }; + AC42D701163638C7002FD7C6 /* Renren.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Renren.m; sourceTree = ""; }; + AC42D703163638C7002FD7C6 /* ROAlbumsInfoRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROAlbumsInfoRequestParam.h; sourceTree = ""; }; + AC42D704163638C7002FD7C6 /* ROAlbumsInfoRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROAlbumsInfoRequestParam.m; sourceTree = ""; }; + AC42D705163638C7002FD7C6 /* ROCreateAlbumRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROCreateAlbumRequestParam.h; sourceTree = ""; }; + AC42D706163638C7002FD7C6 /* ROCreateAlbumRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROCreateAlbumRequestParam.m; sourceTree = ""; }; + AC42D707163638C7002FD7C6 /* ROGetFriendsInfoRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROGetFriendsInfoRequestParam.h; sourceTree = ""; }; + AC42D708163638C7002FD7C6 /* ROGetFriendsInfoRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROGetFriendsInfoRequestParam.m; sourceTree = ""; }; + AC42D709163638C7002FD7C6 /* ROGetFriendsRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROGetFriendsRequestParam.h; sourceTree = ""; }; + AC42D70A163638C7002FD7C6 /* ROGetFriendsRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROGetFriendsRequestParam.m; sourceTree = ""; }; + AC42D70B163638C7002FD7C6 /* ROPasswordFlowRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROPasswordFlowRequestParam.h; sourceTree = ""; }; + AC42D70C163638C7002FD7C6 /* ROPasswordFlowRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROPasswordFlowRequestParam.m; sourceTree = ""; }; + AC42D70D163638C7002FD7C6 /* ROPublishPhotoRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROPublishPhotoRequestParam.h; sourceTree = ""; }; + AC42D70E163638C7002FD7C6 /* ROPublishPhotoRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROPublishPhotoRequestParam.m; sourceTree = ""; }; + AC42D70F163638C7002FD7C6 /* RORequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RORequestParam.h; sourceTree = ""; }; + AC42D710163638C7002FD7C6 /* RORequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RORequestParam.m; sourceTree = ""; }; + AC42D711163638C7002FD7C6 /* ROUserInfoRequestParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROUserInfoRequestParam.h; sourceTree = ""; }; + AC42D712163638C7002FD7C6 /* ROUserInfoRequestParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROUserInfoRequestParam.m; sourceTree = ""; }; + AC42D714163638C7002FD7C6 /* ROAlbumResponseltem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROAlbumResponseltem.h; sourceTree = ""; }; + AC42D715163638C7002FD7C6 /* ROAlbumResponseltem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROAlbumResponseltem.m; sourceTree = ""; }; + AC42D716163638C7002FD7C6 /* ROCreateAlbumResponseItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROCreateAlbumResponseItem.h; sourceTree = ""; }; + AC42D717163638C7002FD7C6 /* ROCreateAlbumResponseItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROCreateAlbumResponseItem.m; sourceTree = ""; }; + AC42D718163638C7002FD7C6 /* ROFriendResponseItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROFriendResponseItem.h; sourceTree = ""; }; + AC42D719163638C7002FD7C6 /* ROFriendResponseItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROFriendResponseItem.m; sourceTree = ""; }; + AC42D71A163638C7002FD7C6 /* ROPublishPhotoResponseItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROPublishPhotoResponseItem.h; sourceTree = ""; }; + AC42D71B163638C7002FD7C6 /* ROPublishPhotoResponseItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROPublishPhotoResponseItem.m; sourceTree = ""; }; + AC42D71C163638C7002FD7C6 /* ROResponseItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROResponseItem.h; sourceTree = ""; }; + AC42D71D163638C7002FD7C6 /* ROResponseItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROResponseItem.m; sourceTree = ""; }; + AC42D71E163638C7002FD7C6 /* ROUserResponseItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROUserResponseItem.h; sourceTree = ""; }; + AC42D71F163638C7002FD7C6 /* ROUserResponseItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROUserResponseItem.m; sourceTree = ""; }; + AC42D720163638C7002FD7C6 /* ROConnect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROConnect.h; sourceTree = ""; }; + AC42D721163638C7002FD7C6 /* RODialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RODialog.h; sourceTree = ""; }; + AC42D722163638C7002FD7C6 /* RODialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RODialog.m; sourceTree = ""; }; + AC42D723163638C7002FD7C6 /* RORequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RORequest.h; sourceTree = ""; }; + AC42D724163638C7002FD7C6 /* RORequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RORequest.m; sourceTree = ""; }; + AC42D725163638C7002FD7C6 /* ROResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROResponse.h; sourceTree = ""; }; + AC42D726163638C7002FD7C6 /* ROResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROResponse.m; sourceTree = ""; }; + AC42D728163638C7002FD7C6 /* RODialogModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RODialogModel.h; sourceTree = ""; }; + AC42D729163638C7002FD7C6 /* RODialogModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RODialogModel.m; sourceTree = ""; }; + AC42D72A163638C7002FD7C6 /* RODialogView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RODialogView.h; sourceTree = ""; }; + AC42D72B163638C7002FD7C6 /* RODialogView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RODialogView.m; sourceTree = ""; }; + AC42D72D163638C7002FD7C6 /* ROPublishPhotoDialogModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROPublishPhotoDialogModel.h; sourceTree = ""; }; + AC42D72E163638C7002FD7C6 /* ROPublishPhotoDialogModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROPublishPhotoDialogModel.m; sourceTree = ""; }; + AC42D72F163638C7002FD7C6 /* ROPublishPhotoInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROPublishPhotoInternal.h; sourceTree = ""; }; + AC42D730163638C7002FD7C6 /* ROPublishPhotoInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROPublishPhotoInternal.m; sourceTree = ""; }; + AC42D732163638C7002FD7C6 /* ROUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROUtility.h; sourceTree = ""; }; + AC42D733163638C7002FD7C6 /* ROUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROUtility.m; sourceTree = ""; }; + AC42D735163638C7002FD7C6 /* ROCloseButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROCloseButton.h; sourceTree = ""; }; + AC42D736163638C7002FD7C6 /* ROCloseButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROCloseButton.m; sourceTree = ""; }; + AC42D737163638C7002FD7C6 /* ROGlobalStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROGlobalStyle.h; sourceTree = ""; }; + AC42D738163638C7002FD7C6 /* ROGlobalStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROGlobalStyle.m; sourceTree = ""; }; + AC42D739163638C7002FD7C6 /* ROImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ROImageView.h; sourceTree = ""; }; + AC42D73A163638C7002FD7C6 /* ROImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ROImageView.m; sourceTree = ""; }; + AC42D73B163638C7002FD7C6 /* SHKRenRen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKRenRen.h; sourceTree = ""; }; + AC42D73D163638C7002FD7C6 /* SHKRenRen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKRenRen.m; sourceTree = ""; }; + AC42D73F163638C7002FD7C6 /* SHKSinaWeibo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKSinaWeibo.h; sourceTree = ""; }; + AC42D740163638C7002FD7C6 /* SHKSinaWeibo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKSinaWeibo.m; sourceTree = ""; }; + AC42D742163638C7002FD7C6 /* SHKTencentWeibo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTencentWeibo.h; sourceTree = ""; }; + AC42D743163638C7002FD7C6 /* SHKTencentWeibo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTencentWeibo.m; sourceTree = ""; }; + AC42D744163638C7002FD7C6 /* TencentOAMutableURLRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TencentOAMutableURLRequest.h; sourceTree = ""; }; + AC42D746163638C7002FD7C6 /* TencentOAMutableURLRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TencentOAMutableURLRequest.m; sourceTree = ""; }; + AC42D747163638C7002FD7C6 /* TencentOAuthView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TencentOAuthView.h; sourceTree = ""; }; + AC42D749163638C7002FD7C6 /* TencentOAuthView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TencentOAuthView.m; sourceTree = ""; }; + AC42D79F163645CF002FD7C6 /* libDouban.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDouban.a; sourceTree = BUILT_PRODUCTS_DIR; }; + AC42D7B0163645F2002FD7C6 /* libRenren.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRenren.a; sourceTree = BUILT_PRODUCTS_DIR; }; + AC42D7DC16364634002FD7C6 /* libNetEase Weibo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libNetEase Weibo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AC42D7EE16364656002FD7C6 /* libTencent Weibo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libTencent Weibo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AC42D7FE16364664002FD7C6 /* libSina Weibo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSina Weibo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AC42D8111636476A002FD7C6 /* libRenren SDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRenren SDK.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AC42D814163648AB002FD7C6 /* RRConnect.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = RRConnect.bundle; sourceTree = ""; }; + AC42D89D163661DE002FD7C6 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; + AC42D89F163669F3002FD7C6 /* SHKiOS6SinaWeibo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKiOS6SinaWeibo.h; sourceTree = ""; }; + AC42D8A0163669F3002FD7C6 /* SHKiOS6SinaWeibo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKiOS6SinaWeibo.m; sourceTree = ""; }; + AC67CE4C1643A46200C74ECE /* libWeChatSDK_armv7_armv7s.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWeChatSDK_armv7_armv7s.a; sourceTree = ""; }; + AC67CE4D1643A46200C74ECE /* WXApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApi.h; sourceTree = ""; }; + AC67CE4E1643A46200C74ECE /* WXApiObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXApiObject.h; sourceTree = ""; }; + AC67CE551643A4C800C74ECE /* SHKTencentWeixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTencentWeixin.h; sourceTree = ""; }; + AC67CE561643A4C800C74ECE /* SHKTencentWeixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTencentWeixin.m; sourceTree = ""; }; + AC91A95B163908C00055FEF6 /* libSina Weibo SDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSina Weibo SDK.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AC91A95E163908E60055FEF6 /* SinaWeibo.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SinaWeibo.bundle; sourceTree = ""; }; + AC91A95F163908E60055FEF6 /* SinaWeibo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinaWeibo.h; sourceTree = ""; }; + AC91A960163908E60055FEF6 /* SinaWeibo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SinaWeibo.m; sourceTree = ""; }; + AC91A961163908E60055FEF6 /* SinaWeiboAuthorizeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinaWeiboAuthorizeView.h; sourceTree = ""; }; + AC91A962163908E60055FEF6 /* SinaWeiboAuthorizeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SinaWeiboAuthorizeView.m; sourceTree = ""; }; + AC91A963163908E60055FEF6 /* SinaWeiboConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinaWeiboConstants.h; sourceTree = ""; }; + AC91A964163908E60055FEF6 /* SinaWeiboRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinaWeiboRequest.h; sourceTree = ""; }; + AC91A965163908E60055FEF6 /* SinaWeiboRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SinaWeiboRequest.m; sourceTree = ""; }; + ACF7F8151643B2B6002947F0 /* libTencent Weixin SDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libTencent Weixin SDK.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + ACF7F82D1643B45B002947F0 /* libTencent Weixin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libTencent Weixin.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B7EFCD8A14C6B966004910F1 /* SHKDiigo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKDiigo.h; sourceTree = ""; }; B7EFCD8B14C6B966004910F1 /* SHKDiigo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKDiigo.m; sourceTree = ""; }; BA465F1D14CC3C5A00B52394 /* SHKPrint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKPrint.h; sourceTree = ""; }; @@ -877,10 +1115,11 @@ buildActionMask = 2147483647; files = ( 7A28825E15540175007DC379 /* libShareKit.a in Frameworks */, - 7A2B025614A342D800E68A4C /* CFNetwork.framework in Frameworks */, + AC42D89E163661DE002FD7C6 /* Social.framework in Frameworks */, 7A3C61EE147520B700C47D14 /* Twitter.framework in Frameworks */, - C0D3077B147BDC8100E74EA3 /* CoreLocation.framework in Frameworks */, 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + C0D3077B147BDC8100E74EA3 /* CoreLocation.framework in Frameworks */, + 7A2B025614A342D800E68A4C /* CFNetwork.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, 4312CF7C11CB33E200E61D7A /* MessageUI.framework in Frameworks */, @@ -970,6 +1209,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + ACF7F8341643B563002947F0 /* libWeChatSDK_armv7_armv7s.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1127,6 +1367,70 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AC42D793163645CF002FD7C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7A4163645F2002FD7C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7D016364633002FD7C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7E216364656002FD7C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7F216364664002FD7C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D8051636476A002FD7C6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC91A94E163908C00055FEF6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ACF7F8041643B2B6002947F0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ACF7F8331643B543002947F0 /* libWeChatSDK_armv7_armv7s.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ACF7F8211643B45B002947F0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1177,6 +1481,15 @@ 7AEE043D160E1D5B00FEC06E /* libTumblr.a */, 7A16F37E161340DD0019645D /* libOAuth.a */, 7A16F3C216134A890019645D /* libInstagram.a */, + AC42D79F163645CF002FD7C6 /* libDouban.a */, + AC42D7B0163645F2002FD7C6 /* libRenren.a */, + AC42D7DC16364634002FD7C6 /* libNetEase Weibo.a */, + AC42D7EE16364656002FD7C6 /* libTencent Weibo.a */, + AC42D7FE16364664002FD7C6 /* libSina Weibo.a */, + AC42D8111636476A002FD7C6 /* libRenren SDK.a */, + AC91A95B163908C00055FEF6 /* libSina Weibo SDK.a */, + ACF7F8151643B2B6002947F0 /* libTencent Weixin SDK.a */, + ACF7F82D1643B45B002947F0 /* libTencent Weixin.a */, ); name = Products; sourceTree = ""; @@ -1229,6 +1542,7 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( + AC42D89D163661DE002FD7C6 /* Social.framework */, 7A2B025514A342D800E68A4C /* CFNetwork.framework */, 7A3C61ED147520B700C47D14 /* Twitter.framework */, C0D3077A147BDC8100E74EA3 /* CoreLocation.framework */, @@ -1566,8 +1880,8 @@ 43A536B511DBE3B9004A1712 /* Sharers */ = { isa = PBXGroup; children = ( - 43A536B611DBE3B9004A1712 /* Actions */, AAACE01413CCB1F500A2118F /* Configuration */, + 43A536B611DBE3B9004A1712 /* Actions */, 43A536C011DBE3B9004A1712 /* Services */, ); path = Sharers; @@ -1617,6 +1931,13 @@ 43A536C011DBE3B9004A1712 /* Services */ = { isa = PBXGroup; children = ( + AC42D6E2163638C7002FD7C6 /* Douban */, + AC42D6E6163638C7002FD7C6 /* NetEase Weibo */, + AC42D6E9163638C7002FD7C6 /* Plurk */, + AC42D6ED163638C7002FD7C6 /* Renren */, + AC42D73E163638C7002FD7C6 /* Sina Weibo */, + AC42D741163638C7002FD7C6 /* Tencent Weibo */, + AC67CE491643A46200C74ECE /* Tencent Weixin */, 7A16F3AC16134A5D0019645D /* Instagram */, 1A52EDF315CB032B00A737D8 /* Kippt */, 7A0F91CB156B9FCE009CB40A /* Delicious */, @@ -1886,6 +2207,231 @@ path = Flickr; sourceTree = ""; }; + AC42D6E2163638C7002FD7C6 /* Douban */ = { + isa = PBXGroup; + children = ( + AC42D6E3163638C7002FD7C6 /* SHKDouban.h */, + AC42D6E5163638C7002FD7C6 /* SHKDouban.m */, + ); + path = Douban; + sourceTree = ""; + }; + AC42D6E6163638C7002FD7C6 /* NetEase Weibo */ = { + isa = PBXGroup; + children = ( + AC42D6E7163638C7002FD7C6 /* SHKNetEaseWeibo.h */, + AC42D6E8163638C7002FD7C6 /* SHKNetEaseWeibo.m */, + ); + path = "NetEase Weibo"; + sourceTree = ""; + }; + AC42D6E9163638C7002FD7C6 /* Plurk */ = { + isa = PBXGroup; + children = ( + AC42D6EA163638C7002FD7C6 /* SHKPlurk.h */, + AC42D6EC163638C7002FD7C6 /* SHKPlurk.m */, + ); + path = Plurk; + sourceTree = ""; + }; + AC42D6ED163638C7002FD7C6 /* Renren */ = { + isa = PBXGroup; + children = ( + AC42D6EE163638C7002FD7C6 /* RRConnect */, + AC42D73B163638C7002FD7C6 /* SHKRenRen.h */, + AC42D73D163638C7002FD7C6 /* SHKRenRen.m */, + ); + path = Renren; + sourceTree = ""; + }; + AC42D6EE163638C7002FD7C6 /* RRConnect */ = { + isa = PBXGroup; + children = ( + AC42D6EF163638C7002FD7C6 /* Renren */, + ); + path = RRConnect; + sourceTree = ""; + }; + AC42D6EF163638C7002FD7C6 /* Renren */ = { + isa = PBXGroup; + children = ( + AC42D814163648AB002FD7C6 /* RRConnect.bundle */, + AC42D6F0163638C7002FD7C6 /* Error */, + AC42D700163638C7002FD7C6 /* Renren.h */, + AC42D701163638C7002FD7C6 /* Renren.m */, + AC42D702163638C7002FD7C6 /* RequestParam */, + AC42D713163638C7002FD7C6 /* ResponseItem */, + AC42D720163638C7002FD7C6 /* ROConnect.h */, + AC42D721163638C7002FD7C6 /* RODialog.h */, + AC42D722163638C7002FD7C6 /* RODialog.m */, + AC42D723163638C7002FD7C6 /* RORequest.h */, + AC42D724163638C7002FD7C6 /* RORequest.m */, + AC42D725163638C7002FD7C6 /* ROResponse.h */, + AC42D726163638C7002FD7C6 /* ROResponse.m */, + AC42D727163638C7002FD7C6 /* Sample UI */, + AC42D731163638C7002FD7C6 /* Tools */, + ); + path = Renren; + sourceTree = ""; + }; + AC42D6F0163638C7002FD7C6 /* Error */ = { + isa = PBXGroup; + children = ( + AC42D6F1163638C7002FD7C6 /* ROError.h */, + AC42D6F2163638C7002FD7C6 /* ROError.m */, + ); + path = Error; + sourceTree = ""; + }; + AC42D702163638C7002FD7C6 /* RequestParam */ = { + isa = PBXGroup; + children = ( + AC42D703163638C7002FD7C6 /* ROAlbumsInfoRequestParam.h */, + AC42D704163638C7002FD7C6 /* ROAlbumsInfoRequestParam.m */, + AC42D705163638C7002FD7C6 /* ROCreateAlbumRequestParam.h */, + AC42D706163638C7002FD7C6 /* ROCreateAlbumRequestParam.m */, + AC42D707163638C7002FD7C6 /* ROGetFriendsInfoRequestParam.h */, + AC42D708163638C7002FD7C6 /* ROGetFriendsInfoRequestParam.m */, + AC42D709163638C7002FD7C6 /* ROGetFriendsRequestParam.h */, + AC42D70A163638C7002FD7C6 /* ROGetFriendsRequestParam.m */, + AC42D70B163638C7002FD7C6 /* ROPasswordFlowRequestParam.h */, + AC42D70C163638C7002FD7C6 /* ROPasswordFlowRequestParam.m */, + AC42D70D163638C7002FD7C6 /* ROPublishPhotoRequestParam.h */, + AC42D70E163638C7002FD7C6 /* ROPublishPhotoRequestParam.m */, + AC42D70F163638C7002FD7C6 /* RORequestParam.h */, + AC42D710163638C7002FD7C6 /* RORequestParam.m */, + AC42D711163638C7002FD7C6 /* ROUserInfoRequestParam.h */, + AC42D712163638C7002FD7C6 /* ROUserInfoRequestParam.m */, + ); + path = RequestParam; + sourceTree = ""; + }; + AC42D713163638C7002FD7C6 /* ResponseItem */ = { + isa = PBXGroup; + children = ( + AC42D714163638C7002FD7C6 /* ROAlbumResponseltem.h */, + AC42D715163638C7002FD7C6 /* ROAlbumResponseltem.m */, + AC42D716163638C7002FD7C6 /* ROCreateAlbumResponseItem.h */, + AC42D717163638C7002FD7C6 /* ROCreateAlbumResponseItem.m */, + AC42D718163638C7002FD7C6 /* ROFriendResponseItem.h */, + AC42D719163638C7002FD7C6 /* ROFriendResponseItem.m */, + AC42D71A163638C7002FD7C6 /* ROPublishPhotoResponseItem.h */, + AC42D71B163638C7002FD7C6 /* ROPublishPhotoResponseItem.m */, + AC42D71C163638C7002FD7C6 /* ROResponseItem.h */, + AC42D71D163638C7002FD7C6 /* ROResponseItem.m */, + AC42D71E163638C7002FD7C6 /* ROUserResponseItem.h */, + AC42D71F163638C7002FD7C6 /* ROUserResponseItem.m */, + ); + path = ResponseItem; + sourceTree = ""; + }; + AC42D727163638C7002FD7C6 /* Sample UI */ = { + isa = PBXGroup; + children = ( + AC42D728163638C7002FD7C6 /* RODialogModel.h */, + AC42D729163638C7002FD7C6 /* RODialogModel.m */, + AC42D72A163638C7002FD7C6 /* RODialogView.h */, + AC42D72B163638C7002FD7C6 /* RODialogView.m */, + AC42D72C163638C7002FD7C6 /* UploadPhotoDialog */, + ); + path = "Sample UI"; + sourceTree = ""; + }; + AC42D72C163638C7002FD7C6 /* UploadPhotoDialog */ = { + isa = PBXGroup; + children = ( + AC42D72D163638C7002FD7C6 /* ROPublishPhotoDialogModel.h */, + AC42D72E163638C7002FD7C6 /* ROPublishPhotoDialogModel.m */, + AC42D72F163638C7002FD7C6 /* ROPublishPhotoInternal.h */, + AC42D730163638C7002FD7C6 /* ROPublishPhotoInternal.m */, + ); + path = UploadPhotoDialog; + sourceTree = ""; + }; + AC42D731163638C7002FD7C6 /* Tools */ = { + isa = PBXGroup; + children = ( + AC42D732163638C7002FD7C6 /* ROUtility.h */, + AC42D733163638C7002FD7C6 /* ROUtility.m */, + AC42D734163638C7002FD7C6 /* UI */, + ); + path = Tools; + sourceTree = ""; + }; + AC42D734163638C7002FD7C6 /* UI */ = { + isa = PBXGroup; + children = ( + AC42D735163638C7002FD7C6 /* ROCloseButton.h */, + AC42D736163638C7002FD7C6 /* ROCloseButton.m */, + AC42D737163638C7002FD7C6 /* ROGlobalStyle.h */, + AC42D738163638C7002FD7C6 /* ROGlobalStyle.m */, + AC42D739163638C7002FD7C6 /* ROImageView.h */, + AC42D73A163638C7002FD7C6 /* ROImageView.m */, + ); + path = UI; + sourceTree = ""; + }; + AC42D73E163638C7002FD7C6 /* Sina Weibo */ = { + isa = PBXGroup; + children = ( + AC91A95D163908E60055FEF6 /* SSO SDK */, + AC42D89F163669F3002FD7C6 /* SHKiOS6SinaWeibo.h */, + AC42D8A0163669F3002FD7C6 /* SHKiOS6SinaWeibo.m */, + AC42D73F163638C7002FD7C6 /* SHKSinaWeibo.h */, + AC42D740163638C7002FD7C6 /* SHKSinaWeibo.m */, + ); + path = "Sina Weibo"; + sourceTree = ""; + }; + AC42D741163638C7002FD7C6 /* Tencent Weibo */ = { + isa = PBXGroup; + children = ( + AC42D742163638C7002FD7C6 /* SHKTencentWeibo.h */, + AC42D743163638C7002FD7C6 /* SHKTencentWeibo.m */, + AC42D744163638C7002FD7C6 /* TencentOAMutableURLRequest.h */, + AC42D746163638C7002FD7C6 /* TencentOAMutableURLRequest.m */, + AC42D747163638C7002FD7C6 /* TencentOAuthView.h */, + AC42D749163638C7002FD7C6 /* TencentOAuthView.m */, + ); + path = "Tencent Weibo"; + sourceTree = ""; + }; + AC67CE491643A46200C74ECE /* Tencent Weixin */ = { + isa = PBXGroup; + children = ( + AC67CE4A1643A46200C74ECE /* SDK */, + AC67CE551643A4C800C74ECE /* SHKTencentWeixin.h */, + AC67CE561643A4C800C74ECE /* SHKTencentWeixin.m */, + ); + path = "Tencent Weixin"; + sourceTree = ""; + }; + AC67CE4A1643A46200C74ECE /* SDK */ = { + isa = PBXGroup; + children = ( + AC67CE4C1643A46200C74ECE /* libWeChatSDK_armv7_armv7s.a */, + AC67CE4D1643A46200C74ECE /* WXApi.h */, + AC67CE4E1643A46200C74ECE /* WXApiObject.h */, + ); + path = SDK; + sourceTree = ""; + }; + AC91A95D163908E60055FEF6 /* SSO SDK */ = { + isa = PBXGroup; + children = ( + AC91A95E163908E60055FEF6 /* SinaWeibo.bundle */, + AC91A95F163908E60055FEF6 /* SinaWeibo.h */, + AC91A960163908E60055FEF6 /* SinaWeibo.m */, + AC91A961163908E60055FEF6 /* SinaWeiboAuthorizeView.h */, + AC91A962163908E60055FEF6 /* SinaWeiboAuthorizeView.m */, + AC91A963163908E60055FEF6 /* SinaWeiboConstants.h */, + AC91A964163908E60055FEF6 /* SinaWeiboRequest.h */, + AC91A965163908E60055FEF6 /* SinaWeiboRequest.m */, + ); + name = "SSO SDK"; + path = "Submodules/sinaweibo-ios-sdk/src/SinaWeibo"; + sourceTree = SOURCE_ROOT; + }; B7EFCD8914C6B966004910F1 /* Diigo */ = { isa = PBXGroup; children = ( @@ -2147,7 +2693,6 @@ 7ABCDBA91577528B003BBFFD /* SHKFormFieldCellSwitch.h in Headers */, 7ABCDBB0157757D1003BBFFD /* SHKFormFieldCellOptionPicker.h in Headers */, 7A4CAA171577BEFA0010E6B3 /* SHKFormFieldCell_PrivateProperties.h in Headers */, - 7A16F3B016134A790019645D /* SHKInstagram.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2445,6 +2990,139 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AC42D794163645CF002FD7C6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D795163645CF002FD7C6 /* Base64Transcoder.h in Headers */, + AC42D796163645CF002FD7C6 /* hmac.h in Headers */, + AC42D797163645CF002FD7C6 /* sha1.h in Headers */, + AC42D798163645CF002FD7C6 /* SHKFormFieldCellText.h in Headers */, + AC42D799163645CF002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */, + AC42D79A163645CF002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC42D79B163645CF002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7A5163645F2002FD7C6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7A6163645F2002FD7C6 /* Base64Transcoder.h in Headers */, + AC42D7A7163645F2002FD7C6 /* hmac.h in Headers */, + AC42D7A8163645F2002FD7C6 /* sha1.h in Headers */, + AC42D7A9163645F2002FD7C6 /* SHKFormFieldCellText.h in Headers */, + AC42D7AA163645F2002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */, + AC42D7AB163645F2002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC42D7AC163645F2002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7D116364633002FD7C6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7D216364633002FD7C6 /* Base64Transcoder.h in Headers */, + AC42D7D316364633002FD7C6 /* hmac.h in Headers */, + AC42D7D416364633002FD7C6 /* sha1.h in Headers */, + AC42D7D516364633002FD7C6 /* SHKFormFieldCellText.h in Headers */, + AC42D7D616364633002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */, + AC42D7D716364633002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC42D7D816364633002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7E316364656002FD7C6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7E416364656002FD7C6 /* Base64Transcoder.h in Headers */, + AC42D7E516364656002FD7C6 /* hmac.h in Headers */, + AC42D7E616364656002FD7C6 /* sha1.h in Headers */, + AC42D7E716364656002FD7C6 /* SHKFormFieldCellText.h in Headers */, + AC42D7E816364656002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */, + AC42D7E916364656002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC42D7EA16364656002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7F316364664002FD7C6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7F416364664002FD7C6 /* Base64Transcoder.h in Headers */, + AC42D7F516364664002FD7C6 /* hmac.h in Headers */, + AC42D7F616364664002FD7C6 /* sha1.h in Headers */, + AC42D7F716364664002FD7C6 /* SHKFormFieldCellText.h in Headers */, + AC42D7F816364664002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */, + AC42D7F916364664002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC42D7FA16364664002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + AC42D8A1163669F3002FD7C6 /* SHKiOS6SinaWeibo.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D8061636476A002FD7C6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D8071636476A002FD7C6 /* Base64Transcoder.h in Headers */, + AC42D8081636476A002FD7C6 /* hmac.h in Headers */, + AC42D8091636476A002FD7C6 /* sha1.h in Headers */, + AC42D80A1636476A002FD7C6 /* SHKFormFieldCellText.h in Headers */, + AC42D80B1636476A002FD7C6 /* SHKFormFieldCellSwitch.h in Headers */, + AC42D80C1636476A002FD7C6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC42D80D1636476A002FD7C6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC91A94F163908C00055FEF6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AC91A950163908C00055FEF6 /* Base64Transcoder.h in Headers */, + AC91A951163908C00055FEF6 /* hmac.h in Headers */, + AC91A952163908C00055FEF6 /* sha1.h in Headers */, + AC91A953163908C00055FEF6 /* SHKFormFieldCellText.h in Headers */, + AC91A954163908C00055FEF6 /* SHKFormFieldCellSwitch.h in Headers */, + AC91A955163908C00055FEF6 /* SHKFormFieldCellOptionPicker.h in Headers */, + AC91A956163908C00055FEF6 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + AC91A957163908C00055FEF6 /* SHKiOS6SinaWeibo.h in Headers */, + AC91A968163908E60055FEF6 /* SinaWeibo.h in Headers */, + AC91A96D163908E60055FEF6 /* SinaWeiboAuthorizeView.h in Headers */, + AC91A972163908E60055FEF6 /* SinaWeiboConstants.h in Headers */, + AC91A974163908E60055FEF6 /* SinaWeiboRequest.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ACF7F8051643B2B6002947F0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ACF7F8061643B2B6002947F0 /* Base64Transcoder.h in Headers */, + ACF7F8071643B2B6002947F0 /* hmac.h in Headers */, + ACF7F8081643B2B6002947F0 /* sha1.h in Headers */, + ACF7F8091643B2B6002947F0 /* SHKFormFieldCellText.h in Headers */, + ACF7F80A1643B2B6002947F0 /* SHKFormFieldCellSwitch.h in Headers */, + ACF7F80B1643B2B6002947F0 /* SHKFormFieldCellOptionPicker.h in Headers */, + ACF7F80C1643B2B6002947F0 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ACF7F80D1643B2B6002947F0 /* SHKiOS6SinaWeibo.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ACF7F8221643B45B002947F0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ACF7F8231643B45B002947F0 /* Base64Transcoder.h in Headers */, + ACF7F8241643B45B002947F0 /* hmac.h in Headers */, + ACF7F8251643B45B002947F0 /* sha1.h in Headers */, + ACF7F8261643B45B002947F0 /* SHKFormFieldCellText.h in Headers */, + ACF7F8271643B45B002947F0 /* SHKFormFieldCellSwitch.h in Headers */, + ACF7F8281643B45B002947F0 /* SHKFormFieldCellOptionPicker.h in Headers */, + ACF7F8291643B45B002947F0 /* SHKFormFieldCell_PrivateProperties.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -3045,61 +3723,214 @@ productReference = 7AEE043D160E1D5B00FEC06E /* libTumblr.a */; productType = "com.apple.product-type.library.static"; }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0430; - }; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ShareKit" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - en, - de, - ja, - nl, - vi, - zh_CN, - eu, - fr, - ko, + AC42D78F163645CF002FD7C6 /* Douban */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC42D79C163645CF002FD7C6 /* Build configuration list for PBXNativeTarget "Douban" */; + buildPhases = ( + AC42D790163645CF002FD7C6 /* Sources */, + AC42D793163645CF002FD7C6 /* Frameworks */, + AC42D794163645CF002FD7C6 /* Headers */, ); - mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 1D6058900D05DD3D006BFB54 /* Demo App */, - 7AB5342D1552AADD00171BCE /* Static Library */, - 7AB5360E1552E26800171BCE /* Resource Bundle */, - 7A0F91D1156BA2A0009CB40A /* Static Library Core */, - 7A1AFC47160E11810086B98A /* JSONKit */, - 7A1AFCB1160E11F90086B98A /* SSKeyChain */, - 7A16F36F161340DD0019645D /* OAuth */, - 7A1AFCC2160E123C0086B98A /* Reachability */, - 7AEE02F8160E1A3F00FEC06E /* Print */, - 7AEE0309160E1A6300FEC06E /* Logout */, - 7AEE031A160E1A8A00FEC06E /* Copy */, - 7AEE02CA160E188400FEC06E /* Email */, - 7AEE032B160E1ABC00FEC06E /* Open in Safari */, - 7AEE033C160E1AF400FEC06E /* Save to Album */, - 7AEE02DB160E18A700FEC06E /* Text Message */, - 7AEE034D160E1B3A00FEC06E /* Kippt */, - 7AEE035D160E1B3D00FEC06E /* Delicious */, - 7AEE037D160E1B4000FEC06E /* Readability */, - 7AEE036D160E1B3E00FEC06E /* Diigo */, - 7AEE038D160E1B4200FEC06E /* VKontakte */, - 7AEE03A3160E1C0600FEC06E /* Evernote */, - 7A1AFCD3160E127B0086B98A /* Evernote SDK */, - 7A1AFD3D160E14590086B98A /* Facebook */, - 7A1AFCFA160E131B0086B98A /* Facebook SDK */, + buildRules = ( + ); + dependencies = ( + ); + name = Douban; + productName = ShareKitLibrary; + productReference = AC42D79F163645CF002FD7C6 /* libDouban.a */; + productType = "com.apple.product-type.library.static"; + }; + AC42D7A1163645F2002FD7C6 /* Renren */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC42D7AD163645F2002FD7C6 /* Build configuration list for PBXNativeTarget "Renren" */; + buildPhases = ( + AC42D7A2163645F2002FD7C6 /* Sources */, + AC42D7A4163645F2002FD7C6 /* Frameworks */, + AC42D7A5163645F2002FD7C6 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Renren; + productName = ShareKitLibrary; + productReference = AC42D7B0163645F2002FD7C6 /* libRenren.a */; + productType = "com.apple.product-type.library.static"; + }; + AC42D7CD16364633002FD7C6 /* NetEase Weibo */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC42D7D916364633002FD7C6 /* Build configuration list for PBXNativeTarget "NetEase Weibo" */; + buildPhases = ( + AC42D7CE16364633002FD7C6 /* Sources */, + AC42D7D016364633002FD7C6 /* Frameworks */, + AC42D7D116364633002FD7C6 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "NetEase Weibo"; + productName = ShareKitLibrary; + productReference = AC42D7DC16364634002FD7C6 /* libNetEase Weibo.a */; + productType = "com.apple.product-type.library.static"; + }; + AC42D7DF16364656002FD7C6 /* Tencent Weibo */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC42D7EB16364656002FD7C6 /* Build configuration list for PBXNativeTarget "Tencent Weibo" */; + buildPhases = ( + AC42D7E016364656002FD7C6 /* Sources */, + AC42D7E216364656002FD7C6 /* Frameworks */, + AC42D7E316364656002FD7C6 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Tencent Weibo"; + productName = ShareKitLibrary; + productReference = AC42D7EE16364656002FD7C6 /* libTencent Weibo.a */; + productType = "com.apple.product-type.library.static"; + }; + AC42D7EF16364664002FD7C6 /* Sina Weibo */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC42D7FB16364664002FD7C6 /* Build configuration list for PBXNativeTarget "Sina Weibo" */; + buildPhases = ( + AC42D7F016364664002FD7C6 /* Sources */, + AC42D7F216364664002FD7C6 /* Frameworks */, + AC42D7F316364664002FD7C6 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Sina Weibo"; + productName = ShareKitLibrary; + productReference = AC42D7FE16364664002FD7C6 /* libSina Weibo.a */; + productType = "com.apple.product-type.library.static"; + }; + AC42D8021636476A002FD7C6 /* Renren SDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC42D80E1636476A002FD7C6 /* Build configuration list for PBXNativeTarget "Renren SDK" */; + buildPhases = ( + AC42D8031636476A002FD7C6 /* Sources */, + AC42D8051636476A002FD7C6 /* Frameworks */, + AC42D8061636476A002FD7C6 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Renren SDK"; + productName = ShareKitLibrary; + productReference = AC42D8111636476A002FD7C6 /* libRenren SDK.a */; + productType = "com.apple.product-type.library.static"; + }; + AC91A94A163908C00055FEF6 /* Sina Weibo SDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = AC91A958163908C00055FEF6 /* Build configuration list for PBXNativeTarget "Sina Weibo SDK" */; + buildPhases = ( + AC91A94B163908C00055FEF6 /* Sources */, + AC91A94E163908C00055FEF6 /* Frameworks */, + AC91A94F163908C00055FEF6 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Sina Weibo SDK"; + productName = ShareKitLibrary; + productReference = AC91A95B163908C00055FEF6 /* libSina Weibo SDK.a */; + productType = "com.apple.product-type.library.static"; + }; + ACF7F7FF1643B2B6002947F0 /* Tencent Weixin SDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = ACF7F8121643B2B6002947F0 /* Build configuration list for PBXNativeTarget "Tencent Weixin SDK" */; + buildPhases = ( + ACF7F8001643B2B6002947F0 /* Sources */, + ACF7F8041643B2B6002947F0 /* Frameworks */, + ACF7F8051643B2B6002947F0 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Tencent Weixin SDK"; + productName = ShareKitLibrary; + productReference = ACF7F8151643B2B6002947F0 /* libTencent Weixin SDK.a */; + productType = "com.apple.product-type.library.static"; + }; + ACF7F81C1643B45B002947F0 /* Tencent Weixin */ = { + isa = PBXNativeTarget; + buildConfigurationList = ACF7F82A1643B45B002947F0 /* Build configuration list for PBXNativeTarget "Tencent Weixin" */; + buildPhases = ( + ACF7F81D1643B45B002947F0 /* Sources */, + ACF7F8211643B45B002947F0 /* Frameworks */, + ACF7F8221643B45B002947F0 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Tencent Weixin"; + productName = ShareKitLibrary; + productReference = ACF7F82D1643B45B002947F0 /* libTencent Weixin.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0430; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ShareKit" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + de, + ja, + nl, + vi, + zh_CN, + eu, + fr, + ko, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Demo App */, + 7AB5342D1552AADD00171BCE /* Static Library */, + 7AB5360E1552E26800171BCE /* Resource Bundle */, + 7A0F91D1156BA2A0009CB40A /* Static Library Core */, + 7A1AFC47160E11810086B98A /* JSONKit */, + 7A1AFCB1160E11F90086B98A /* SSKeyChain */, + 7A16F36F161340DD0019645D /* OAuth */, + 7A1AFCC2160E123C0086B98A /* Reachability */, + 7AEE02F8160E1A3F00FEC06E /* Print */, + 7AEE0309160E1A6300FEC06E /* Logout */, + 7AEE031A160E1A8A00FEC06E /* Copy */, + 7AEE02CA160E188400FEC06E /* Email */, + 7AEE032B160E1ABC00FEC06E /* Open in Safari */, + 7AEE033C160E1AF400FEC06E /* Save to Album */, + 7AEE02DB160E18A700FEC06E /* Text Message */, + 7AEE034D160E1B3A00FEC06E /* Kippt */, + 7AEE035D160E1B3D00FEC06E /* Delicious */, + 7AEE037D160E1B4000FEC06E /* Readability */, + 7AEE036D160E1B3E00FEC06E /* Diigo */, + 7AEE038D160E1B4200FEC06E /* VKontakte */, + 7AEE03A3160E1C0600FEC06E /* Evernote */, + 7A1AFCD3160E127B0086B98A /* Evernote SDK */, + 7A1AFD3D160E14590086B98A /* Facebook */, + 7A1AFCFA160E131B0086B98A /* Facebook SDK */, 7AEE03B3160E1C0800FEC06E /* FoursquareV2 */, 7AEE03C3160E1C0C00FEC06E /* Flickr */, 7A1AFD15160E13740086B98A /* Flickr SDK */, @@ -3111,6 +3942,15 @@ 7AEE041E160E1D5A00FEC06E /* Read It Later */, 7AEE042E160E1D5B00FEC06E /* Tumblr */, 7A1AFD2B160E14340086B98A /* Twitter */, + AC42D78F163645CF002FD7C6 /* Douban */, + AC42D7EF16364664002FD7C6 /* Sina Weibo */, + AC91A94A163908C00055FEF6 /* Sina Weibo SDK */, + AC42D7CD16364633002FD7C6 /* NetEase Weibo */, + AC42D7DF16364656002FD7C6 /* Tencent Weibo */, + ACF7F81C1643B45B002947F0 /* Tencent Weixin */, + ACF7F7FF1643B2B6002947F0 /* Tencent Weixin SDK */, + AC42D7A1163645F2002FD7C6 /* Renren */, + AC42D8021636476A002FD7C6 /* Renren SDK */, ); }; /* End PBXProject section */ @@ -3137,6 +3977,8 @@ 7A28824A1553CC6F007DC379 /* FBDialog.bundle in Resources */, 7A2882571553D7E1007DC379 /* SHKSharers.plist in Resources */, 7A2882581553FEE6007DC379 /* SHKEvernote.md in Resources */, + AC42D815163648AB002FD7C6 /* RRConnect.bundle in Resources */, + AC91A966163908E60055FEF6 /* SinaWeibo.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3330,6 +4172,42 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC42D8A316366F4F002FD7C6 /* SHKiOS6SinaWeibo.m in Sources */, + AC42D83C16364CA2002FD7C6 /* SHKNetEaseWeibo.m in Sources */, + AC42D83D16364CA2002FD7C6 /* SHKPlurk.m in Sources */, + AC42D83E16364CA2002FD7C6 /* ROError.m in Sources */, + AC42D83F16364CA2002FD7C6 /* Renren.m in Sources */, + AC42D84016364CA2002FD7C6 /* ROAlbumsInfoRequestParam.m in Sources */, + AC42D84116364CA2002FD7C6 /* ROCreateAlbumRequestParam.m in Sources */, + AC42D84216364CA2002FD7C6 /* ROGetFriendsInfoRequestParam.m in Sources */, + AC42D84316364CA2002FD7C6 /* ROGetFriendsRequestParam.m in Sources */, + AC42D84416364CA2002FD7C6 /* ROPasswordFlowRequestParam.m in Sources */, + AC42D84516364CA2002FD7C6 /* ROPublishPhotoRequestParam.m in Sources */, + AC42D84616364CA2002FD7C6 /* RORequestParam.m in Sources */, + AC42D84716364CA2002FD7C6 /* ROUserInfoRequestParam.m in Sources */, + AC42D84816364CA2002FD7C6 /* ROAlbumResponseltem.m in Sources */, + AC42D84916364CA2002FD7C6 /* ROCreateAlbumResponseItem.m in Sources */, + AC42D84A16364CA2002FD7C6 /* ROFriendResponseItem.m in Sources */, + AC42D84B16364CA2002FD7C6 /* ROPublishPhotoResponseItem.m in Sources */, + AC42D84C16364CA2002FD7C6 /* ROResponseItem.m in Sources */, + AC42D84D16364CA2002FD7C6 /* ROUserResponseItem.m in Sources */, + AC42D84E16364CA2002FD7C6 /* RODialog.m in Sources */, + AC42D84F16364CA2002FD7C6 /* RORequest.m in Sources */, + AC42D85016364CA2002FD7C6 /* ROResponse.m in Sources */, + AC42D85116364CA2002FD7C6 /* RODialogModel.m in Sources */, + AC42D85216364CA2002FD7C6 /* RODialogView.m in Sources */, + AC42D85316364CA2002FD7C6 /* ROPublishPhotoDialogModel.m in Sources */, + AC42D85416364CA2002FD7C6 /* ROPublishPhotoInternal.m in Sources */, + AC42D85516364CA2002FD7C6 /* ROUtility.m in Sources */, + AC42D85616364CA2002FD7C6 /* ROCloseButton.m in Sources */, + AC42D85716364CA2002FD7C6 /* ROGlobalStyle.m in Sources */, + AC42D85816364CA2002FD7C6 /* ROImageView.m in Sources */, + AC42D85916364CA2002FD7C6 /* SHKRenRen.m in Sources */, + AC42D85A16364CA2002FD7C6 /* SHKSinaWeibo.m in Sources */, + AC42D85B16364CA2002FD7C6 /* SHKTencentWeibo.m in Sources */, + AC42D85C16364CA2002FD7C6 /* TencentOAMutableURLRequest.m in Sources */, + AC42D85D16364CA2002FD7C6 /* TencentOAuthView.m in Sources */, + AC42D83616364BBF002FD7C6 /* SHKDouban.m in Sources */, 7AB418E2160761AB002059FA /* SHKKippt.m in Sources */, 7AB534B11552BE7D00171BCE /* SHKCustomFormFieldCell.m in Sources */, 7AB534B31552BE7D00171BCE /* SHKCustomFormControllerLargeTextField.m in Sources */, @@ -3372,20 +4250,6 @@ 7AB5350A1552BE7D00171BCE /* SHKDiigo.m in Sources */, 7AB5350B1552BE7D00171BCE /* SHKVkontakteOAuthView.m in Sources */, 7AB5350D1552BE7D00171BCE /* SHKVkontakte.m in Sources */, - 7AB535101552BE7D00171BCE /* (null) in Sources */, - 7AB535121552BE7D00171BCE /* (null) in Sources */, - 7AB535141552BE7D00171BCE /* (null) in Sources */, - 7AB535161552BE7D00171BCE /* (null) in Sources */, - 7AB535181552BE7D00171BCE /* (null) in Sources */, - 7AB5351A1552BE7D00171BCE /* (null) in Sources */, - 7AB5351D1552BE7D00171BCE /* (null) in Sources */, - 7AB535201552BE7D00171BCE /* (null) in Sources */, - 7AB535221552BE7D00171BCE /* (null) in Sources */, - 7AB535241552BE7D00171BCE /* (null) in Sources */, - 7AB535281552BE7D00171BCE /* (null) in Sources */, - 7AB5352A1552BE7D00171BCE /* (null) in Sources */, - 7AB5352D1552BE7D00171BCE /* (null) in Sources */, - 7AB5352F1552BE7D00171BCE /* (null) in Sources */, 7AB535311552BE7D00171BCE /* SHKEvernote.m in Sources */, 7AB535351552BE7D00171BCE /* NSObject+SBJSON.m in Sources */, 7AB535371552BE7D00171BCE /* NSString+SBJSON.m in Sources */, @@ -3463,6 +4327,10 @@ 7AB8050F15AC7AAF004FB430 /* ENOAuthViewController.m in Sources */, 7AB8051015AC7BC9004FB430 /* GTMNSString+HTML.m in Sources */, 7A16F3B216134A790019645D /* SHKInstagram.m in Sources */, + AC91A969163908E60055FEF6 /* SinaWeibo.m in Sources */, + AC91A96E163908E60055FEF6 /* SinaWeiboAuthorizeView.m in Sources */, + AC91A975163908E60055FEF6 /* SinaWeiboRequest.m in Sources */, + AC67CE581643A4C800C74ECE /* SHKTencentWeixin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3648,6 +4516,110 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AC42D790163645CF002FD7C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7A0163645E8002FD7C6 /* SHKDouban.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7A2163645F2002FD7C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7CC16364628002FD7C6 /* SHKRenRen.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7CE16364633002FD7C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D7DE1636464E002FD7C6 /* SHKNetEaseWeibo.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7E016364656002FD7C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D85E16364CC5002FD7C6 /* TencentOAMutableURLRequest.m in Sources */, + AC42D85F16364CC5002FD7C6 /* TencentOAuthView.m in Sources */, + AC42D7FF16364688002FD7C6 /* SHKTencentWeibo.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D7F016364664002FD7C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D80016364691002FD7C6 /* SHKSinaWeibo.m in Sources */, + AC42D8A2163669F3002FD7C6 /* SHKiOS6SinaWeibo.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC42D8031636476A002FD7C6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC42D816163648E0002FD7C6 /* ROError.m in Sources */, + AC42D817163648E0002FD7C6 /* Renren.m in Sources */, + AC42D818163648E0002FD7C6 /* ROAlbumsInfoRequestParam.m in Sources */, + AC42D819163648E0002FD7C6 /* ROCreateAlbumRequestParam.m in Sources */, + AC42D81A163648E0002FD7C6 /* ROGetFriendsInfoRequestParam.m in Sources */, + AC42D81B163648E0002FD7C6 /* ROGetFriendsRequestParam.m in Sources */, + AC42D81C163648E0002FD7C6 /* ROPasswordFlowRequestParam.m in Sources */, + AC42D81D163648E0002FD7C6 /* ROPublishPhotoRequestParam.m in Sources */, + AC42D81E163648E0002FD7C6 /* RORequestParam.m in Sources */, + AC42D81F163648E0002FD7C6 /* ROUserInfoRequestParam.m in Sources */, + AC42D820163648E0002FD7C6 /* ROAlbumResponseltem.m in Sources */, + AC42D821163648E0002FD7C6 /* ROCreateAlbumResponseItem.m in Sources */, + AC42D822163648E0002FD7C6 /* ROFriendResponseItem.m in Sources */, + AC42D823163648E0002FD7C6 /* ROPublishPhotoResponseItem.m in Sources */, + AC42D824163648E0002FD7C6 /* ROResponseItem.m in Sources */, + AC42D825163648E0002FD7C6 /* ROUserResponseItem.m in Sources */, + AC42D826163648E0002FD7C6 /* RODialog.m in Sources */, + AC42D827163648E0002FD7C6 /* RORequest.m in Sources */, + AC42D828163648E0002FD7C6 /* ROResponse.m in Sources */, + AC42D829163648E0002FD7C6 /* RODialogModel.m in Sources */, + AC42D82A163648E0002FD7C6 /* RODialogView.m in Sources */, + AC42D82B163648E0002FD7C6 /* ROPublishPhotoDialogModel.m in Sources */, + AC42D82C163648E0002FD7C6 /* ROPublishPhotoInternal.m in Sources */, + AC42D82D163648E0002FD7C6 /* ROUtility.m in Sources */, + AC42D82E163648E0002FD7C6 /* ROCloseButton.m in Sources */, + AC42D82F163648E0002FD7C6 /* ROGlobalStyle.m in Sources */, + AC42D830163648E0002FD7C6 /* ROImageView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AC91A94B163908C00055FEF6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC91A96B163908E60055FEF6 /* SinaWeibo.m in Sources */, + AC91A970163908E60055FEF6 /* SinaWeiboAuthorizeView.m in Sources */, + AC91A977163908E60055FEF6 /* SinaWeiboRequest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ACF7F8001643B2B6002947F0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ACF7F82F1643B497002947F0 /* WXApi.h in Sources */, + ACF7F8301643B497002947F0 /* WXApiObject.h in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ACF7F81D1643B45B002947F0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ACF7F82E1643B48E002947F0 /* SHKTencentWeixin.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -3680,6 +4652,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = NO; INFOPLIST_FILE = "ShareKit-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 4.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK\"", + ); OTHER_LDFLAGS = ( "-ObjC", "-all_load", @@ -3705,6 +4681,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = NO; INFOPLIST_FILE = "ShareKit-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 4.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK\"", + ); OTHER_LDFLAGS = ( "-ObjC", "-all_load", @@ -4401,6 +5381,10 @@ GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_UNINITIALIZED_AUTOS = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK\"", + ); OTHER_LDFLAGS = ( "-ObjC", "-all_load", @@ -4427,6 +5411,10 @@ GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_UNINITIALIZED_AUTOS = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK\"", + ); OTHER_LDFLAGS = ( "-ObjC", "-all_load", @@ -5756,45 +6744,593 @@ }; name = Release; }; - C01FCF4F08A954540054247B /* Debug */ = { + AC42D79D163645CF002FD7C6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = ( armv6, - armv7, + "$(ARCHS_STANDARD_32_BIT)", ); - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_C_LANGUAGE_STANDARD = c99; + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_THUMB_SUPPORT = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.0; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = Douban; + SKIP_INSTALL = YES; }; name = Debug; }; - C01FCF5008A954540054247B /* Release */ = { + AC42D79E163645CF002FD7C6 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = ( armv6, - armv7, + "$(ARCHS_STANDARD_32_BIT)", ); - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_C_LANGUAGE_STANDARD = c99; + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; GCC_THUMB_SUPPORT = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.0; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = Douban; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AC42D7AE163645F2002FD7C6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = Renren; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + AC42D7AF163645F2002FD7C6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = Renren; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AC42D7DA16364633002FD7C6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "NetEase Weibo"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + AC42D7DB16364633002FD7C6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "NetEase Weibo"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AC42D7EC16364656002FD7C6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Tencent Weibo"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + AC42D7ED16364656002FD7C6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Tencent Weibo"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AC42D7FC16364664002FD7C6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Sina Weibo"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + AC42D7FD16364664002FD7C6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Sina Weibo"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AC42D80F1636476A002FD7C6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Renren SDK"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + AC42D8101636476A002FD7C6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Renren SDK"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AC91A959163908C00055FEF6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Sina Weibo SDK"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + AC91A95A163908C00055FEF6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Sina Weibo SDK"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + ACF7F8131643B2B6002947F0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Tencent Weixin SDK"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + ACF7F8141643B2B6002947F0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/ShareKit/Sharers/Services/Tencent Weixin/SDK\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Tencent Weixin SDK"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + ACF7F82B1643B45B002947F0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Tencent Weixin"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + ACF7F82C1643B45B002947F0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + armv6, + "$(ARCHS_STANDARD_32_BIT)", + ); + COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ShareKitLibrary.dst; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ShareKitLibrary/ShareKitLibrary-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_NAME = "Tencent Weixin"; + SKIP_INSTALL = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + armv6, + armv7, + ); + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + armv6, + armv7, + ); + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + /* Begin XCConfigurationList section */ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Demo App" */ = { isa = XCConfigurationList; @@ -6111,6 +7647,87 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + AC42D79C163645CF002FD7C6 /* Build configuration list for PBXNativeTarget "Douban" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC42D79D163645CF002FD7C6 /* Debug */, + AC42D79E163645CF002FD7C6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC42D7AD163645F2002FD7C6 /* Build configuration list for PBXNativeTarget "Renren" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC42D7AE163645F2002FD7C6 /* Debug */, + AC42D7AF163645F2002FD7C6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC42D7D916364633002FD7C6 /* Build configuration list for PBXNativeTarget "NetEase Weibo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC42D7DA16364633002FD7C6 /* Debug */, + AC42D7DB16364633002FD7C6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC42D7EB16364656002FD7C6 /* Build configuration list for PBXNativeTarget "Tencent Weibo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC42D7EC16364656002FD7C6 /* Debug */, + AC42D7ED16364656002FD7C6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC42D7FB16364664002FD7C6 /* Build configuration list for PBXNativeTarget "Sina Weibo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC42D7FC16364664002FD7C6 /* Debug */, + AC42D7FD16364664002FD7C6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC42D80E1636476A002FD7C6 /* Build configuration list for PBXNativeTarget "Renren SDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC42D80F1636476A002FD7C6 /* Debug */, + AC42D8101636476A002FD7C6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AC91A958163908C00055FEF6 /* Build configuration list for PBXNativeTarget "Sina Weibo SDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AC91A959163908C00055FEF6 /* Debug */, + AC91A95A163908C00055FEF6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ACF7F8121643B2B6002947F0 /* Build configuration list for PBXNativeTarget "Tencent Weixin SDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ACF7F8131643B2B6002947F0 /* Debug */, + ACF7F8141643B2B6002947F0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ACF7F82A1643B45B002947F0 /* Build configuration list for PBXNativeTarget "Tencent Weixin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ACF7F82B1643B45B002947F0 /* Debug */, + ACF7F82C1643B45B002947F0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ShareKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Submodules/JSONKit b/Submodules/JSONKit index 82157634c..02b983fa8 160000 --- a/Submodules/JSONKit +++ b/Submodules/JSONKit @@ -1 +1 @@ -Subproject commit 82157634ca0ca5b6a4a67a194dd11f15d9b72835 +Subproject commit 02b983fa8f26521e47dc1d49e3a47ed062e20058 diff --git a/Submodules/evernote-ios-sdk b/Submodules/evernote-ios-sdk index 391ca643c..acc868d6c 160000 --- a/Submodules/evernote-ios-sdk +++ b/Submodules/evernote-ios-sdk @@ -1 +1 @@ -Subproject commit 391ca643c5b1cd02e9fa869a6b0760436ea452ed +Subproject commit acc868d6cddf35262632c9ac6fb4d50a0fce0778 diff --git a/Submodules/facebook-ios-sdk b/Submodules/facebook-ios-sdk index ada467f75..397c0b62b 160000 --- a/Submodules/facebook-ios-sdk +++ b/Submodules/facebook-ios-sdk @@ -1 +1 @@ -Subproject commit ada467f754febd4f2871d15943e9be16b323f114 +Subproject commit 397c0b62b116a9680035e87a07ab936e1c5dfce6 diff --git a/Submodules/objectiveflickr b/Submodules/objectiveflickr index f474a78c8..e6df2db06 160000 --- a/Submodules/objectiveflickr +++ b/Submodules/objectiveflickr @@ -1 +1 @@ -Subproject commit f474a78c807b5fa0c887bf8efaead5be1da637ec +Subproject commit e6df2db06c1401b7a1777ac37a26a87affc019a6 diff --git a/Submodules/sinaweibo-ios-sdk b/Submodules/sinaweibo-ios-sdk new file mode 160000 index 000000000..1dae02662 --- /dev/null +++ b/Submodules/sinaweibo-ios-sdk @@ -0,0 +1 @@ +Subproject commit 1dae02662e46bb2b041fce7cfe5241f90ef73d59 diff --git a/Submodules/sskeychain b/Submodules/sskeychain index 8252a69cd..e8f45d75c 160000 --- a/Submodules/sskeychain +++ b/Submodules/sskeychain @@ -1 +1 @@ -Subproject commit 8252a69cdfea562223d4dc2e2ccaf01b752d2cc6 +Subproject commit e8f45d75c87fa8e56e04c62c81f7ad1e45a2cabb