PageRenderTime 112ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/EXPikchur.m

http://exportkit-cocoa.googlecode.com/
Objective C | 339 lines | 242 code | 88 blank | 9 comment | 42 complexity | ce1479bd6d9183988528254c2706699d MD5 | raw file
  1. //
  2. // EXPikchur.m
  3. // ExportKit-Demo
  4. //
  5. // Created by Shane Gianelli on 5/28/10.
  6. // Copyright 2010 SJ Development LLC. All rights reserved.
  7. //
  8. #import "EXPikchur.h"
  9. #define kCacheDirectory(x) [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:x]
  10. @interface EXPikchur (private)
  11. - (void)addString:(NSString *)str forAPI:(NSString *)api toData:(NSMutableData *)data;
  12. - (void)parseXMLFileWithData:(NSData *)xml;
  13. @end
  14. @implementation EXPikchur
  15. @synthesize delegate,userName,service;
  16. - (id)initWithUsername:(NSString *)user andPassword:(NSString *)pass forService:(EXPikchurServices)serv {
  17. if (user == nil || pass == nil || serv == 0)
  18. return nil;
  19. if (self = [super init]) {
  20. switch (serv) {
  21. case EXPikchurServicesTwitter: service = [[NSString alloc] initWithString:@"twitter"]; break;
  22. case EXPikchurServicesPosterous: service = [[NSString alloc] initWithString:@"posterous"]; break;
  23. case EXPikchurServicesFourSquare: service = [[NSString alloc] initWithString:@"fourSquare"]; break;
  24. case EXPikchurServicesJaiku: service = [[NSString alloc] initWithString:@"jaiku"]; break;
  25. case EXPikchurServicesTumblr: service = [[NSString alloc] initWithString:@"tumblr"]; break;
  26. case EXPikchurServicesFriendFeed: service = [[NSString alloc] initWithString:@"friendfeed"]; break;
  27. case EXPikchurServicesIdentica: service = [[NSString alloc] initWithString:@"identi.ca"]; break;
  28. case EXPikchurServicesPlurk: service = [[NSString alloc] initWithString:@"plurk"]; break;
  29. case EXPikchurServicesKoornk: service = [[NSString alloc] initWithString:@"koornk"]; break;
  30. case EXPikchurServicesBrightKite: service = [[NSString alloc] initWithString:@"brightkite"]; break;
  31. case EXPikchurServicesPikchur: service = [[NSString alloc] initWithString:@"pikchur"]; break;
  32. default: break;
  33. }
  34. NSLog(@"service: %d string: %@",serv,service);
  35. authToken = nil;
  36. userName = [user copy];
  37. currentUploads = [[NSMutableArray alloc] init];
  38. [self performSelectorInBackground:@selector(authenticateWithPassword:) withObject:pass];
  39. }
  40. return self;
  41. }
  42. - (void)authenticateWithPassword:(NSString *)pw {
  43. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  44. NSURL *url = [NSURL URLWithString:@"https://api.pikchur.com/auth/xml"];
  45. NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
  46. [postRequest setHTTPMethod:@"POST"];
  47. NSString *stringBoundary = @"sjdevsmostwonderfulofboundrylinesforexportkitTHANKYOUFORUSING";
  48. NSString *headerBoundary = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
  49. [postRequest addValue:headerBoundary forHTTPHeaderField:@"Content-Type"];
  50. NSMutableData *postBody = [NSMutableData data];
  51. [self addString:userName forAPI:@"data[api][username]" toData:postBody];
  52. [self addString:pw forAPI:@"data[api][password]" toData:postBody];
  53. [self addString:kPikchurAPIKey forAPI:@"data[api][key]" toData:postBody];
  54. [self addString:service forAPI:@"data[api][service]" toData:postBody];
  55. [postRequest setHTTPBody:postBody];
  56. NSData *connectionResponse = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:nil error:nil];
  57. if (connectionResponse != nil) {
  58. parseKeys = [[NSArray alloc] initWithObjects:@"auth_key",@"user_id",@"message",@"error",nil];
  59. [self parseXMLFileWithData:connectionResponse];
  60. }
  61. [pool drain];
  62. }
  63. - (void)uploadPikchurData:(EXPikchurData *)data {
  64. [self performSelectorInBackground:@selector(uploadData:) withObject:data];
  65. }
  66. - (void)uploadData:(EXPikchurData *)data {
  67. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  68. if (authToken == nil || data.media == nil || data.statusMessage == nil) {
  69. if (delegate)
  70. [delegate pikchur:self failedToUploadData:data withError:[NSError errorWithDomain:@"auth, media, or status message nil" code:0 userInfo:nil]];
  71. [pool drain];
  72. return;
  73. }
  74. NSString *mediaType;
  75. switch (data.mediaType) {
  76. case EXMediaTypePNG:
  77. mediaType = @"image/png";
  78. break;
  79. case EXMediaTypeJPEG:
  80. mediaType = @"image/jpeg";
  81. break;
  82. case EXMediaTypeGIF:
  83. mediaType = @"image/gif";
  84. break;
  85. case EXMediaTypeMP4:
  86. mediaType = @"video/mp4";
  87. break;
  88. default:
  89. break;
  90. }
  91. NSURL *url = [NSURL URLWithString:@"http://api.pikchur.com/post/xml"];
  92. NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
  93. [postRequest setHTTPMethod:@"POST"];
  94. NSString *stringBoundary = @"sjdevsmostwonderfulofboundrylinesforexportkitTHANKYOUFORUSING";
  95. NSString *headerBoundary = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
  96. [postRequest addValue:headerBoundary forHTTPHeaderField:@"Content-Type"];
  97. NSMutableData *postBody = [NSMutableData data];
  98. [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
  99. [postBody appendData:[@"Content-Disposition: form-data; name=\"dataAPIimage\"; filename=\"vid.mp4\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
  100. [postBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n",mediaType] dataUsingEncoding:NSUTF8StringEncoding]];
  101. [postBody appendData:[@"Content-Transfer-Encoding: binary\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
  102. [postBody appendData:data.media];
  103. [postBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
  104. [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
  105. //required parameters
  106. [self addString:authToken forAPI:@"data[api][auth_key]" toData:postBody];
  107. [self addString:data.statusMessage forAPI:@"data[api][status]" toData:postBody];
  108. [self addString:kPikchurAPIKey forAPI:@"data[api][key]" toData:postBody];
  109. //optional parameters
  110. if (data.geoLocation) {
  111. [self addString:[NSString stringWithFormat:@"%f",data.geoLocation.coordinate.latitude] forAPI:@"data[api][geo][lat]" toData:postBody];
  112. [self addString:[NSString stringWithFormat:@"%f",data.geoLocation.coordinate.longitude] forAPI:@"data[api][geo][lon]" toData:postBody];
  113. }
  114. if (data.generalLocation) [self addString:data.generalLocation forAPI:@"data[api][geo][location]" toData:postBody];
  115. if (data.privateUpload) [self addString:@"YES" forAPI:@"data[api][private]" toData:postBody];
  116. else [self addString:@"NO" forAPI:@"data[api][private]" toData:postBody];
  117. if (data.shouldPost) [self addString:@"YES" forAPI:@"data[api][upload_only]" toData:postBody];
  118. else [self addString:@"NO" forAPI:@"data[api][upload_only]" toData:postBody];
  119. [postRequest setHTTPBody:postBody];
  120. NSArray *keys = [[NSArray alloc] initWithObjects:@"id",
  121. @"note",
  122. @"url",
  123. @"status",
  124. @"type",nil];
  125. UploadManager *man = [[UploadManager alloc] initWithParserKeys:keys andDelegate:self];
  126. [currentUploads addObjectsFromArray:[NSArray arrayWithObjects:man,data,nil]];
  127. [man performSelectorOnMainThread:@selector(beginConnectionWithRequest:) withObject:postRequest waitUntilDone:NO];
  128. [keys release];
  129. [pool drain];
  130. }
  131. - (void)addString:(NSString *)str forAPI:(NSString *)api toData:(NSMutableData *)data {
  132. NSString *stringBoundary = @"sjdevsmostwonderfulofboundrylinesforexportkitTHANKYOUFORUSING";
  133. [data appendData:[[NSString stringWithFormat:@"--%@\r\n", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
  134. [data appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",api] dataUsingEncoding:NSUTF8StringEncoding]];
  135. [data appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
  136. [data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
  137. }
  138. - (void)uploadCompleted:(UploadManager *)manager {
  139. }
  140. - (void)uploadFailed:(UploadManager *)manager withError:(NSError *)err {
  141. if (delegate)
  142. [delegate pikchurFailedToAuthenticate:self withErrorMessage:err];
  143. [currentUploads removeObjectAtIndex:[currentUploads indexOfObject:manager] + 1];
  144. [currentUploads removeObjectAtIndex:[currentUploads indexOfObject:manager]];
  145. if (delegate && [currentUploads count] == 0)
  146. [delegate pikchurCompletedAllUploads:self];
  147. }
  148. - (void)upload:(UploadManager *)manager receivedBytes:(NSInteger)bytes ofTotal:(NSInteger)total {
  149. if ([(NSObject *)delegate respondsToSelector:@selector(pikchur:forData:receivedBytes:ofTotal:)])
  150. [delegate pikchur:self forData:[currentUploads objectAtIndex:[currentUploads indexOfObject:manager] + 1] receivedBytes:bytes ofTotal:total];
  151. }
  152. - (void)upload:(UploadManager *)manager receivedResponse:(NSDictionary *)response {
  153. if (delegate && [currentUploads count] == 0)
  154. [delegate pikchurCompletedAllUploads:self];
  155. [currentUploads removeObjectAtIndex:[currentUploads indexOfObject:manager] + 1];
  156. [currentUploads removeObjectAtIndex:[currentUploads indexOfObject:manager]];
  157. }
  158. - (NSData *)upload:(UploadManager *)manager receivedData:(NSData *)data {
  159. NSString *response = [NSString stringWithCString:[data bytes] length:[data length]];
  160. response = [response substringFromIndex:[response rangeOfString:@"<?xml"].location];
  161. return [response dataUsingEncoding:NSUTF8StringEncoding];
  162. }
  163. + (UIImage *)thumbnailForMediaID:(NSString *)mediaid isVideo:(BOOL)vid {
  164. UIImage *returnImage = nil;
  165. NSURL *url;
  166. if (vid)
  167. url = [NSURL URLWithString:[NSString stringWithFormat:@"http://vid.pikchur.com/vid_%@_t.jpg",mediaid]]; //changing the t at the end to s,m, or l will produce other sizes of images
  168. else
  169. url = [NSURL URLWithString:[NSString stringWithFormat:@"http://img.pikchur.com/pic_%@_t.jpg",mediaid]];
  170. NSURLResponse *response = nil;
  171. NSError *error = nil;
  172. NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
  173. NSData *connectionResponse = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
  174. if (error)
  175. return nil;
  176. if (connectionResponse)
  177. returnImage = [UIImage imageWithData:connectionResponse];
  178. return returnImage;
  179. }
  180. - (void)parseXMLFileWithData:(NSData *)xml {
  181. parsedContent = [[NSMutableDictionary alloc] init];
  182. NSXMLParser *xmlParser = [[[NSXMLParser alloc] initWithData:xml] autorelease];
  183. [xmlParser setDelegate:self];
  184. [xmlParser setShouldProcessNamespaces:NO];
  185. [xmlParser setShouldReportNamespacePrefixes:NO];
  186. [xmlParser setShouldResolveExternalEntities:NO];
  187. [xmlParser parse];
  188. }
  189. - (void)parserDidStartDocument:(NSXMLParser *)parser {
  190. }
  191. - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
  192. [parsedContent release];
  193. }
  194. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
  195. currentElement = [elementName copy];
  196. }
  197. - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
  198. currentElement = nil;
  199. }
  200. - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
  201. if ([parseKeys containsObject:currentElement])
  202. [parsedContent setObject:string forKey:currentElement];
  203. }
  204. - (void)parserDidEndDocument:(NSXMLParser *)parser {
  205. if ([parsedContent objectForKey:@"auth_key"]) {
  206. authToken = [(NSString *)[parsedContent objectForKey:@"auth_key"] copy];
  207. if (delegate)
  208. [delegate pikchurDidAuthenticate:self];
  209. } else if (delegate)
  210. [delegate pikchurFailedToAuthenticate:self withErrorMessage:[NSError errorWithDomain:[parsedContent objectForKey:@"message"] code:0 userInfo:nil]];
  211. if (parsedContent)
  212. [parsedContent release];
  213. if (currentElement)
  214. [currentElement release];
  215. [parseKeys release];
  216. }
  217. - (void)dealloc {
  218. [super dealloc];
  219. self.delegate = nil;
  220. [userName release];
  221. [authToken release];
  222. [service release];
  223. [currentUploads release];
  224. [currentElement release];
  225. [parseKeys release];
  226. [parsedContent release];
  227. }
  228. @end
  229. @implementation EXPikchurData
  230. @synthesize media,mediaType,statusMessage,generalLocation,privateUpload,shouldPost,geoLocation;
  231. - (id)initWithMedia:(NSData *)data ofType:(EXMediaType)type andMessage:(NSString *)message {
  232. if (self = [self init]) {
  233. self.media = [data copy];
  234. self.mediaType = type;
  235. self.statusMessage = [message copy];
  236. }
  237. return self;
  238. }
  239. - (id)init {
  240. if (self = [super init]) {
  241. self.media = nil;
  242. self.mediaType = 0;
  243. self.statusMessage = nil;
  244. self.generalLocation = nil;
  245. self.privateUpload = NO;
  246. self.shouldPost = YES;
  247. self.geoLocation = nil;
  248. }
  249. return self;
  250. }
  251. @end