From 22b94919b1f787ebdafca9873e15f9761367769e Mon Sep 17 00:00:00 2001 From: Jim Spoto Date: Wed, 13 Jul 2011 19:11:50 -0400 Subject: [PATCH] ShareKit LinkedIn Integration, first version (release pass) --- Classes/Example/ExampleShareImage.m | 2 +- Classes/Example/ExampleShareLink.m | 6 +- .../Core/Base Sharer Classes/SHKOAuthSharer.h | 2 + .../Core/Base Sharer Classes/SHKOAuthSharer.m | 8 +- .../Core/Helpers/OAuth/OAMutableURLRequest.h | 3 + .../Core/Helpers/OAuth/OAMutableURLRequest.m | 115 ++-- Classes/ShareKit/Core/SHK.m | 7 + Classes/ShareKit/Core/SHKSharers.plist | 3 +- Classes/ShareKit/SHKConfig.h | 48 +- .../LinkedIn/Categories/SHKItem+KVC.h | 39 ++ .../LinkedIn/Categories/SHKItem+KVC.m | 95 +++ .../LinkedIn/Categories/UIWebView+SHKPlus.h | 40 ++ .../LinkedIn/Categories/UIWebView+SHKPlus.m | 57 ++ .../Sharers/Services/LinkedIn/SHKLinkedIn.h | 44 ++ .../Sharers/Services/LinkedIn/SHKLinkedIn.m | 550 ++++++++++++++++++ .../Services/LinkedIn/UI/SHKLinkedInField.h | 95 +++ .../Services/LinkedIn/UI/SHKLinkedInField.m | 194 ++++++ .../Services/LinkedIn/UI/SHKLinkedInForm.h | 67 +++ .../Services/LinkedIn/UI/SHKLinkedInForm.m | 408 +++++++++++++ .../LinkedIn/UI/SHKLinkedInFormStyle.h | 53 ++ .../LinkedIn/UI/SHKLinkedInFormStyle.m | 76 +++ .../UI/SHKLinkedInMultilineTextField.h | 58 ++ .../UI/SHKLinkedInMultilineTextField.m | 420 +++++++++++++ .../LinkedIn/UI/SHKLinkedInTextField.h | 51 ++ .../LinkedIn/UI/SHKLinkedInTextField.m | 186 ++++++ .../LinkedIn/UI/SHKLinkedInURLField.h | 37 ++ .../LinkedIn/UI/SHKLinkedInURLField.m | 62 ++ RootViewController.xib | 19 +- ShareKit.xcodeproj/project.pbxproj | 107 +++- 29 files changed, 2752 insertions(+), 100 deletions(-) create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.m create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.h create mode 100644 Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.m diff --git a/Classes/Example/ExampleShareImage.m b/Classes/Example/ExampleShareImage.m index e7031f0f..653003ad 100644 --- a/Classes/Example/ExampleShareImage.m +++ b/Classes/Example/ExampleShareImage.m @@ -41,7 +41,7 @@ - (void)dealloc - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { self.toolbarItems = [NSArray arrayWithObjects: [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease], diff --git a/Classes/Example/ExampleShareLink.m b/Classes/Example/ExampleShareLink.m index 308de462..9ef6a680 100644 --- a/Classes/Example/ExampleShareLink.m +++ b/Classes/Example/ExampleShareLink.m @@ -27,6 +27,7 @@ #import "ExampleShareLink.h" #import "SHK.h" +#import "UIWebView+SHKPlus.h" @implementation ExampleShareLink @@ -40,7 +41,7 @@ - (void)dealloc - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { self.toolbarItems = [NSArray arrayWithObjects: [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease], @@ -56,6 +57,9 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil - (void)share { SHKItem *item = [SHKItem URL:webView.request.URL title:[webView pageTitle]]; + + [item setCustomValue:[webView pageDescription] forKey:@"linkDescription"]; + SHKActionSheet *actionSheet = [SHKActionSheet actionSheetForItem:item]; [actionSheet showFromToolbar:self.navigationController.toolbar]; } diff --git a/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.h b/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.h index 9bcfec55..fa85447e 100644 --- a/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.h +++ b/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.h @@ -35,6 +35,7 @@ NSString *consumerKey; NSString *secretKey; NSURL *authorizeCallbackURL; + NSString *realm; NSURL *authorizeURL; NSURL *accessURL; @@ -52,6 +53,7 @@ @property (nonatomic, retain) NSString *consumerKey; @property (nonatomic, retain) NSString *secretKey; @property (nonatomic, retain) NSURL *authorizeCallbackURL; +@property (nonatomic, retain) NSString *realm; @property (nonatomic, retain) NSURL *authorizeURL; @property (nonatomic, retain) NSURL *accessURL; diff --git a/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m b/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m index e2edf057..44067976 100644 --- a/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m +++ b/Classes/ShareKit/Core/Base Sharer Classes/SHKOAuthSharer.m @@ -32,7 +32,7 @@ @implementation SHKOAuthSharer -@synthesize consumerKey, secretKey, authorizeCallbackURL; +@synthesize consumerKey, secretKey, authorizeCallbackURL, realm; @synthesize authorizeURL, requestURL, accessURL; @synthesize consumer, requestToken, accessToken; @synthesize signatureProvider; @@ -44,6 +44,8 @@ - (void)dealloc [consumerKey release]; [secretKey release]; [authorizeCallbackURL release]; + self.realm = nil; + [authorizeURL release]; [requestURL release]; [accessURL release]; @@ -81,7 +83,7 @@ - (void)tokenRequest OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:requestURL consumer:consumer token:nil // we don't have a Token yet - realm:nil // our service provider doesn't specify a realm + realm:self.realm // our service provider doesn't specify a realm signatureProvider:signatureProvider]; @@ -189,7 +191,7 @@ - (void)tokenAccess:(BOOL)refresh OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:accessURL consumer:consumer token:(refresh ? accessToken : requestToken) - realm:nil // our service provider doesn't specify a realm + realm:self.realm // our service provider doesn't specify a realm signatureProvider:signatureProvider]; // use the default method, HMAC-SHA1 [oRequest setHTTPMethod:@"POST"]; diff --git a/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.h b/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.h index 03c6cfac..bcd247e4 100755 --- a/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.h +++ b/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.h @@ -38,6 +38,7 @@ OAConsumer *consumer; OAToken *token; NSString *realm; + NSString *callback; NSString *signature; id signatureProvider; NSString *nonce; @@ -48,6 +49,8 @@ @property(readonly) NSString *signature; @property(readonly) NSString *nonce; +@property(nonatomic, retain) NSString *callback; + - (id)initWithURL:(NSURL *)aUrl consumer:(OAConsumer *)aConsumer token:(OAToken *)aToken diff --git a/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m b/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m index f5d48204..a8387662 100755 --- a/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m +++ b/Classes/ShareKit/Core/Helpers/OAuth/OAMutableURLRequest.m @@ -36,7 +36,7 @@ - (NSString *)_signatureBaseString; @implementation OAMutableURLRequest @synthesize signature, nonce; - +@synthesize callback; #pragma mark init - (id)initWithURL:(NSURL *)aUrl @@ -45,35 +45,8 @@ - (id)initWithURL:(NSURL *)aUrl realm:(NSString *)aRealm signatureProvider:(id)aProvider { - if (self = [super initWithURL:aUrl - cachePolicy:NSURLRequestReloadIgnoringCacheData - timeoutInterval:10.0]) - { - consumer = [aConsumer retain]; - - // empty token for Unauthorized Request Token transaction - if (aToken == nil) - token = [[OAToken alloc] init]; - else - token = [aToken retain]; - - if (aRealm == nil) - realm = [[NSString alloc] initWithString:@""]; - else - realm = [aRealm retain]; - - // default to HMAC-SHA1 - if (aProvider == nil) - signatureProvider = [[OAHMAC_SHA1SignatureProvider alloc] init]; - else - signatureProvider = [aProvider retain]; - - [self _generateTimestamp]; - [self _generateNonce]; - - didPrepare = NO; - } - return self; + + return [self initWithURL:aUrl consumer:aConsumer token:aToken realm:aRealm signatureProvider:aProvider nonce:nil timestamp:nil]; } // Setting a timestamp and nonce to known @@ -86,9 +59,9 @@ - (id)initWithURL:(NSURL *)aUrl nonce:(NSString *)aNonce timestamp:(NSString *)aTimestamp { - if (self = [super initWithURL:aUrl + if ((self = [super initWithURL:aUrl cachePolicy:NSURLRequestReloadIgnoringCacheData - timeoutInterval:10.0]) + timeoutInterval:10.0])) { consumer = [aConsumer retain]; @@ -103,14 +76,25 @@ - (id)initWithURL:(NSURL *)aUrl else realm = [aRealm retain]; + + self.callback = nil; + // default to HMAC-SHA1 if (aProvider == nil) signatureProvider = [[OAHMAC_SHA1SignatureProvider alloc] init]; else signatureProvider = [aProvider retain]; - timestamp = [aTimestamp retain]; - nonce = [aNonce retain]; + + if(timestamp) + timestamp = [aTimestamp retain]; + else + [self _generateTimestamp]; + + if(nonce) + nonce = [aNonce retain]; + else + [self _generateNonce]; didPrepare = NO; } @@ -121,6 +105,9 @@ - (void)dealloc { [consumer release]; [token release]; + + self.callback = nil; + [realm release]; [signatureProvider release]; [timestamp release]; @@ -148,43 +135,54 @@ - (void)prepare if (didPrepare) { return; } + didPrepare = YES; - // sign + + // 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]]]; // set OAuth headers - NSString *oauthToken; - if ([token.key isEqualToString:@""]) - oauthToken = @""; // not used on Request Token transactions - else - oauthToken = [NSString stringWithFormat:@"oauth_token=\"%@\", ", [token.key URLEncodedString]]; + NSString *oauthToken = nil; + if (!([token.key isEqualToString:@""])) + oauthToken = [NSString stringWithFormat:@"oauth_token=\"%@\"", [token.key URLEncodedString]]; NSMutableString *extraParameters = [NSMutableString string]; - // Adding the optional parameters in sorted order isn't required by the OAuth spec, but it makes it possible to hard-code expected values in the unit tests. + // Adding the optional parameters in sorted order isn't required by the OAuth spec, but it makes it possible to hard-code expected values in the unit tests for(NSString *parameterName in [[extraOAuthParameters allKeys] sortedArrayUsingSelector:@selector(compare:)]) { - [extraParameters appendFormat:@", %@=\"%@\"", - [parameterName URLEncodedString], - [[extraOAuthParameters objectForKey:parameterName] URLEncodedString]]; + [extraParameters appendFormat:@", %@=\"%@\"", [parameterName URLEncodedString], [[extraOAuthParameters objectForKey:parameterName] URLEncodedString] ]; } + + NSMutableArray *parameters = [NSMutableArray array]; + + [parameters addObject:[NSString stringWithFormat:@"realm=\"%@\"", [realm URLEncodedString]]]; - NSString *oauthHeader = [NSString stringWithFormat:@"OAuth realm=\"%@\", oauth_consumer_key=\"%@\", %@oauth_signature_method=\"%@\", oauth_signature=\"%@\", oauth_timestamp=\"%@\", oauth_nonce=\"%@\", oauth_version=\"1.0\"%@", - [realm URLEncodedString], - [consumer.key URLEncodedString], - oauthToken, - [[signatureProvider name] URLEncodedString], - [signature URLEncodedString], - timestamp, - nonce, - extraParameters]; - + if ([callback length] > 0) + [parameters addObject:[NSString stringWithFormat:@"oauth_callback=\"%@\"", [callback URLEncodedString]]]; + + if(oauthToken) + [parameters addObject:oauthToken]; + + [parameters addObject:[NSString stringWithFormat:@"oauth_consumer_key=\"%@\"", [consumer.key URLEncodedString]]]; + + [parameters addObject:[NSString stringWithFormat:@"oauth_signature_method=\"%@\"", [[signatureProvider name] URLEncodedString]]]; + [parameters addObject:[NSString stringWithFormat:@"oauth_signature=\"%@\"", [signature URLEncodedString]]]; + [parameters addObject:[NSString stringWithFormat:@"oauth_timestamp=\"%@\"", timestamp]]; + [parameters addObject:[NSString stringWithFormat:@"oauth_nonce=\"%@\"", nonce]]; + [parameters addObject:@"oauth_version=\"1.0\""]; + + NSString *oauthHeader = [NSString stringWithFormat:@"OAuth %@%@", [parameters componentsJoinedByString:@", "], extraParameters]; [self setValue:oauthHeader forHTTPHeaderField:@"Authorization"]; + + SHKLog(@"Auth Header: %@", oauthHeader); + } #pragma mark - @@ -201,7 +199,6 @@ - (void)_generateNonce CFStringRef string = CFUUIDCreateString(NULL, theUUID); NSMakeCollectable(theUUID); nonce = (NSString *)string; - CFRelease(theUUID); } - (NSString *)_signatureBaseString @@ -216,6 +213,12 @@ - (NSString *)_signatureBaseString [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_nonce" value:nonce] URLEncodedNameValuePair]]; [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_version" value:@"1.0"] URLEncodedNameValuePair]]; + + if ([callback length] > 0) + { + [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_callback" value:callback] URLEncodedNameValuePair]]; + } + if (![token.key isEqualToString:@""]) { [parameterPairs addObject:[[OARequestParameter requestParameterWithName:@"oauth_token" value:token.key] URLEncodedNameValuePair]]; } @@ -240,7 +243,7 @@ - (NSString *)_signatureBaseString [[[self URL] URLStringWithoutQuery] URLEncodedString], [normalizedRequestParameters URLEncodedString]]; - SHKLog(@"OAMutableURLRequest parameters %@", normalizedRequestParameters); + SHKLog(@"OAMutableURLRequest Parameter Pairs: %@", normalizedRequestParameters); return ret; } diff --git a/Classes/ShareKit/Core/SHK.m b/Classes/ShareKit/Core/SHK.m index 7521b2a8..d5a64b9d 100644 --- a/Classes/ShareKit/Core/SHK.m +++ b/Classes/ShareKit/Core/SHK.m @@ -158,6 +158,13 @@ - (void)showViewController:(UIViewController *)vc vc.modalTransitionStyle = [SHK modalTransitionStyle]; [topViewController presentModalViewController:vc animated:YES]; + +///// This is where you'd resize any view presented by the Sharer (JRS) +// The view size is determined by the modal view controller settings (and device) +// +// vc.view.superview.frame = CGRectMake(0, 0, 300, 300);//it's important to do this after presentModalViewController +// vc.view.superview.center = topViewController.view.center; + [(UINavigationController *)vc navigationBar].barStyle = [(UINavigationController *)vc toolbar].barStyle = [SHK barStyle]; self.currentView = vc; diff --git a/Classes/ShareKit/Core/SHKSharers.plist b/Classes/ShareKit/Core/SHKSharers.plist index db686302..a2987b9d 100644 --- a/Classes/ShareKit/Core/SHKSharers.plist +++ b/Classes/ShareKit/Core/SHKSharers.plist @@ -12,7 +12,6 @@ services - SHKEvernote SHKTwitter SHKPinboard SHKDelicious @@ -21,6 +20,8 @@ SHKReadItLater SHKInstapaper SHKTumblr + SHKLinkedIn + SHKEvernote diff --git a/Classes/ShareKit/SHKConfig.h b/Classes/ShareKit/SHKConfig.h index c2aa3565..39a91781 100644 --- a/Classes/ShareKit/SHKConfig.h +++ b/Classes/ShareKit/SHKConfig.h @@ -1,16 +1,11 @@ - - // PLEASE SEE INSTALL/CONFIG INSTRUCTIONS: // http://getsharekit.com/install - - - // App Description // These values are used by any service that shows 'shared from XYZ' @@ -37,6 +32,13 @@ */ +// LinkedIn - http://developer.linkedin.com/ +// Please note that LinkedIn does enforce application throttling limits, +// Developer Login (app/secret keys) https://www.linkedin.com/secure/developer +// +#define SHKLinkedInConsumerKey @"" +#define SHKLinkedInSecretKey @"" + // Delicious - https://developer.apps.yahoo.com/projects #define SHKDeliciousConsumerKey @"" @@ -79,14 +81,20 @@ #define SHKBitLyLogin @"" #define SHKBitLyKey @"" + +// Evernote +#define SHKEvernoteConsumerKey @"" +#define SHKEvernoteSecretKey @"" +#define SHKEvernoteUserStoreURL @"" +#define SHKEvernoteNetStoreURLBase @"" + + // ShareMenu Ordering #define SHKShareMenuAlphabeticalOrder 1 // Setting this to 1 will show list in Alphabetical Order, setting to 0 will follow the order in SHKShares.plist // Append 'Shared With 'Signature to Email (and related forms) #define SHKSharedWithSignature 0 - - /* UI Configuration : Basic ------ @@ -130,23 +138,21 @@ /* Debugging ------ - To show debug output in the console: - 1. uncomment section A below - 2. comment out section B below - - To hide debug output in the console: - 1. uncomment section B below - 2. comment out section A below - */ + To show debug output in the console, setSHKDebugShowLogs to TRUE -// A : show debug output -//#define SHKDebugShowLogs 1 -//#define SHKLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] ) + The #if block that follows should be left alone unless modifying the behavior of enabling/disabling SHKLog -// B : hide debug output -#define SHKDebugShowLogs 0 -#define SHKLog( s, ... ) +*/ + +#define SHKDebugShowLogs (TRUE) +/////////////////////////////////////////// +#if(SHKDebugShowLogs) +#define SHKLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] ) +#else +#define SHKLog( s, ... ) +#endif +/////////////////////////////////////////// /* diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.h b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.h new file mode 100644 index 00000000..5174a40e --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.h @@ -0,0 +1,39 @@ +// +// SHKItem+KVC.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKItem.h" + +@interface SHKItem (KVC) + + +- (id)propertyForKey:(NSString*)key; +- (void)setProperty:(id)property forKey:(NSString*)key; + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.m b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.m new file mode 100644 index 00000000..965f2a11 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/SHKItem+KVC.m @@ -0,0 +1,95 @@ +// +// SHKItem+KVC.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKItem+KVC.h" + + +@interface SHKItem () +-(NSArray*)propertyList; +@end + + +@implementation SHKItem (KVC) + + +- (NSArray*)propertyList +{ + NSArray *array = [NSArray arrayWithObjects:@"text", @"tags", @"image", @"title", @"URL", @"data", @"mimeType", @"filename" , nil]; + return array; +} + + +- (BOOL)isProperty:(NSString*)key +{ + for(NSString *property in [self propertyList]) + { + if([property isEqualToString:key]) + return true; + } + + return false; + +} + + +- (id)propertyForKey:(NSString*)key +{ + if([self isProperty:key]) + return [self valueForKey:key]; + else + return [self customValueForKey:key]; +} + +- (void)setProperty:(id)property forKey:(NSString*)key +{ + + if([self isProperty:key]) + [self setValue:property forKey:key]; + else + [self setCustomValue:property forKey:key]; + +} + +/* +- (id)valueForUndefinedKey:(NSString *)key +{ + + return [self customValueForKey:key]; + +} + + +- (void)setValue:(id)value forUndefinedKey:(NSString *)key +{ + + [self setCustomValue:value forKey:key]; + +} +*/ + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.h b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.h new file mode 100644 index 00000000..135f3afc --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.h @@ -0,0 +1,40 @@ +// +// UIWebView+SHKPlus.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 + + +@interface UIWebView (SHKPlus) + +// Retrieves the title from the page loaded in a UIWebView +// Useful for providing a title when sharing URLs + +- (NSString *)pageDescription; + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.m b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.m new file mode 100644 index 00000000..cff06413 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/Categories/UIWebView+SHKPlus.m @@ -0,0 +1,57 @@ +// +// UIWebView+SHKPlus.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "UIWebView+SHKPlus.h" + +@implementation UIWebView (SHK) + + + + +- (NSString *)pageDescription +{ + NSString *fcn = @" function getMetaContents(mn){" + " var m = document.getElementsByTagName('meta');" + " for(var i in m){" + " if(m[i].name.toLowerCase() == mn.toLowerCase() ){" + " return m[i].content;" + " }" + " }" + " }" + + " getMetaContents('Description');"; + + NSString *ret = [self stringByEvaluatingJavaScriptFromString:fcn]; + + + return ret; +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.h b/Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.h new file mode 100644 index 00000000..6f48fef0 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.h @@ -0,0 +1,44 @@ +// +// SHKLinkedIn.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHK.h" +#import "SHKOAuthSharer.h" +#import "SHKLinkedInForm.h" + + +@interface SHKLinkedIn : SHKOAuthSharer { + + + +} + +- (void)showLinkedInForm; +- (void)sendForm:(SHKLinkedInForm *)form; + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.m b/Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.m new file mode 100644 index 00000000..6c2704e8 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/SHKLinkedIn.m @@ -0,0 +1,550 @@ +// +// SHKLinkedIn.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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. +// +// + +///////////////////////////////////////////////////////////////////////////////// +/* SHKLinkedIn (7/11/2011) Jim Spoto + + Some notes on getting this service up and running... + + Reference Code: http://lee.hdgreetings.com/2011/03/iphone-oauth.html + + * The project linked above has a working implementation of OAuth via LinkedIn, and was used + primarily as a point of reference. It appears to have a different flavor of OAuth which, + frustratingly, couldn't be integrated directly into ShareKit without what appeared to be + a substantial amount of work. + + + OAuth: OAMutableURLRequest modified to enable authorization via LinkedIn + + * Modifications/additions to better support realm / callback in the request + * An appropriate callback & verifier is necessary to avoid LinkedIn's OOB (pin) validation path + * Both the header and signature have to be created and assembled correctly. Some parameters + seem to require being in both, some not. Perhaps the OAuth spec can be reviewed to validate + this (http://oauth.net/core/1.0/) + + + UI: A new style UI class cluster has been created, based largely on the SHKTwitter source + + * The class cluster includes classes for form, form style, abstract field, and three specific + field types: text, URL, and multiline text + + * Discussion: The reason for going this route was the apparent incompatibility between the + way custom ShareKit forms are designed to work, and the way the SHKTwitter form works, in terms + of available UI functionality and composition of controls. LinkedIn includes support for very + long (700 characters) input fields, and UITextField controls are not usable for long input. The + SHKTwitter style control is, but does not support multiple multi-line input fields - something + again supported by LinkedIn share data. + + * Features: The UI classes support custom coloring via the style property of the form class, and + new field classes should be fairly simple to add by extending the SHKLinkedInForm class. + + * Implementation: The form is created using a custom UIScrollView class instead of a UITableView. + the primary reasons for this are the issues associated with embedding UITextView controls inside of + a UITableViewCell object. It may be desirable to rework SHK form code, to support dynamically + sized, multi-line cell classes, but there were enough caveats to avoid this on a first pass. + + For what it's worth, AddressBook appears to do this somehow, so it's possible (if you're Apple)... + + * "SHK Native UI: If this is desired, moving the core share functionality of SHKLinkedIn.m into + a vanilla custom share class should be straightforward + + + Categories: Created to experiment with some class methods, without modifying them + + SHKItem+KVC: Facilitates KVC methods on the Item, instead of using the methods to conver to an + NSDictionary, which would seem unnecessary (and acutally only supports string parms). Making + getting/setting item data more dynamic greatly improved the ease with which fields (and their + associated keys) can automatically sync with the share Item. + + UIWebView+SHKPlus: A bit of a toy, really. Javascript to get the Document meta tag from a web + page. Many social networking sites do something like this automatically when posting a link, and + since LinkedIn supports a link description, I used this data to auto-fill the Description field + by adding support in ExampleShareLink.m + + + + TDB / Incomplete Features: The important stuff I haven't yet gotten to.. + + Error Handling, Login/Auth Failure Handling is *incomplete*! Currently, virtually no error handling + exists based on LinkedIn's return data. Need to include authorization issues (and reauthentication loop) + as well as share/api return errors. + + + Known Issues / Bugs: + + * Twitter: Using the Example project, having issues when attempting to re-login after logging out with Twitter. + Not sure if the unmodified project has this issue (need to test). May have broken something with Twitter when + getting LinkedIn working (JRS) + + * Memory Leak: Occaisional leak sharing with LinkedIn using the Example project, when doing the following: + Authenticate, cancel out of share form, log out, authenticate again, cancel during share step, etc. At a glance, + the leak does not appear to be coming from any of the SHK classes directly (and may be in another thread related + to the URL connection). Need to test and compare to the unmodified (ie non-LinkedIn) project (JRS) + + + Reference: + + * Information on the LinkedIn API & OAuth + + LinkedIn Rest Doc. Home: http://developer.linkedin.com/community/apis + Share API: http://developer.linkedin.com/docs/DOC-1212# + Throttle Limits: http://developer.linkedin.com/docs/DOC-1112 + Common Issues: http://developer.linkedin.com/docs/DOC-1121 + + + + For more information and discussion, please see:https://github.com/jspoto/ShareKit + +*//////////////////////////////////////////////////////////////////////////////// + +#import "SHKLinkedIn.h" +#import "SHKLinkedInField.h" + +@implementation SHKLinkedIn + + +#pragma mark - +#pragma mark Configuration : Service Defination + +// Enter the name of the service ++ (NSString *)sharerTitle +{ + return @"LinkedIn"; +} + + +// What types of content can the action handle? + +// If the action can handle URLs, uncomment this section + ++ (BOOL)canShareURL +{ + return YES; +} + + +// If the action can handle images, uncomment this section +/* ++ (BOOL)canShareImage +{ + return YES; +} +*/ + +// If the action can handle text, uncomment this section + ++ (BOOL)canShareText +{ + return YES; +} + + +// If the action can handle files, uncomment this section +/* ++ (BOOL)canShareFile +{ + return YES; +} +*/ + + +// Does the service require a login? If for some reason it does NOT, uncomment this section: +/* ++ (BOOL)requiresAuthentication +{ + return NO; +} +*/ + + +#pragma mark - +#pragma mark Configuration : Dynamic Enable + +// Subclass if you need to dynamically enable/disable the service. (For example if it only works with specific hardware) ++ (BOOL)canShare +{ + return YES; +} + + +#pragma mark - +#pragma mark Authentication + +// These defines should be renamed (to match your service name). +// They will eventually be moved to SHKConfig so the user can modify them. + +// linkedin.com key info here: https://www.linkedin.com/secure/developer (JRS) + +#define SHKLinkedInCallbackUrl @"hdlinked://linkedin/oauth" +#define SHKLinkedInRealm @"https://api.linkedin.com/" +#define SHKLinkedInShareURL @"http://api.linkedin.com/v1/people/~/shares" + +/* + The site: https://api.linkedin.com. Some libraries will have you enter this root URL. + Request token path: /uas/oauth/requestToken + Access token path: /uas/oauth/accessToken + Authorize path: /uas/oauth/authorize +*/ + +#define SHKLinkedInAPIRequestURL @"https://api.linkedin.com/uas/oauth/requestToken" +#define SHKLinkedInAPIAccessURL @"https://api.linkedin.com/uas/oauth/accessToken" +#define SHKLinkedInAPIAuthorizeURL @"https://www.linkedin.com/uas/oauth/authorize" + +#define SHKLinkedInShareLimit (700) // char limit for shares +#define SHKLinkedInDescriptionLimit (400) // char limit for URL descriptions +#define SHKLInkedInTitleLimit (200) // char limit for titles + +//////// + +- (id)init +{ + if ((self = [super init])) + { + self.consumerKey = SHKLinkedInConsumerKey; + self.secretKey = SHKLinkedInSecretKey; + self.authorizeCallbackURL = [NSURL URLWithString:SHKLinkedInCallbackUrl]; + + // Set to correct URL's for OAuth steps, as defined above (JRS) + self.requestURL = [NSURL URLWithString:SHKLinkedInAPIRequestURL]; + self.accessURL = [NSURL URLWithString:SHKLinkedInAPIAccessURL]; + self.authorizeURL = [NSURL URLWithString:SHKLinkedInAPIAuthorizeURL]; + self.realm = SHKLinkedInRealm; + + // Allows you to set a default signature type, uncomment only one + self.signatureProvider = [[[OAHMAC_SHA1SignatureProvider alloc] init] autorelease]; + } + return self; +} + +// If you need to add additional headers or parameters to the request_token request, uncomment this section: + +- (void)tokenRequestModifyRequest:(OAMutableURLRequest *)oRequest +{ + // Here is an example that adds the user's callback to the request headers +// [oRequest setOAuthParameterName:@"oauth_callback" withValue:authorizeCallbackURL.absoluteString]; + + oRequest.callback = authorizeCallbackURL.absoluteString; + +} + + +// If you need to add additional headers or parameters to the access_token request, uncomment this section: + +- (void)tokenAccessModifyRequest:(OAMutableURLRequest *)oRequest +{ + // Here is an example that adds the oauth_verifier value received from the authorize call. + // authorizeResponseQueryVars is a dictionary that contains the variables sent to the callback url + [oRequest setOAuthParameterName:@"oauth_verifier" withValue:[authorizeResponseQueryVars objectForKey:@"oauth_verifier"]]; +} + + + +#pragma mark - +#pragma mark Share Form + +// If your action has options or additional information it needs to get from the user, +// use this to create the form that is presented to user upon sharing. + + + +- (NSArray *)shareFormFieldsForType:(SHKShareType)type +{ + // See http://getsharekit.com/docs/#forms for documentation on creating forms + + if (type == SHKShareTypeURL) + { + // An example form that has a single text field to let the user edit the share item's title + return [NSArray arrayWithObjects: + + [SHKLinkedInField textField:@"Title" key:@"title" placeholder:@"the title" type:SHKLinkedInTextFieldPlain newGroup:false], + [SHKLinkedInField urlField:@"URL" key:@"URL" placeholder:@"the url" newGroup:false], + + [SHKLinkedInField multilineTextField:@"Link Description" key:@"linkDescription" placeholder:@"Link Description (optional)" charLimit:SHKLinkedInDescriptionLimit newGroup:false required:false], + + [SHKLinkedInField multilineTextField:@"Status Update" key:@"text" placeholder:@"Status Update (optional)" charLimit:SHKLinkedInShareLimit newGroup:true required:false], + + nil ]; + + } + else if (type == SHKShareTypeText) + { + // An example form that has a single text field to let the user edit the share item's title + return [NSArray arrayWithObjects: + + [SHKLinkedInField multilineTextField:@"Status Update" key:@"text" placeholder:@"Post Status Update" charLimit:SHKLinkedInShareLimit newGroup:false required:true], + + nil ]; + } + else if (type == SHKShareTypeImage) + { + // return a form if required when sharing an image + return nil; + } + else if (type == SHKShareTypeFile) + { + // return a form if required when sharing a file + return nil; + } + + return nil; +} + + + +// If you have a share form the user will have the option to skip it in the future. +// If your form has required information and should never be skipped, uncomment this section. ++ (BOOL)canAutoShare +{ + return NO; +} + + + +- (void)show +{ + if (item.shareType == SHKShareTypeURL) + { +// [self shortenURL]; + [self showLinkedInForm]; + + } + else if (item.shareType == SHKShareTypeText) + { + [self showLinkedInForm]; + } + +} + +- (void)showLinkedInForm +{ + SHKLinkedInForm *rootView = [[SHKLinkedInForm alloc] initWithNibName:nil bundle:nil]; + rootView.delegate = self; + rootView.item = item; + rootView.style.backgroundColor = [UIColor colorWithRed:0.8f green:0.92f blue:1.0f alpha:1.0f]; + + // force view to load so we can set textView text + [rootView view]; + + [rootView setFieldValuesForItem:item]; + + [self pushViewController:rootView animated:NO]; + [[SHK currentHelper] showViewController:self]; +} + +- (void)sendForm:(SHKLinkedInForm *)form +{ + + [form applyFieldValuesToItem:item]; + + [self tryToSend]; +} + + + +// Validate the user input on the share form +- (void)shareFormValidate:(SHKCustomFormController *)form +{ + /* + + Services should subclass this if they need to validate any data before sending. + You can get a dictionary of the field values from [form formValues] + + -- + + You should perform one of the following actions: + + 1. Save the form - If everything is correct call [form saveForm] + + 2. Display an error - If the user input was incorrect, display an error to the user and tell them what to do to fix it + + + */ + + // default does no checking and proceeds to share + [form saveForm]; +} + + + +#pragma mark - +#pragma mark Implementation + +// When an attempt is made to share the item, verify that it has everything it needs, otherwise display the share form + +- (BOOL)validateItem +{ + // The super class will verify that: + // -if sharing a url : item.url != nil + // -if sharing an image : item.image != nil + // -if sharing text : item.text != nil + // -if sharing a file : item.data != nil + + return [super validateItem]; +} + + +// Send the share item to the server +- (BOOL)send +{ + if (![self validateItem]) + return NO; + + /* + Enter the necessary logic to share the item here. + + The shared item and relevant data is in self.item + // See http://getsharekit.com/docs/#sending + + -- + + A common implementation looks like: + + - Send a request to the server + - call [self sendDidStart] after you start your action + - after the action completes, fails or is cancelled, call one of these on 'self': + - (void)sendDidFinish (if successful) + - (void)sendDidFailShouldRelogin (if failed because the user's current credentials are out of date) + - (void)sendDidFailWithError:(NSError *)error shouldRelogin:(BOOL)shouldRelogin + - (void)sendDidCancel + */ + + + // Determine which type of share to do + if (item.shareType == SHKShareTypeURL || item.shareType == SHKShareTypeText) // sharing a URL + { + // For more information on OAMutableURLRequest see http://code.google.com/p/oauthconsumer/wiki/UsingOAuthConsumer + + OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:SHKLinkedInShareURL] + consumer:consumer // this is a consumer object already made available to us + token:self.accessToken // this is our accessToken already made available to us + realm:self.realm + signatureProvider:signatureProvider]; + + // Set the http method (POST or GET) + [oRequest setHTTPMethod:@"POST"]; + + // Build the share document (XML) More information on the share format can be found here: + // + // http://developer.linkedin.com/docs/DOC-1212 + // + + NSString *comment = nil; + NSString *content = nil; + NSString *visibility = @"anyone"; + + if(item.text) + comment = [NSString stringWithFormat:@"%@", item.text]; + + if(item.URL) + { + NSString *contentTitle = [NSString stringWithFormat:@"%@", item.title]; + NSString *contentURL = [NSString stringWithFormat:@" %@", [item.URL absoluteString]]; + NSString *contentDescription = @""; + + NSString *desc = [item customValueForKey:@"linkDescription"]; + + if(desc) + contentDescription = [NSString stringWithFormat:@" %@", desc]; + + content = [NSString stringWithFormat:@"%@%@%@", contentTitle, contentURL, contentDescription]; + + } + + NSMutableString *share = [NSMutableString string]; + + if(comment) + [share appendString:comment]; + + if(content) + [share appendString:content]; + + [share appendString:visibility]; + + NSString *body = [NSString stringWithFormat:@"%@", share ]; + + // Prepare the request before setting the body, because OAuthConsumer wants to parse the body + // for parameters to include in the signature, but LinkedIn doesn't work that way (JRS) + [oRequest prepare]; + + if([body length]) + [oRequest setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]]; + + // [oRequest setValue:[NSString stringWithFormat:@"%d", [body length]] forHTTPHeaderField:@"Content-Length"]; + [oRequest setValue:@"text/xml;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; + + // Start the request + OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest + delegate:self + didFinishSelector:@selector(sendTicket:didFinishWithData:) + didFailSelector:@selector(sendTicket:didFailWithError:)]; + + [fetcher start]; + [oRequest release]; + + // Notify delegate + [self sendDidStart]; + + return true; + } + + return false; + +} + +// This is a continuation of the example provided in 'send' above. It handles the OAAsynchronousDataFetcher response +// This is not a required method and is only provided as an example + +- (void)sendTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data +{ + if (ticket.didSucceed) + { + // The send was successful + [self sendDidFinish]; + } + else + { + // Handle the error +/* NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + SHKLog(@"*ERROR* Share Ticket Response:%@", responseBody); + [responseBody release]; +*/ + // If the error was the result of the user no longer being authenticated, you can reprompt + // for the login information with: + // [self sendDidFailShouldRelogin]; + + // Otherwise, all other errors should end with: + [self sendDidFailWithError:[SHK error:@"Why it failed"] shouldRelogin:NO]; + } +} +- (void)sendTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error +{ + [self sendDidFailWithError:error shouldRelogin:NO]; +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.h b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.h new file mode 100644 index 00000000..a8e6519f --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.h @@ -0,0 +1,95 @@ +// +// SHKLinkedInField.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInForm.h" + +#import "SHKLinkedInFormStyle.h" + +@class SHKLinkedInMultilineTextField; +@class SHKLinkedInTextField; +@class SHKLinkedInURLField; + +@class SHKLinkedInForm; +@class SHKLinkedInField; + +typedef enum +{ + + SHKLinkedInTextFieldPlain, + SHKLinkedInTextFieldPassword + +} SHKLinkedInTextFieldType; + + +@protocol SHKLinkedInFieldDelegate + +@required + +- (void)fieldViewFrameDidChange:(SHKLinkedInField*)field; + +@end + + +@interface SHKLinkedInField : NSObject +{ + id fieldDelegate; + + UIView *view; + + NSString *label; + NSString *key; + + float topMargin; + float bottomMargin; + BOOL newGroup; + +} + +@property (nonatomic, retain) id fieldDelegate; +@property (nonatomic, retain) UIView *view; +@property (readwrite) float topMargin, bottomMargin; +@property (nonatomic, readwrite) BOOL newGroup; +@property (nonatomic, retain) NSString *label; +@property (nonatomic, retain) NSString *key; + +@property (nonatomic, assign) id value; + +-(void)loadViewWithFrame:(CGRect)frame style:(SHKLinkedInFormStyle*)style; +-(void)fieldWillAppear:(SHKLinkedInForm*)form; +-(BOOL)validate; +-(void)setAsFirstResponder; + + ++(SHKLinkedInMultilineTextField*) multilineTextField:(NSString*)label key:(NSString*)key placeholder:(NSString*)placeholder charLimit:(int)charLimit newGroup:(BOOL)newGroup required:(BOOL)required; + ++(SHKLinkedInTextField*) textField:(NSString*)label key:(NSString*)key placeholder:(NSString*)placeholder type:(SHKLinkedInTextFieldType)type newGroup:(BOOL)newGroup; + ++(SHKLinkedInURLField*) urlField:(NSString*)label key:(NSString*)key placeholder:(NSString*)placeholder newGroup:(BOOL)newGroup; + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.m b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.m new file mode 100644 index 00000000..441f6d5d --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInField.m @@ -0,0 +1,194 @@ +// +// SHKLinkedInField.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHK.h" +#import "SHKLinkedInField.h" +#import "SHKLinkedInMultilineTextField.h" +#import "SHKLinkedInTextField.h" +#import "SHKLinkedInURLField.h" + + +@interface SHKLinkedInField() + +@end + + +// SHKLinkedInField +// +// Abstract base class for creating form fields +// + +@implementation SHKLinkedInField + +@synthesize view; +@synthesize fieldDelegate; +@synthesize newGroup; +@synthesize topMargin, bottomMargin; +@synthesize label, key; + + +// loadViewWithFrame:style +// +// All Subclasses should override this to set the field's view object hierarchy +// + +-(void)loadViewWithFrame:(CGRect)frame style:(SHKLinkedInFormStyle*)style +{ + self.view = nil; +} + + +- (id)init +{ + if((self = [super init])) + { + topMargin = 0.0f; + bottomMargin = 0.0f; + + self.fieldDelegate = nil; + self.view = nil; + self.key = nil; + + } + + return self; + +} + + +- (void)dealloc +{ + self.fieldDelegate = nil; + + self.label = nil; + self.key = nil; + self.view = nil; + + [super dealloc]; +} + + + + +-(void)fieldWillAppear:(SHKLinkedInForm*)form +{ + // Override this if your field controls need to be adjusted prior to display + // This is provided as form view frame isn't size correctly until it's pushed + // onto the view controller stack +} + + + + +-(BOOL)validate +{ + // Override to perform general validation for a field type + + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"No Field Defined") + message:SHKLocalizedString(@"You must define a valid field subclass to use") + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Close") + otherButtonTitles:nil] autorelease] show]; + + return false; +} + + +-(void)setAsFirstResponder +{ + // Override to perform set the relevant input control as the first responder +} + + +-(id)value +{ + // Override to get the value of the input control + + return nil; +} + +-(void)setValue:(id)value +{ + // Override to set the value of the input control + + return; +} + + +// Class factory methods, provided as a convenience to create fields in sharer classes + ++(SHKLinkedInMultilineTextField*) multilineTextField:(NSString*)label key:(NSString*)key placeholder:(NSString*)placeholder charLimit:(int)charLimit newGroup:(BOOL)newGroup required:(BOOL)required +{ + + SHKLinkedInMultilineTextField* mtf = [[SHKLinkedInMultilineTextField alloc] init]; + + mtf.label = label; + mtf.key = key; + mtf.placeholder = placeholder; + mtf.charLimit = charLimit; + mtf.newGroup = newGroup; + mtf.required = required; + + return [mtf autorelease]; + +} + + ++(SHKLinkedInTextField*) textField:(NSString*)label key:(NSString*)key placeholder:(NSString*)placeholder type:(SHKLinkedInTextFieldType)type newGroup:(BOOL)newGroup +{ + SHKLinkedInTextField* tf = [[SHKLinkedInTextField alloc] init]; + + tf.label = label; + tf.key = key; + tf.placeholder = placeholder; + tf.type = type; + tf.newGroup = newGroup; + + return [tf autorelease]; + +} + + ++(SHKLinkedInURLField*) urlField:(NSString*)label key:(NSString*)key placeholder:(NSString*)placeholder newGroup:(BOOL)newGroup +{ + + SHKLinkedInURLField* uf = [[SHKLinkedInURLField alloc] init]; + + uf.label = label; + uf.key = key; + uf.placeholder = placeholder; + uf.newGroup = newGroup; + + return [uf autorelease]; +} + + + +@end + diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.h b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.h new file mode 100644 index 00000000..d8dfd1b0 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.h @@ -0,0 +1,67 @@ +// +// SHKLinkedInForm.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInFormStyle.h" +#import "SHKItem+KVC.h" +#import "SHKLinkedInField.h" + +@interface SHKLinkedInForm : UIViewController +{ + id delegate; + UIScrollView *scrollView; + + SHKItem *item; + + NSMutableArray *formFieldArray; + NSMutableDictionary *formFieldDict; + + SHKLinkedInFormStyle *style; + + BOOL hasAttachment; + BOOL enableURLFields; +} + +@property (nonatomic, retain) id delegate; +@property (nonatomic, retain) UIScrollView *scrollView; +@property (nonatomic, retain) UILabel *counter; +@property (nonatomic, retain) NSMutableDictionary *formFieldDict; + +@property (nonatomic, retain) SHKItem *item; +@property (readonly) SHKLinkedInFormStyle *style; + +@property BOOL hasAttachment; +@property BOOL enableURLFields; + +- (void)setFieldValuesForItem:(SHKItem*)item; +- (void)applyFieldValuesToItem:(SHKItem*)item; +- (void)save; +- (void)keyboardWillShow:(NSNotification *)notification; + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.m b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.m new file mode 100644 index 00000000..fd31ca5b --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInForm.m @@ -0,0 +1,408 @@ +// +// SHKLinkedInForm.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHK.h" +#import "SHKLinkedInForm.h" +#import "SHKLinkedIn.h" +#import "SHKLinkedInField.h" +#import "SHKItem+KVC.h" + +@interface SHKLinkedInForm () + +- (void)layoutForm; + + +@end + + + +@implementation SHKLinkedInForm + +@synthesize delegate; +@synthesize scrollView; +@synthesize counter; +@synthesize hasAttachment; +@synthesize enableURLFields; +@synthesize formFieldDict; +@synthesize style; +@synthesize item; + + +- (void)dealloc +{ + [delegate release]; + [scrollView release]; + + [item release]; + + [style release]; + + [counter release]; + + [formFieldArray release]; + [formFieldDict release]; + + [super dealloc]; +} + + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) + { + self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:self + action:@selector(cancel)]; + + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:SHKLocalizedString(@"Send to LinkedIn") + style:UIBarButtonItemStyleDone + target:self + action:@selector(save)]; + + + + self.hasAttachment = false; + self.enableURLFields = false; + + style = [[SHKLinkedInFormStyle style] retain]; + + } + + + + return self; +} + + +///// + + +- (void)layoutForm +{ + float ypos = 0.0f; + + for(SHKLinkedInField *field in formFieldArray) + { + ypos += field.topMargin; + + CGRect r = field.view.frame; + r.origin.y = ypos; + field.view.frame = r; + + ypos += r.size.height + field.bottomMargin; + + } + + scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, 16 + ypos); + +} + + +//////// + +- (void)loadView +{ + [super loadView]; + + float leftRightMargins, topMargin, fieldMargin, groupMargin; + + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) + { + leftRightMargins = 45.0f; + topMargin = 40.0f; + fieldMargin = 3.0f; + groupMargin = 28.0f; + } + else + { + leftRightMargins = 8.0f; + topMargin = 8.0f; + fieldMargin = 2.0f; + groupMargin = 14.0f; + } + + float fieldHeight = 42.0f; + + self.view.backgroundColor = self.style.backgroundColor; + + UIScrollView *sv = [[UIScrollView alloc] initWithFrame:self.view.bounds]; + sv.contentInset = UIEdgeInsetsMake(0, 0, 20, 0); + sv.backgroundColor = [UIColor clearColor]; + sv.alwaysBounceHorizontal = false; + sv.alwaysBounceVertical = true; + sv.clipsToBounds = false; + + formFieldArray = [[NSMutableArray array] retain]; + self.formFieldDict = [NSMutableDictionary dictionary]; + + NSArray *a = [(SHKLinkedIn*)self.delegate shareFormFieldsForType:item.shareType]; + + float header = topMargin; + + for(SHKLinkedInField *field in a) + { + CGRect frame = CGRectMake(0, 0, self.view.bounds.size.width, fieldHeight); + CGPoint inset = CGPointMake(leftRightMargins, 0); + CGRect i = CGRectInset(frame, inset.x, inset.y) ; + + field.fieldDelegate = self; + + [field loadViewWithFrame:i style:self.style]; + + [sv addSubview:field.view]; + + if(field.newGroup) + field.topMargin = groupMargin; + else + field.topMargin = header; + + [formFieldArray addObject:field]; + [self.formFieldDict setObject:field forKey:field.key]; + + header = fieldMargin; + + } + + self.scrollView = sv; + [self.view addSubview:self.scrollView]; + + [sv release]; + + [self layoutForm]; + +} + + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + scrollView.frame = CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height); + + for(SHKLinkedInField* field in formFieldArray) + { + [field fieldWillAppear:self]; + } + + [self layoutForm]; + +} + + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil]; + [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil]; + + + if([formFieldArray count]) + [(SHKLinkedInField*)[formFieldArray objectAtIndex:0] setAsFirstResponder]; + +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + + // Remove observers + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:self name: UIKeyboardWillShowNotification object:nil]; + + // Remove the SHK view wrapper from the window + [[SHK currentHelper] viewWasDismissed]; +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +////////// + + +//#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +- (void)keyboardWillHide:(NSNotification *)notification +{ + CGRect sb = scrollView.bounds; + CGRect sf = self.scrollView.frame; + sb.size.height = self.view.bounds.size.height; + sf.size.height = self.view.frame.size.height; + + // animate the scrollview content view back to full size + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:0.4]; + self.scrollView.frame = sf; + [UIView commitAnimations]; + + +} + + +- (void)keyboardWillShow:(NSNotification *)notification +{ + CGRect keyboardFrame; + CGFloat keyboardHeight; + + // 3.2 and above + /*if (UIKeyboardFrameEndUserInfoKey) + { + [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame]; + if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) + keyboardHeight = keyboardFrame.size.height; + else + keyboardHeight = keyboardFrame.size.width; + } + + // < 3.2 + else + {*/ + + [[notification.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame]; + keyboardHeight = keyboardFrame.size.height; + //} + + // Find the bottom of the screen (accounting for keyboard overlay) + // This is pretty much only for pagesheet's on the iPad + UIInterfaceOrientation orient = [[UIApplication sharedApplication] statusBarOrientation]; + BOOL inLandscape = orient == UIInterfaceOrientationLandscapeLeft || orient == UIInterfaceOrientationLandscapeRight; + BOOL upsideDown = orient == UIInterfaceOrientationPortraitUpsideDown || orient == UIInterfaceOrientationLandscapeRight; + + CGPoint topOfViewPoint = [self.view convertPoint:CGPointZero toView:nil]; + CGFloat topOfView = inLandscape ? topOfViewPoint.x : topOfViewPoint.y; + + CGFloat screenHeight = inLandscape ? [[UIScreen mainScreen] applicationFrame].size.width : [[UIScreen mainScreen] applicationFrame].size.height; + + CGFloat distFromBottom = screenHeight - ((upsideDown ? screenHeight - topOfView : topOfView ) + self.view.bounds.size.height) + ([UIApplication sharedApplication].statusBarHidden || upsideDown ? 0 : 20); + + + CGFloat maxViewHeight = self.view.bounds.size.height - keyboardHeight + distFromBottom; + float maxy = screenHeight - keyboardHeight + 20; + + UIView *v = ((SHKLinkedIn*)self.delegate).view.superview; + CGRect f = v.frame; + float vy = f.origin.y + f.size.height; + + float delta = (vy > maxy) ? vy - maxy : 0.0f; + + if(delta) + { + // animate the scrollview content view to frame what's visible behind the keyboard pop-up + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:0.4]; + self.scrollView.frame = CGRectMake(0,0,self.view.bounds.size.width,maxViewHeight); + [UIView commitAnimations]; + } + + +} + + +#pragma mark - + +- (void)cancel +{ + [[SHK currentHelper] hideCurrentViewControllerAnimated:YES]; + [(SHKLinkedIn *)delegate sendDidCancel]; +} + + +- (void)save +{ + + for(SHKLinkedInField *field in formFieldArray) + { + if(!([field validate])) + return; + } + + [(SHKLinkedIn *)delegate sendForm:self]; + + [[SHK currentHelper] hideCurrentViewControllerAnimated:YES]; +} + + +//// + + +- (void)setFieldValuesForItem:(SHKItem*)theItem +{ + if(self.formFieldDict) + { + for(NSString* key in self.formFieldDict) + { + SHKLinkedInField *field = [self.formFieldDict valueForKey:key]; + id value = [theItem propertyForKey:key]; + + if(value) + { + field.value = value; + } + + } + } + +} + + + +- (void)applyFieldValuesToItem:(SHKItem*)theItem +{ + if(self.formFieldDict) + { + for(NSString* key in self.formFieldDict) + { + SHKLinkedInField *field = [self.formFieldDict valueForKey:key]; + + if(field.value) + [theItem setProperty:field.value forKey:key]; + + } + + } + +} + + +- (void)fieldViewFrameDidChange:(SHKLinkedInField*)field +{ + + [self layoutForm]; +} + + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.h b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.h new file mode 100644 index 00000000..34eb1b70 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.h @@ -0,0 +1,53 @@ +// +// SHKLinkedInFormStyle.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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. +// +// + + + +@interface SHKLinkedInFormStyle : NSObject { + + UIColor *backgroundColor; + UIColor *fieldBackgroundColor; + UIColor *labelTextColor; + UIColor *textColor; + UIColor *placeholderTextColor; + UIColor *counterTextColor; + +} + +@property (nonatomic, retain) UIColor *backgroundColor; +@property (nonatomic, retain) UIColor *fieldBackgroundColor; +@property (nonatomic, retain) UIColor *labelTextColor; +@property (nonatomic, retain) UIColor *textColor; +@property (nonatomic, retain) UIColor *placeholderTextColor; +@property (nonatomic, retain) UIColor *counterTextColor; + + ++(SHKLinkedInFormStyle*)style; + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.m b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.m new file mode 100644 index 00000000..1756bc8c --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInFormStyle.m @@ -0,0 +1,76 @@ +// +// SHKLinkedInFormStyle.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInFormStyle.h" + + +@implementation SHKLinkedInFormStyle + +@synthesize backgroundColor, fieldBackgroundColor, labelTextColor, textColor, placeholderTextColor, counterTextColor; + + +- (id)init +{ + if((self = [super init])) + { + self.backgroundColor = [UIColor colorWithRed:0.86f green:0.88f blue:0.90f alpha:1.0f]; + self.fieldBackgroundColor = [UIColor whiteColor]; + self.labelTextColor = [UIColor colorWithRed:50/255.0f green:79/255.0f blue:133/255.0f alpha:1.0f]; + self.textColor = [UIColor blackColor]; + self.placeholderTextColor = [UIColor lightGrayColor]; + self.counterTextColor = [UIColor lightGrayColor]; + } + + return self; + +} + + +- (void)dealloc +{ + self.backgroundColor = nil; + self.fieldBackgroundColor = nil; + self.labelTextColor = nil; + self.textColor = nil; + self.placeholderTextColor = nil; + self.counterTextColor = nil; + + [super dealloc]; +} + + ++(SHKLinkedInFormStyle*)style +{ + SHKLinkedInFormStyle *newStyle = [[SHKLinkedInFormStyle alloc] init]; + + return [newStyle autorelease]; +} + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.h b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.h new file mode 100644 index 00000000..b989b6dc --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.h @@ -0,0 +1,58 @@ +// +// SHKLinkedInMultilineTextView.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInField.h" +#import "SHKLinkedInFormStyle.h" + + +@interface SHKLinkedInMultilineTextField : SHKLinkedInField +{ + + UITextView *textView; + + NSString *placeholder; + + int charLimit; + BOOL required; + + UILabel *counterLabel; + UILabel *placeholderLabel; + UILabel *fieldLabel; + + UIColor *counterTextColor; + + +} + + +@property (nonatomic, retain) NSString *placeholder; + +@property (nonatomic, readwrite) int charLimit; +@property (nonatomic, readwrite) BOOL required; + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.m b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.m new file mode 100644 index 00000000..aaf33791 --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInMultilineTextField.m @@ -0,0 +1,420 @@ +// +// SHKLinkedInMultilineTextView.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHK.h" +#import "SHKLinkedInMultilineTextField.h" + +#import + + +#define MTV_MARGIN_LEFT (8) +#define MTV_MARGIN_RIGHT (8) +#define MTV_MARGIN_BOTTOM (4) +#define MTV_FOOTER_HEIGHT (16) +#define MTV_LABEL_WIDTH (190) +#define MTV_COUNTER_WIDTH (60) +#define MTV_PLACEHOLDER_MARGIN_TOP (6) +#define MTV_PLACEHOLDER_WIDTH (280) +#define MTV_PLACEHOLDER_HEIGHT (24) + +#define MTV_TEXT_SIZE (15.0f) +#define MTV_LABEL_SIZE (15.0f) + + +@interface SHKLinkedInMultilineTextField () + +- (void)updateDisplay; +- (void)updateCounter:(UITextView*)tv; +- (void)updateLabelVisibility; +- (void)frameContent; + +@end + + + +@implementation SHKLinkedInMultilineTextField + +@synthesize charLimit; +@synthesize placeholder; +@synthesize required; + + +-(void)loadViewWithFrame:(CGRect)frame style:(SHKLinkedInFormStyle*)style +{ + + UITextView *tv = [[[UITextView alloc] initWithFrame:frame] autorelease]; + + tv.textColor = style.textColor; + tv.backgroundColor = style.fieldBackgroundColor; + tv.font = [UIFont systemFontOfSize:MTV_TEXT_SIZE]; + tv.autoresizesSubviews = YES; + tv.autoresizingMask = UIViewAutoresizingFlexibleWidth; + tv.layer.masksToBounds = true; + tv.opaque = false; + tv.layer.cornerRadius = 8; + tv.scrollEnabled = false; + tv.scrollsToTop = false; + tv.bounces = false; + + tv.delegate = self; + + counterTextColor = [style.counterTextColor copy]; + + + fieldLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + fieldLabel.backgroundColor = [UIColor clearColor]; + fieldLabel.opaque = NO; + fieldLabel.font = [UIFont boldSystemFontOfSize:MTV_LABEL_SIZE]; + fieldLabel.textAlignment = UITextAlignmentLeft; + fieldLabel.autoresizesSubviews = YES; + fieldLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin; + fieldLabel.textColor = style.labelTextColor; + + fieldLabel.frame = CGRectMake(MTV_MARGIN_LEFT, + frame.size.height - MTV_FOOTER_HEIGHT - MTV_MARGIN_BOTTOM, + MTV_LABEL_WIDTH, + MTV_FOOTER_HEIGHT); + + + fieldLabel.text = self.label; + + [tv addSubview:fieldLabel]; + + + counterLabel = [[UILabel alloc] initWithFrame: CGRectMake(frame.size.width - MTV_COUNTER_WIDTH - MTV_MARGIN_RIGHT, + frame.size.height - MTV_FOOTER_HEIGHT - MTV_MARGIN_BOTTOM, + MTV_COUNTER_WIDTH, + MTV_FOOTER_HEIGHT)]; + + counterLabel.backgroundColor = [UIColor clearColor]; + counterLabel.opaque = NO; + counterLabel.font = [UIFont boldSystemFontOfSize:MTV_LABEL_SIZE]; + counterLabel.textAlignment = UITextAlignmentRight; + counterLabel.autoresizesSubviews = YES; + counterLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; + + [tv addSubview:counterLabel]; + + + placeholderLabel = [[UILabel alloc] initWithFrame:CGRectMake(MTV_MARGIN_LEFT, + MTV_PLACEHOLDER_MARGIN_TOP, + MTV_PLACEHOLDER_WIDTH, + MTV_PLACEHOLDER_HEIGHT) ]; + + placeholderLabel.backgroundColor = [UIColor clearColor]; + placeholderLabel.opaque = NO; + placeholderLabel.font = [UIFont systemFontOfSize:MTV_TEXT_SIZE]; + placeholderLabel.textColor = style.placeholderTextColor; //[UIColor lightGrayColor]; + placeholderLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; + placeholderLabel.textAlignment = UITextAlignmentLeft; + + placeholderLabel.text = placeholder; + + [tv addSubview:placeholderLabel]; + + // initialize the state of subviews (JRS) + [self updateLabelVisibility]; + [self updateCounter:nil]; + + [textView release]; + textView = [tv retain]; + + // Set the field view + self.view = tv; + +} + + +- (id)init +{ + if((self = [super init])) + { + charLimit = -1; + required = false; + + textView = nil; + + counterLabel = nil; + placeholderLabel = nil; + fieldLabel = nil; + + counterTextColor = nil; +// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; + + } + + return self; + +} + + + +- (void)dealloc +{ + + [textView release]; + [fieldLabel release]; + [counterLabel release]; + [placeholderLabel release]; + + [counterTextColor release]; + + self.placeholder = nil; + + //[[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; + +} + + ++ (SHKLinkedInMultilineTextField*) textViewWithFrame:(CGRect)frame label:(NSString*)label placeholder:(NSString*)placeholder charLimit:(int)charLimit style:(SHKLinkedInFormStyle*)style delegate:(id)delegate +{ + + SHKLinkedInMultilineTextField* fv = [[SHKLinkedInMultilineTextField alloc] initWithFrame:frame]; + + UITextView *textView = (UITextView*)fv.view; + textView.delegate = delegate; + + charLimit = charLimit; + + return [fv autorelease]; +} + + + +- (void)updateDisplay +{ + + [self updateLabelVisibility]; + [self updateCounter:textView]; + + [self frameContent]; + + [fieldDelegate fieldViewFrameDidChange:self]; + +// [form layoutForm]; +} + + + +- (void)updateLabelVisibility +{ + + if ([[textView text] length] == 0) + { + placeholderLabel.hidden = false; + fieldLabel.hidden = true; + } + else + { + placeholderLabel.hidden = true; + fieldLabel.hidden = false; + } + +} + + +- (void)updateCounter:(UITextView*)tv +{ + + UILabel *ctr = counterLabel; + + if(charLimit > 0) + { + BOOL hasAttachment = false; // taken from Twitter form support, should probably be removed (JRS) + int count = (hasAttachment?(charLimit-25):charLimit) - tv.text.length; + + ctr.text = [NSString stringWithFormat:@"%@%i", hasAttachment ? @"Image + ":@"" , count]; + ctr.textColor = count >= 0 ? counterTextColor : [UIColor redColor]; + ctr.hidden = false; + + } + else + { + ctr.hidden = true; + } + +} + + + +- (void)textViewDidChange:(UITextView *)tv +{ + + [self updateDisplay]; + +} + + +/* +-(void)textChanged:(NSNotification*)notif +{ + [self updateLabelVisibility]; + [self updateCounter:textView]; +} +*/ + + +-(void)fieldWillAppear:(SHKLinkedInForm*)form +{ + + [self updateDisplay]; + +} + + + +- (void)frameContent +{ + UITextView *tv = textView; + tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, tv.contentSize.width, tv.contentSize.height + (MTV_FOOTER_HEIGHT + 2)); +} + + +-(BOOL)validate +{ + + NSString *fieldName = SHKLocalizedString(self.label); + + if(self.required) + { + if([textView.text length] < 1) + { + + NSString *message = SHKLocalizedString(@"You must provide text for this field in order to post."); + message = [NSString stringWithFormat:@"\"%@\": %@", fieldName, message]; + + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Required Field") + message:message + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Close") + otherButtonTitles:nil] autorelease] show]; + + return false; + + } + } + + if(charLimit > 0) + { + if([textView.text length] > charLimit) + { + NSString *limit = [NSString stringWithFormat:@"%i", charLimit]; + NSString *message = SHKLocalizedString(@"You must limit input to XXXX characters or less in order to post."); + message = [message stringByReplacingOccurrencesOfString:@"XXXX" withString:limit]; + message = [NSString stringWithFormat:@"\"%@\": %@", fieldName, message]; + + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Limit Exceeded") + message:message + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Close") + otherButtonTitles:nil] autorelease] show]; + + return false; + + } + } + + return true; +} + + +-(void)setAsFirstResponder +{ + [textView becomeFirstResponder]; + + NSRange n; + n.length = 0; + n.location = 0; + + textView.selectedRange = n; +} + +//// + +- (void)setPlaceholder:(NSString *)thePlaceholder +{ + [placeholder release]; + placeholder = [thePlaceholder retain]; + + placeholderLabel.text = thePlaceholder; + + CGSize newsize = [thePlaceholder sizeWithFont:placeholderLabel.font]; + CGRect frame = placeholderLabel.frame; + frame.size = newsize; + + placeholderLabel.frame = frame; + +} + + + +- (void)setLabel:(NSString *)theLabel +{ + [super setLabel:theLabel]; + + fieldLabel.text = theLabel; +} + + + +-(void) setCharLimit:(int)theCharLimit +{ + charLimit = theCharLimit; + + [self updateCounter:textView]; +} + +///// + +-(id)value +{ + return textView.text; +} + + +-(void)setValue:(id)value +{ + + textView.text = (NSString*)value; + + [self updateCounter:textView]; + [self updateLabelVisibility]; + [self frameContent]; + + [fieldDelegate fieldViewFrameDidChange:self]; + +// [form layoutForm]; + +} + + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.h b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.h new file mode 100644 index 00000000..c943f67e --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.h @@ -0,0 +1,51 @@ +// +// SHKLinkedInTextViewV2.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInField.h" +#import "SHKLinkedInFormStyle.h" + + + +@interface SHKLinkedInTextField : SHKLinkedInField +{ + + UITextField *textField; + NSString *placeholder; + + SHKLinkedInTextFieldType type; + +} + + +@property (nonatomic, readwrite) SHKLinkedInTextFieldType type; +@property (nonatomic, retain) NSString *placeholder; + + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.m b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.m new file mode 100644 index 00000000..a0970d0e --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInTextField.m @@ -0,0 +1,186 @@ +// +// SHKLinkedInTextViewV2.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHK.h" +#import "SHKLinkedInTextField.h" +#import + +@implementation SHKLinkedInTextField + +@synthesize placeholder; +@synthesize type; + + +- (id)init +{ + if((self = [super init])) + { + self.placeholder = nil; + textField = nil; + self.type = SHKLinkedInTextFieldPlain; + + } + + return self; + +} + + +- (void)dealloc +{ + + self.placeholder = nil; + + [textField release]; + + [super dealloc]; + +} + + +-(void)loadViewWithFrame:(CGRect)frame style:(SHKLinkedInFormStyle*)style +{ + UITextField *tf = nil; + + UIView *v = nil; + + v = [[[UIView alloc] initWithFrame:frame] autorelease]; + v.backgroundColor = style.fieldBackgroundColor; + v.opaque = false; + v.layer.masksToBounds = true; + v.layer.cornerRadius = 8; + v.autoresizingMask = UIViewAutoresizingFlexibleWidth; + v.autoresizesSubviews = true; + v.clipsToBounds = true; + + float leftInset = 8.0f; + float rightInset = 8.0f; + float spacing = 12.0f; + + UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(leftInset, 0, 0, v.frame.size.height)]; + l.backgroundColor = [UIColor clearColor]; + l.font = [UIFont boldSystemFontOfSize:18.0f]; + l.textColor = style.labelTextColor; + + l.text = self.label; + + CGSize s = [label sizeWithFont:l.font]; + float labelWidth = s.width; + l.frame = CGRectMake(l.frame.origin.x, l.frame.origin.y, labelWidth, l.frame.size.height); + + float fieldOffset = leftInset + labelWidth + spacing; + float fieldWidth = v.frame.size.width - fieldOffset - rightInset; + + tf = [[[UITextField alloc] initWithFrame:CGRectMake(fieldOffset, l.frame.size.height * 0.5f - 11.0f, fieldWidth, v.frame.size.height) ] autorelease]; + tf.autoresizingMask = UIViewAutoresizingFlexibleWidth; + tf.borderStyle = UITextBorderStyleNone; + tf.placeholder = placeholder; + + tf.textColor = style.textColor; + tf.font = [UIFont systemFontOfSize:17.0f]; + + + switch (type) + { + case SHKLinkedInTextFieldPassword: + { + tf.secureTextEntry = true; + } + break; + + case SHKLinkedInTextFieldPlain: + { + } + break; + + default: + break; + + } + + [v addSubview:l]; + [v addSubview:tf]; + + [l release]; + + + [textField release]; + textField = [tf retain]; + + // set the field view + self.view = v; + +} + + + +-(BOOL)validate +{ + + if([textField.text length] < 1) + { + + NSString *fieldName = SHKLocalizedString(self.label); + NSString *message = SHKLocalizedString(@"You must provide text for this field in order to post."); + message = [NSString stringWithFormat:@"\"%@\": %@", fieldName, message]; + + [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Required Field") + message:message + delegate:nil + cancelButtonTitle:SHKLocalizedString(@"Close") + otherButtonTitles:nil] autorelease] show]; + + return false; + + } + + return true; + +} + + +-(void)setAsFirstResponder +{ + [textField becomeFirstResponder]; +} + + +-(id)value +{ + return textField.text; +} + +-(void)setValue:(id)value +{ + textField.text = (NSString*)value; +} + + + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.h b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.h new file mode 100644 index 00000000..fa2703ad --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.h @@ -0,0 +1,37 @@ +// +// SHKLinkedInURLField.h +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInTextField.h" + + +@interface SHKLinkedInURLField : SHKLinkedInTextField { + +} + +@end diff --git a/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.m b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.m new file mode 100644 index 00000000..1409cfaa --- /dev/null +++ b/Classes/ShareKit/Sharers/Services/LinkedIn/UI/SHKLinkedInURLField.m @@ -0,0 +1,62 @@ +// +// SHKLinkedInURLField.m +// ShareKit +// +// Created by Jim Spoto on 7/11/11. +// With permission from Dot Matrix, LLC. + +// +// 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 "SHKLinkedInURLField.h" + + +@implementation SHKLinkedInURLField + + +-(void)loadViewWithFrame:(CGRect)frame style:(SHKLinkedInFormStyle*)style +{ + + [super loadViewWithFrame:frame style:style]; + + textField.autocapitalizationType = UITextAutocapitalizationTypeNone; + textField.autocorrectionType = UITextAutocorrectionTypeNo; + textField.keyboardType = UIKeyboardTypeURL; + +} + + +-(id)value +{ + return [NSURL URLWithString:textField.text]; +} + + +-(void)setValue:(id)value +{ + NSString *url = [(NSURL*)value absoluteString]; + + textField.text = url; + +} + +@end diff --git a/RootViewController.xib b/RootViewController.xib index de9ed051..fb0c7e2c 100644 --- a/RootViewController.xib +++ b/RootViewController.xib @@ -2,17 +2,16 @@ 784 - 10D541 - 760 - 1038.29 - 460.00 + 10K540 + 844 + 1038.36 + 461.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 81 + 141 YES - YES @@ -38,10 +37,9 @@ IBCocoaTouchFramework - + 274 {320, 247} - 3 MQA @@ -49,6 +47,9 @@ NO YES NO + + 3 + IBCocoaTouchFramework NO 1 @@ -379,6 +380,6 @@ YES ShareKit.xcodeproj 3 - 81 + 141 diff --git a/ShareKit.xcodeproj/project.pbxproj b/ShareKit.xcodeproj/project.pbxproj index adcbf90e..c9506245 100755 --- a/ShareKit.xcodeproj/project.pbxproj +++ b/ShareKit.xcodeproj/project.pbxproj @@ -81,7 +81,6 @@ 43A5372D11DBE3B9004A1712 /* SHKPinboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536E311DBE3B9004A1712 /* SHKPinboard.m */; }; 43A5372E11DBE3B9004A1712 /* SHKReadItLater.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536E611DBE3B9004A1712 /* SHKReadItLater.m */; }; 43A5372F11DBE3B9004A1712 /* SHKTwitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536E911DBE3B9004A1712 /* SHKTwitter.m */; }; - 43A5373011DBE3B9004A1712 /* SHKTwitterForm.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536EB11DBE3B9004A1712 /* SHKTwitterForm.m */; }; 43A5373111DBE3B9004A1712 /* SHKActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536EF11DBE3B9004A1712 /* SHKActionSheet.m */; }; 43A5373211DBE3B9004A1712 /* SHKActivityIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536F111DBE3B9004A1712 /* SHKActivityIndicator.m */; }; 43A5373311DBE3B9004A1712 /* SHKFormController.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A536F311DBE3B9004A1712 /* SHKFormController.m */; }; @@ -106,6 +105,17 @@ 43D1DEF011D5CDD200550D75 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D1DEEF11D5CDD200550D75 /* SystemConfiguration.framework */; }; 43EF406E11D3FFF800B1F700 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43EF406D11D3FFF800B1F700 /* Security.framework */; }; 43FF9C7412270E9F00ADE53C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 43FF9C7212270E9F00ADE53C /* Localizable.strings */; }; + 694D231913B56B7C00BF0F4C /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 694D231813B56B7C00BF0F4C /* QuartzCore.framework */; }; + 699073AC13C6629E009E3524 /* SHKLinkedInField.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073A313C6629E009E3524 /* SHKLinkedInField.m */; }; + 699073AD13C6629E009E3524 /* SHKLinkedInForm.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073A513C6629E009E3524 /* SHKLinkedInForm.m */; }; + 699073AE13C6629E009E3524 /* SHKLinkedInFormStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073A713C6629E009E3524 /* SHKLinkedInFormStyle.m */; }; + 699073AF13C6629E009E3524 /* SHKLinkedInMultilineTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073A913C6629E009E3524 /* SHKLinkedInMultilineTextField.m */; }; + 699073B013C6629E009E3524 /* SHKLinkedInTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073AB13C6629E009E3524 /* SHKLinkedInTextField.m */; }; + 699073B913C7BB55009E3524 /* SHKLinkedInURLField.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073B813C7BB52009E3524 /* SHKLinkedInURLField.m */; }; + 699073C513C7BBE3009E3524 /* SHKItem+KVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073C213C7BBE3009E3524 /* SHKItem+KVC.m */; }; + 699073C613C7BBE3009E3524 /* UIWebView+SHKPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = 699073C413C7BBE3009E3524 /* UIWebView+SHKPlus.m */; }; + 6994F89E13B008C3005BC46B /* SHKLinkedIn.m in Sources */ = {isa = PBXBuildFile; fileRef = 6994F89D13B008C3005BC46B /* SHKLinkedIn.m */; }; + 69A0C3BF13B1C6120018837B /* SHKTwitterForm.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A0C3BE13B1C6120018837B /* SHKTwitterForm.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -264,8 +274,6 @@ 43A536E611DBE3B9004A1712 /* SHKReadItLater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKReadItLater.m; sourceTree = ""; }; 43A536E811DBE3B9004A1712 /* SHKTwitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTwitter.h; sourceTree = ""; }; 43A536E911DBE3B9004A1712 /* SHKTwitter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTwitter.m; sourceTree = ""; }; - 43A536EA11DBE3B9004A1712 /* SHKTwitterForm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTwitterForm.h; sourceTree = ""; }; - 43A536EB11DBE3B9004A1712 /* SHKTwitterForm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTwitterForm.m; sourceTree = ""; }; 43A536EC11DBE3B9004A1712 /* SHKConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKConfig.h; sourceTree = ""; }; 43A536EE11DBE3B9004A1712 /* SHKActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKActionSheet.h; sourceTree = ""; }; 43A536EF11DBE3B9004A1712 /* SHKActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKActionSheet.m; sourceTree = ""; }; @@ -310,6 +318,27 @@ 43EF406D11D3FFF800B1F700 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 43FF9C7312270E9F00ADE53C /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = Classes/ShareKit/Localization/en.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; }; 43FF9C7512270EB900ADE53C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Classes/ShareKit/Localization/de.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; }; + 694D231813B56B7C00BF0F4C /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 699073A213C6629E009E3524 /* SHKLinkedInField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedInField.h; path = LinkedIn/UI/SHKLinkedInField.h; sourceTree = ""; }; + 699073A313C6629E009E3524 /* SHKLinkedInField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedInField.m; path = LinkedIn/UI/SHKLinkedInField.m; sourceTree = ""; }; + 699073A413C6629E009E3524 /* SHKLinkedInForm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedInForm.h; path = LinkedIn/UI/SHKLinkedInForm.h; sourceTree = ""; }; + 699073A513C6629E009E3524 /* SHKLinkedInForm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedInForm.m; path = LinkedIn/UI/SHKLinkedInForm.m; sourceTree = ""; }; + 699073A613C6629E009E3524 /* SHKLinkedInFormStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedInFormStyle.h; path = LinkedIn/UI/SHKLinkedInFormStyle.h; sourceTree = ""; }; + 699073A713C6629E009E3524 /* SHKLinkedInFormStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedInFormStyle.m; path = LinkedIn/UI/SHKLinkedInFormStyle.m; sourceTree = ""; }; + 699073A813C6629E009E3524 /* SHKLinkedInMultilineTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedInMultilineTextField.h; path = LinkedIn/UI/SHKLinkedInMultilineTextField.h; sourceTree = ""; }; + 699073A913C6629E009E3524 /* SHKLinkedInMultilineTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedInMultilineTextField.m; path = LinkedIn/UI/SHKLinkedInMultilineTextField.m; sourceTree = ""; }; + 699073AA13C6629E009E3524 /* SHKLinkedInTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedInTextField.h; path = LinkedIn/UI/SHKLinkedInTextField.h; sourceTree = ""; }; + 699073AB13C6629E009E3524 /* SHKLinkedInTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedInTextField.m; path = LinkedIn/UI/SHKLinkedInTextField.m; sourceTree = ""; }; + 699073B713C7BB4E009E3524 /* SHKLinkedInURLField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedInURLField.h; path = LinkedIn/UI/SHKLinkedInURLField.h; sourceTree = ""; }; + 699073B813C7BB52009E3524 /* SHKLinkedInURLField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedInURLField.m; path = LinkedIn/UI/SHKLinkedInURLField.m; sourceTree = ""; }; + 699073C113C7BBE3009E3524 /* SHKItem+KVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SHKItem+KVC.h"; sourceTree = ""; }; + 699073C213C7BBE3009E3524 /* SHKItem+KVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SHKItem+KVC.m"; sourceTree = ""; }; + 699073C313C7BBE3009E3524 /* UIWebView+SHKPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIWebView+SHKPlus.h"; sourceTree = ""; }; + 699073C413C7BBE3009E3524 /* UIWebView+SHKPlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIWebView+SHKPlus.m"; sourceTree = ""; }; + 6994F89C13B008C3005BC46B /* SHKLinkedIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHKLinkedIn.h; path = LinkedIn/SHKLinkedIn.h; sourceTree = ""; }; + 6994F89D13B008C3005BC46B /* SHKLinkedIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHKLinkedIn.m; path = LinkedIn/SHKLinkedIn.m; sourceTree = ""; }; + 69A0C3BD13B1C6120018837B /* SHKTwitterForm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTwitterForm.h; sourceTree = ""; }; + 69A0C3BE13B1C6120018837B /* SHKTwitterForm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTwitterForm.m; sourceTree = ""; }; 8D1107310486CEB800E47090 /* ShareKit-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ShareKit-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -324,6 +353,7 @@ 4312CF7C11CB33E200E61D7A /* MessageUI.framework in Frameworks */, 43EF406E11D3FFF800B1F700 /* Security.framework in Frameworks */, 43D1DEF011D5CDD200550D75 /* SystemConfiguration.framework in Frameworks */, + 694D231913B56B7C00BF0F4C /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -384,6 +414,7 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( + 694D231813B56B7C00BF0F4C /* QuartzCore.framework */, 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 1D30AB110D05D00D00671497 /* Foundation.framework */, 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, @@ -725,6 +756,7 @@ 43A536C411DBE3B9004A1712 /* Facebook */, 43A536DE11DBE3B9004A1712 /* Google Reader */, 43150A8A11E78697008C6B68 /* Instapaper */, + 6994F89913B00767005BC46B /* LinkedIn */, 43A536E111DBE3B9004A1712 /* Pinboard */, 43A536E411DBE3B9004A1712 /* Read It Later */, 43C91DF211EBAE4800F31FAE /* Tumblr */, @@ -815,8 +847,8 @@ children = ( 43A536E811DBE3B9004A1712 /* SHKTwitter.h */, 43A536E911DBE3B9004A1712 /* SHKTwitter.m */, - 43A536EA11DBE3B9004A1712 /* SHKTwitterForm.h */, - 43A536EB11DBE3B9004A1712 /* SHKTwitterForm.m */, + 69A0C3BD13B1C6120018837B /* SHKTwitterForm.h */, + 69A0C3BE13B1C6120018837B /* SHKTwitterForm.m */, ); path = Twitter; sourceTree = ""; @@ -830,10 +862,10 @@ 43A536F111DBE3B9004A1712 /* SHKActivityIndicator.m */, 43A536F211DBE3B9004A1712 /* SHKFormController.h */, 43A536F311DBE3B9004A1712 /* SHKFormController.m */, - 43A536F411DBE3B9004A1712 /* SHKFormFieldCell.h */, - 43A536F511DBE3B9004A1712 /* SHKFormFieldCell.m */, 43A536F611DBE3B9004A1712 /* SHKFormFieldSettings.h */, 43A536F711DBE3B9004A1712 /* SHKFormFieldSettings.m */, + 43A536F411DBE3B9004A1712 /* SHKFormFieldCell.h */, + 43A536F511DBE3B9004A1712 /* SHKFormFieldCell.m */, 43A536FC11DBE3B9004A1712 /* SHKShareMenu.h */, 43A536FD11DBE3B9004A1712 /* SHKShareMenu.m */, 43A536FA11DBE3B9004A1712 /* SHKOAuthView.h */, @@ -891,6 +923,48 @@ name = Localization; sourceTree = ""; }; + 6990734113C507AD009E3524 /* UI */ = { + isa = PBXGroup; + children = ( + 699073A413C6629E009E3524 /* SHKLinkedInForm.h */, + 699073A513C6629E009E3524 /* SHKLinkedInForm.m */, + 699073A613C6629E009E3524 /* SHKLinkedInFormStyle.h */, + 699073A713C6629E009E3524 /* SHKLinkedInFormStyle.m */, + 699073A213C6629E009E3524 /* SHKLinkedInField.h */, + 699073A313C6629E009E3524 /* SHKLinkedInField.m */, + 699073B713C7BB4E009E3524 /* SHKLinkedInURLField.h */, + 699073B813C7BB52009E3524 /* SHKLinkedInURLField.m */, + 699073AA13C6629E009E3524 /* SHKLinkedInTextField.h */, + 699073AB13C6629E009E3524 /* SHKLinkedInTextField.m */, + 699073A813C6629E009E3524 /* SHKLinkedInMultilineTextField.h */, + 699073A913C6629E009E3524 /* SHKLinkedInMultilineTextField.m */, + ); + name = UI; + sourceTree = ""; + }; + 699073C013C7BBC1009E3524 /* Categories */ = { + isa = PBXGroup; + children = ( + 699073C113C7BBE3009E3524 /* SHKItem+KVC.h */, + 699073C213C7BBE3009E3524 /* SHKItem+KVC.m */, + 699073C313C7BBE3009E3524 /* UIWebView+SHKPlus.h */, + 699073C413C7BBE3009E3524 /* UIWebView+SHKPlus.m */, + ); + name = Categories; + path = LinkedIn/Categories; + sourceTree = ""; + }; + 6994F89913B00767005BC46B /* LinkedIn */ = { + isa = PBXGroup; + children = ( + 699073C013C7BBC1009E3524 /* Categories */, + 6990734113C507AD009E3524 /* UI */, + 6994F89C13B008C3005BC46B /* SHKLinkedIn.h */, + 6994F89D13B008C3005BC46B /* SHKLinkedIn.m */, + ); + name = LinkedIn; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1014,7 +1088,6 @@ 43A5372D11DBE3B9004A1712 /* SHKPinboard.m in Sources */, 43A5372E11DBE3B9004A1712 /* SHKReadItLater.m in Sources */, 43A5372F11DBE3B9004A1712 /* SHKTwitter.m in Sources */, - 43A5373011DBE3B9004A1712 /* SHKTwitterForm.m in Sources */, 43A5373111DBE3B9004A1712 /* SHKActionSheet.m in Sources */, 43A5373211DBE3B9004A1712 /* SHKActivityIndicator.m in Sources */, 43A5373311DBE3B9004A1712 /* SHKFormController.m in Sources */, @@ -1052,6 +1125,16 @@ 4379F2C11291AC9700D2A41E /* SHKEvernote.m in Sources */, 4379F2EA1291AE5700D2A41E /* NSData+md5.m in Sources */, 4379F3B21291C45700D2A41E /* SHKTextMessage.m in Sources */, + 6994F89E13B008C3005BC46B /* SHKLinkedIn.m in Sources */, + 69A0C3BF13B1C6120018837B /* SHKTwitterForm.m in Sources */, + 699073AC13C6629E009E3524 /* SHKLinkedInField.m in Sources */, + 699073AD13C6629E009E3524 /* SHKLinkedInForm.m in Sources */, + 699073AE13C6629E009E3524 /* SHKLinkedInFormStyle.m in Sources */, + 699073AF13C6629E009E3524 /* SHKLinkedInMultilineTextField.m in Sources */, + 699073B013C6629E009E3524 /* SHKLinkedInTextField.m in Sources */, + 699073B913C7BB55009E3524 /* SHKLinkedInURLField.m in Sources */, + 699073C513C7BBE3009E3524 /* SHKItem+KVC.m in Sources */, + 699073C613C7BBE3009E3524 /* UIWebView+SHKPlus.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1083,6 +1166,10 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + ); GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -1101,6 +1188,10 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ShareKit_Prefix.pch; INFOPLIST_FILE = "ShareKit-Info.plist";