|
Nimbus
0.9.3 - Nimbus is proudly hosted on Github
An iOS framework whose growth is bounded by O(documentation).
|
00001 // 00002 // Copyright 2011 Jeff Verkoeyen 00003 // 00004 // Licensed under the Apache License, Version 2.0 (the "License"); 00005 // you may not use this file except in compliance with the License. 00006 // You may obtain a copy of the License at 00007 // 00008 // http://www.apache.org/licenses/LICENSE-2.0 00009 // 00010 // Unless required by applicable law or agreed to in writing, software 00011 // distributed under the License is distributed on an "AS IS" BASIS, 00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 // See the License for the specific language governing permissions and 00014 // limitations under the License. 00015 // 00016 00017 #import "NIInterapp.h" 00018 00019 #import "NimbusCore+Additions.h" 00020 00021 00025 @implementation NIInterapp 00026 00027 00029 + (NSString *)sanitizedPhoneNumberFromString:(NSString *)string { 00030 if (nil == string) { 00031 return nil; 00032 } 00033 00034 NSCharacterSet* validCharacters = 00035 [NSCharacterSet characterSetWithCharactersInString:@"1234567890-+"]; 00036 return [[string componentsSeparatedByCharactersInSet:[validCharacters invertedSet]] 00037 componentsJoinedByString:@""]; 00038 00039 } 00040 00041 00044 #pragma mark - 00045 #pragma mark Safari 00046 00047 00049 + (BOOL)safariWithURL:(NSURL *)url { 00050 return [[UIApplication sharedApplication] openURL:url]; 00051 } 00052 00053 00056 #pragma mark - 00057 #pragma mark Google Maps 00058 00064 00065 + (BOOL)googleMapAtLocation:(CLLocationCoordinate2D)location { 00066 NSString* urlPath = [NSString stringWithFormat: 00067 @"http://maps.google.com/maps?q=%f,%f", 00068 location.latitude, location.longitude]; 00069 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00070 } 00071 00072 00074 + (BOOL)googleMapAtLocation: (CLLocationCoordinate2D)location 00075 title: (NSString *)title { 00076 NSString* urlPath = [NSString stringWithFormat: 00077 @"http://maps.google.com/maps?q=%@@%f,%f", 00078 [title stringByAddingPercentEscapesForURLParameter], location.latitude, location.longitude]; 00079 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00080 } 00081 00082 00084 + (BOOL)googleMapDirectionsFromLocation: (CLLocationCoordinate2D)fromLocation 00085 toLocation: (CLLocationCoordinate2D)toLocation { 00086 NSString* urlPath = [NSString stringWithFormat: 00087 @"http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f", 00088 fromLocation.latitude, fromLocation.longitude, 00089 toLocation.latitude, toLocation.longitude]; 00090 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00091 } 00092 00093 00095 + (BOOL)googleMapWithQuery:(NSString *)query { 00096 NSString* urlPath = [NSString stringWithFormat: 00097 @"http://maps.google.com/maps?q=%@", 00098 [query stringByAddingPercentEscapesForURLParameter]]; 00099 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00100 } 00101 00102 00105 #pragma mark - 00106 #pragma mark Phone 00107 00108 00110 + (BOOL)phone { 00111 return [self phoneWithNumber:nil]; 00112 } 00113 00114 00116 + (BOOL)phoneWithNumber:(NSString *)phoneNumber { 00117 phoneNumber = [self sanitizedPhoneNumberFromString:phoneNumber]; 00118 00119 if (nil == phoneNumber) { 00120 phoneNumber = @""; 00121 } 00122 00123 NSString* urlPath = [@"tel:" stringByAppendingString:phoneNumber]; 00124 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00125 } 00126 00127 00130 #pragma mark - 00131 #pragma mark Texting 00132 00133 00135 + (BOOL)sms { 00136 return [self smsWithNumber:nil]; 00137 } 00138 00139 00141 + (BOOL)smsWithNumber:(NSString *)phoneNumber { 00142 phoneNumber = [self sanitizedPhoneNumberFromString:phoneNumber]; 00143 00144 if (nil == phoneNumber) { 00145 phoneNumber = @""; 00146 } 00147 00148 NSString* urlPath = [@"sms:" stringByAppendingString:phoneNumber]; 00149 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00150 } 00151 00152 00155 #pragma mark - 00156 #pragma mark Mail 00157 00158 static NSString* const sMailScheme = @"mailto:"; 00159 00160 00162 + (BOOL)mailWithInvocation:(NIMailAppInvocation *)invocation { 00163 NSMutableDictionary* parameters = [NSMutableDictionary dictionary]; 00164 00165 NSString* urlPath = sMailScheme; 00166 00167 if (NIIsStringWithAnyText(invocation.recipient)) { 00168 urlPath = [urlPath stringByAppendingString:[invocation.recipient stringByAddingPercentEscapesForURLParameter]]; 00169 } 00170 00171 if (NIIsStringWithAnyText(invocation.cc)) { 00172 [parameters setObject:invocation.cc forKey:@"cc"]; 00173 } 00174 if (NIIsStringWithAnyText(invocation.bcc)) { 00175 [parameters setObject:invocation.bcc forKey:@"bcc"]; 00176 } 00177 if (NIIsStringWithAnyText(invocation.subject)) { 00178 [parameters setObject:invocation.subject forKey:@"subject"]; 00179 } 00180 if (NIIsStringWithAnyText(invocation.body)) { 00181 [parameters setObject:invocation.body forKey:@"body"]; 00182 } 00183 00184 urlPath = [urlPath stringByAddingQueryDictionary:parameters]; 00185 00186 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00187 } 00188 00189 00192 #pragma mark - 00193 #pragma mark YouTube 00194 00195 00197 + (BOOL)youTubeWithVideoId:(NSString *)videoId { 00198 NSString* urlPath = [@"http://www.youtube.com/watch?v=" stringByAppendingString:videoId]; 00199 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00200 } 00201 00202 00205 #pragma mark - 00206 #pragma mark iBooks 00207 00208 static NSString* const sIBooksScheme = @"itms-books:"; 00209 00210 00212 + (BOOL)iBooksIsInstalled { 00213 return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sIBooksScheme]]; 00214 } 00215 00216 00218 + (BOOL)iBooks { 00219 BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sIBooksScheme]]; 00220 00221 if (!didOpen) { 00222 didOpen = [self appStoreWithAppId:[self iBooksAppStoreId]]; 00223 } 00224 00225 return didOpen; 00226 } 00227 00228 00230 + (NSString *)iBooksAppStoreId { 00231 return @"364709193"; 00232 } 00233 00234 00237 #pragma mark - 00238 #pragma mark Facebook 00239 00240 static NSString* const sFacebookScheme = @"fb:"; 00241 00242 00244 + (BOOL)facebookIsInstalled { 00245 return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sFacebookScheme]]; 00246 } 00247 00248 00250 + (BOOL)facebook { 00251 BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sFacebookScheme]]; 00252 00253 if (!didOpen) { 00254 didOpen = [self appStoreWithAppId:[self facebookAppStoreId]]; 00255 } 00256 00257 return didOpen; 00258 } 00259 00260 00262 + (BOOL)facebookProfileWithId:(NSString *)profileId { 00263 NSString* urlPath = [sFacebookScheme stringByAppendingFormat:@"//profile/%@", profileId]; 00264 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00265 } 00266 00267 00269 + (NSString *)facebookAppStoreId { 00270 return @"284882215"; 00271 } 00272 00273 00276 #pragma mark - 00277 #pragma mark Twitter 00278 00279 static NSString* const sTwitterScheme = @"twitter:"; 00280 00281 00283 + (BOOL)twitterIsInstalled { 00284 return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sTwitterScheme]]; 00285 } 00286 00287 00289 + (BOOL)twitter { 00290 BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sTwitterScheme]]; 00291 00292 if (!didOpen) { 00293 didOpen = [self appStoreWithAppId:[self twitterAppStoreId]]; 00294 } 00295 00296 return didOpen; 00297 } 00298 00299 00301 + (BOOL)twitterWithMessage:(NSString *)message { 00302 NSString* urlPath = [sTwitterScheme stringByAppendingFormat:@"//post?message=%@", 00303 [message stringByAddingPercentEscapesForURLParameter]]; 00304 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00305 } 00306 00307 00309 + (BOOL)twitterProfileForUsername:(NSString *)username { 00310 NSString* urlPath = [sTwitterScheme stringByAppendingFormat:@"//user?screen_name=%@", 00311 [username stringByAddingPercentEscapesForURLParameter]]; 00312 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00313 } 00314 00315 00317 + (NSString *)twitterAppStoreId { 00318 return @"333903271"; 00319 } 00320 00321 00324 #pragma mark - 00325 #pragma mark Application 00326 00327 //static NSString* const sTwitterScheme = @"twitter:"; 00328 00329 00331 + (BOOL)applicationIsInstalledWithScheme:(NSString *)applicationScheme { 00332 return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:applicationScheme]]; 00333 } 00334 00335 00337 + (BOOL)applicationWithScheme:(NSString *)applicationScheme { 00338 return [self applicationWithScheme:applicationScheme 00339 appStoreId:nil 00340 andPath:nil]; 00341 } 00342 00343 00345 + (BOOL)applicationWithScheme:(NSString *)applicationScheme 00346 andAppStoreId:(NSString *)appStoreId { 00347 return [self applicationWithScheme:applicationScheme 00348 appStoreId:appStoreId 00349 andPath:nil]; 00350 } 00351 00352 00354 + (BOOL)applicationWithScheme:(NSString *)applicationScheme 00355 andPath:(NSString *)path { 00356 return [self applicationWithScheme:applicationScheme 00357 appStoreId:nil 00358 andPath:path]; 00359 } 00360 00361 00363 + (BOOL)applicationWithScheme:(NSString *)applicationScheme 00364 appStoreId:(NSString *)appStoreId 00365 andPath:(NSString *)path { 00366 BOOL didOpen = false; 00367 NSString* urlPath = applicationScheme; 00368 00369 // Were we passed a path? 00370 if (path != nil) { 00371 // Generate the full application URL 00372 urlPath = [urlPath stringByAppendingFormat:@"%@", path]; 00373 } 00374 00375 // Try to open the application URL 00376 didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00377 00378 // Didn't open and we have an appStoreId 00379 if (!didOpen && appStoreId != nil) { 00380 // Open the app store instead 00381 didOpen = [self appStoreWithAppId:appStoreId]; 00382 } 00383 00384 return didOpen; 00385 } 00386 00387 00390 #pragma mark - 00391 #pragma mark Instagram 00392 00393 static NSString* const sInstagramScheme = @"instagram:"; 00394 00395 00397 + (BOOL)instagramIsInstalled { 00398 return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sInstagramScheme]]; 00399 } 00400 00401 00403 + (BOOL)instagram { 00404 BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sInstagramScheme]]; 00405 00406 if (!didOpen) { 00407 didOpen = [self appStoreWithAppId:[self instagramAppStoreId]]; 00408 } 00409 00410 return didOpen; 00411 } 00412 00413 00415 + (BOOL)instagramCamera { 00416 NSString* urlPath = [sInstagramScheme stringByAppendingString:@"//camera"]; 00417 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00418 } 00419 00420 00422 + (BOOL)instagramProfileForUsername:(NSString *)username { 00423 NSString* urlPath = [sInstagramScheme stringByAppendingFormat:@"//user?username=%@", 00424 [username stringByAddingPercentEscapesForURLParameter]]; 00425 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00426 } 00427 00428 00430 + (NSURL *)urlForInstagramImageAtFilePath:(NSString *)filePath error:(NSError **)error { 00431 UIImage* image = [[UIImage alloc] initWithContentsOfFile:filePath]; 00432 00433 // Unable to read the image. 00434 if (nil == image) { 00435 if (nil != error) { 00436 *error = [NSError errorWithDomain: NSCocoaErrorDomain 00437 code: NSFileReadUnknownError 00438 userInfo: [NSDictionary dictionaryWithObject: filePath 00439 forKey: NSFilePathErrorKey]]; 00440 } 00441 return nil; 00442 } 00443 00444 // Instagram requires that images are at least 612x612 and preferably square. 00445 if (image.size.width < 612 00446 || image.size.height < 612) { 00447 if (nil != error) { 00448 *error = [NSError errorWithDomain: NINimbusErrorDomain 00449 code: NIImageTooSmall 00450 userInfo: [NSDictionary dictionaryWithObject: image 00451 forKey: NIImageErrorKey]]; 00452 } 00453 NI_RELEASE_SAFELY(image); 00454 return nil; 00455 } 00456 00457 // Immediately remove the image from memory. 00458 NI_RELEASE_SAFELY(image); 00459 00460 NSFileManager* fm = [NSFileManager defaultManager]; 00461 NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 00462 00463 NIDASSERT(NIIsArrayWithObjects(paths)); 00464 if (!NIIsArrayWithObjects(paths)) { 00465 return nil; 00466 } 00467 00468 NSString* documentsPath = [paths objectAtIndex:0]; 00469 NSString* destinationPath = [documentsPath stringByAppendingPathComponent: 00470 [NSString stringWithFormat:@"nimbus-instagram-image-%.0f.ig", 00471 [NSDate timeIntervalSinceReferenceDate]]]; 00472 00473 [fm copyItemAtPath: filePath 00474 toPath: destinationPath 00475 error: error]; 00476 00477 NIDASSERT(nil == error || nil == *error); 00478 if (nil == error || nil == *error) { 00479 return [NSURL URLWithString:[@"file:" stringByAppendingString:destinationPath]]; 00480 00481 } else { 00482 return nil; 00483 } 00484 } 00485 00486 00488 + (NSString *)instagramAppStoreId { 00489 return @"389801252"; 00490 } 00491 00492 00495 #pragma mark - 00496 #pragma mark App Store 00497 00498 00500 + (BOOL)appStoreWithAppId:(NSString *)appId { 00501 NSString* urlPath = [@"http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=" stringByAppendingString:appId]; 00502 return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]]; 00503 } 00504 00505 00506 @end 00507 00508 00512 @implementation NIMailAppInvocation 00513 00514 @synthesize recipient = _recipient; 00515 @synthesize cc = _cc; 00516 @synthesize bcc = _bcc; 00517 @synthesize subject = _subject; 00518 @synthesize body = _body; 00519 00520 00522 - (void)dealloc { 00523 NI_RELEASE_SAFELY(_recipient); 00524 NI_RELEASE_SAFELY(_cc); 00525 NI_RELEASE_SAFELY(_bcc); 00526 NI_RELEASE_SAFELY(_subject); 00527 NI_RELEASE_SAFELY(_body); 00528 00529 [super dealloc]; 00530 } 00531 00532 00534 + (id)invocation { 00535 return [[[[self class] alloc] init] autorelease]; 00536 } 00537 00538 00539 @end