定义打开URL的方法
- (void)openURL:(NSString *)urlStr {
NSURL *url = [NSURL URLWithString:urlStr];
UIApplication *app = [UIApplication sharedApplication];
if ([app canOpenURL:url]) {
#ifdef __IPHONE_10_0
[app openURL:url options:[NSDictionary dictionary] completionHandler:nil];
#else
[app openURL:url];
#endif
}
}
调用方法为:
NSString *url = @"xxxxxx";
[xx openURL:url];
1.打开email
NSString *url = [NSString stringWithFormat:@"mailto://[email protected]"];
2.打开appstore 某应用的主页
NSString *appID = @"xxxxxxx";
NSString *url = [NSString stringWithFormat:@"https://itunes.apple.com/cn/app/id%@?mt=8", appID];
3.打电话
NSString *url = @"tel://8008808888";
4.调用 SMS
NSString *url = @"sms://800888";
5.自带safari打开网页
NSString *url = @"https://www.baidu.com";
6. 代开Remote
NSString *url = @"remote://xxx";
7.app之间拉起调用
1)在被调用app的plist文件中,注册对外接口
在TARGETS --> Info找到URL Types,然后展开URL types,增加一项,URLSchemes为:myapp,这个myapp就是对外接口,其它应用可以通过它
2)调用app方法
NSString *url = @"myapp:";
通过上述两个步骤,你可以在你的应用中,让用户打开你的其它应用。如果加参数的话,最好写成"myapp://login?account=xxx&password=123456",就好比http请求的“http”换成“myapp”.
3)处理URL请求
应用程序委托在application:handleOpenURL:方法中处理传递给应用程序的URL请求。如果您已经为自己的应用程序注册了定制的URL模式,则务必在委托中实现这个方法。
application:handleOpenURL:方法实现 中,传入的URL对象在其请求和片断部分带有具体应用程序的信息。
- (BOOL)application: (UIApplication * )application handleOpenURL: (NSURL *)url {
if ([[url scheme] isEqualToString:@"myapp"]) {
//处理链接
return YES;
}
return NO;
}
第二种处理URL请求方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//被其他应用调用
NSURL *url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
if(url) {//做出相应的判断
if ([[url scheme] isEqualToString:@"myapp"]) {
//处理链接
}
}
return YES;
}
说明:iOS 程序启动时总会调用application:didFinishLaunchingWithOptions:,其中第二个参数launchOptions为NSDictionary类型的对象,里面存储有此程序启动的原因。
4).快速测试外部调用
1.回到Home屏幕,启动Safari(在iPhone仿真器上,在菜单上选择Hardware->Home命令就可以回到Home屏幕)。
2.在Safari的地址栏中,键入使用定制模式的URL,即“myapp:”,加参数的话则为“myapp://........”
3.确认您的应用程序是否启动,以及应用程序委托是否收到application:handleOpenURL:消息。
8. H5拉起调用app
[Mobile Safari 调用本地APP,否则进入App Store下载]
1.window.location连接的指向为打开应用
2.延时打开App Store下载应用页面
具体来说:
当你打开链接时,Mobile Safari通过window.location指向URL Scheme,直接打开本地应用,否则30ms后打开下载页面。如果应用成功打开,生命周期就是激活状态,那么浏览器的状态是进入后台,页面里的所有操作都被注销了,显然timeout会被clear掉,但如果你没成功打开应用即返回404,那么30ms后页面当然会自动跳转了。
这种方式使用有个缺点:如果应用没有安装的话页面在跳转至App Store的同时会弹出打不开网址的提示。
当然将连接协议改成itms-apps://可以避免。即:
itms-apps://itunes.apple.com/cn/app/qq-2011/id444934666?mt=8
一篇完整的代码,可针对PC 和 Mobile单独做调整:
Mobile Safari 调用本地APP,否则进入App Store下载
9.用我们的app打开word、pdf之类的文档,即点击word、pdf可以选用我们的app打开
概要点:
1. 注册申明app能够打开某种类型的文档,这样其他app才可能通过DIC(document interaction interface)把文件转给你app来打开
2. 注册就要在plist里声明CFBundleDocumentTypes
CFBundleDocumentTypes
CFBundleTypeName 文档类型名称
pdf
LSHandlerRank //是拥有此类型文档,还是仅用于打开
Default
一般而言一个文档类型和一个文件类型对应,当然也可以是多个文件类型例如。doc和docx是word文档在两个不同版本下的文件后缀。这样你可以把这两个文件类型组合在一个文档类型中
A uniform type identifier (UTI) is a string that identifies a class of entities with a type. UTIs are typically used to identify the format for files or in-memory data types and to identify the hierarchical layout of directories, volumes or packages
这里有个基本的对照表,文件后缀和UTI的串
https://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
更多的对应可以参考:
Apple's Uniform Type Identifiers Overview
LSItemContentTypes
com.sunsetlakesoftware.molecules.pdb //app id+.pdb
org.gnu.gnu-zip-archive
这里我们使用了一个系统定义的。org。gnu。。。。另外一个是程序定义的UTI,程序定义的UTI需要导出,系统其他程序才能知道
3. 需要为自定义的UtI在plist中申明:
UTExportedTypeDeclarations
UTTypeConformsTo
public.plain-text
public.text
UTTypeDescription
Molecules Structure File
UTTypeIdentifier
com.sunsetlakesoftware.molecules.pdb // 自定义的type identifier
UTTypeTagSpecification
public.filename-extension //关键点
pdb
public.mime-type //关键点
chemical/x-pdb
关键是说明 com.sunsetlakesoftware.molecules.pdb UTI 是和.pdb后缀文件关联,且mime类型是 chemical/x-pdb.
这样一来,在邮件程序中,tap且hold等待弹出候选程序列表,可以打开特定的文件。
当附件被打开,你的app就启动了。一般而言,至少要在application:didfinishelaunchingwithoptions中处理文件路径等,看起来就像是文件被copy到你app目录下,然后打开了:
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
再看另外一个例子,注释在其中
CFBundleTypeName
My File Format //任意定义
CFBundleTypeIconFiles //icon图标资源,当用于显示此类文件的时候
MySmallIcon.png //resource in bundle
MyLargeIcon.png
LSItemContentTypes //使用了UTI格式的,关联到文件格式
也可以通过MIME来指定文件类型CFBundleTypeMIMETypes
更多信息:
https://developer.apple.com/library/ios/#documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-SW1
案例: 在iOS app中导入/导出文档
我们经常会用到的文件操作,又希望本地有文档保存,可以离线操作,其实ibook/iannotation之类多有类似的东西,就是本地library;有时候,还希望可以导出文件去另g外一个地方
新建一个项目view based application:
打开nib文件,增加两控件:
WebView
-
Button
1. 通过拖拽,完成outlet action的声明;
增加一些message例如opendocument/handledocumentopenUrL2.注意到要实现protocol:UIDocumentInteractionControllerDelegate
@interface flyViewController : UIViewController
{
IBOutlet UIWebView *webview;
}
-(void)openDocumentIn;
-(void)handleDocumentOpenURL:(NSURL *)url;
-(void)displayAlert:(NSString *) str;
-(void)loadFileFromDocumentsFolder:(NSString *) filename;
-(void)listFilesFromDocumentsFolder;
- (IBAction)btnDisplayFiles:(id)sender;
@end
-(void)openDocumentIn {
NSString * filePath =
[[NSBundle mainBundle]
pathForResource:@"Courses for Q2 2011" ofType:@"pdf"];
documentController =
[UIDocumentInteractionController
interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
documentController.delegate = self;
[documentController retain];
documentController.UTI = @"com.adobe.pdf";
[documentController presentOpenInMenuFromRect:CGRectZero
inView:self.view
animated:YES];
}
-(void)documentInteractionController:(UIDocumentInteractionController *)controller
willBeginSendingToApplication:(NSString *)application {
}
-(void)documentInteractionController:(UIDocumentInteractionController *)controller
didEndSendingToApplication:(NSString *)application {
}
-(void)documentInteractionControllerDidDismissOpenInMenu:
(UIDocumentInteractionController *)controller {
}
10. 文档共享
1.通过itunes
Info.plist增加如下声明:
UIFileSharingEnabled
当文件拖动到app后,会存储在default document目录下
-(void) displayAlert:(NSString *) str {
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"Alert"
message:str
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)handleDocumentOpenURL:(NSURL *)url {
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView setUserInteractionEnabled:YES];
[webView loadRequest:requestObj];
}
-(void)loadFileFromDocumentsFolder:(NSString *) filename {
//---get the path of the Documents folder---
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory
stringByAppendingPathComponent:filename];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
[self handleDocumentOpenURL:fileUrl];
}
-(void)listFilesFromDocumentsFolder {
//---get the path of the Documents folder---
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList =
[manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableString *filesStr =
[NSMutableString stringWithString:@"Files in Documents folder \n"];
for (NSString *s in fileList){
[filesStr appendFormat:@"%@ \n", s];
}
[self displayAlert:filesStr];
[self loadFileFromDocumentsFolder:@"0470918020.pdf"];
}
- (IBAction) btnDisplayFiles {
[self listFilesFromDocumentsFolder];
}
第二中方法就是自己作为一个文档接受方:主要是通过注册,在plist中声明通过CFBundledocumenttypes
其实当文档触发app起来后,文档会被复制到一个inbox的目录,在documents目录下的一个子目录,可以通过url来看到路径
#import "OfflineReaderAppDelegate.h"
#import "OfflineReaderViewController.h"
@implementation OfflineReaderAppDelegate
@synthesize window;
@synthesize viewController;
-(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if (url != nil && [url isFileURL]) {
[self.viewController handleDocumentOpenURL:url];
}
return YES;
}