• IOS_多线程_ASI_AFN_UIWebView


    H:/0730/00_多线程4票种_ViewController.h
    //
    //  ViewController.h
    //  卖票
    //
    //  Created by apple on 13-7-29.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    // 多行文本提示框
    @property (weak, nonatomic) IBOutlet UITextView *infoTextView;
    
    // NSThread售票
    - (IBAction)threadSales:(id)sender;
    
    // NSInvocationOperation售票
    - (IBAction)invocationSales:(id)sender;
    
    // NSBlockOperation售票
    - (IBAction)blockSales:(id)sender;
    
    // GCD售票
    - (IBAction)gcdSales:(id)sender;
    
    @end
    

    H:/0730/00_多线程4种售票_ViewController.m
    <pre name="code" class="objc">

    //  ViewController.m
    //  卖票
    //  Created by apple on 13-7-29.
    #import "ViewController.h"
    @interface ViewController ()
    {
        NSInteger   _tickets;
        // 线程锁NSLock,必须是成员变量,不能是局部变量
        NSLock      *_lock;
    }
    // 以下的atomic成员,结合同步代码块使用,@synchronized (self) {}
    @property (assign, atomic) NSInteger tickets;
    /*
     1. 在做多线程NSOperation和GCD技术的时候,抢夺的内存资源必须是“原子属性”——atomic
     2. 抢夺的资源在使用的时候,
    		//一定要用属性的self.xxx或者object.xxx,这样才getter,才atomic发挥作用
     3. 要在Operation和GCD中抢夺资源,须要使用到“同步锁”。@synchronized(self){...}
    			//目的是,锁住与抢夺资源相关的代码,包含读和写
     4. 平时,尽量不要用抢夺资源去做推断条件。而且同步锁的范围越小越好!
    */
    
    @end
    @implementation ViewController
    
    /*
    		// 同步锁是要手敲出来的
    		@synchronized (self) {
    			
    		}
    */
    
    // 为了在TextView里面添加文本,更新界面,须要先写一个方法处理。
    // 1. 读出当前文本框的内容
    // 2. 把要追加的文本附加在当前文本框内容的后面
    // 3. 又一次为文本框赋值
    // 这是负责更新界面的UI
    - (void)appendTextView:(NSString *)text
    {
        NSMutableString *str = [NSMutableString stringWithString:_infoTextView.text];
        [str appendFormat:@"
    %@", text];
        [_infoTextView setText:str];
        // 定义一个NSRange,代表文本框须要滚动到的位置    
        NSRange range = NSMakeRange(str.length, 1);
    	// 我们如今想要滚动到最后,这种方法的參数是一个NSRange    
        [_infoTextView scrollRangeToVisible:range];
    }
    
    // 多线程一:响应button点击,启动NSThread售票
    - (IBAction)threadSales:(id)sender
    {   
        _tickets = 100;    
        // 创建线程 NSThread1
        NSThread *thread1 = [[NSThread alloc]initWithTarget:self
    				selector:@selector(threadSaleMethod) object:nil];
        // 设置线程1的名字
        [thread1 setName:@"售票线程-1"];
        // 启动线程 NSThread1 仅仅有NSThread须要手动start
        [thread1 start];
        // 创建线程 NSThread2
        NSThread *thread2 = [[NSThread alloc]initWithTarget:self
    				selector:@selector(threadSaleMethod) object:nil];
    	// 设置线程2的名字
        [thread2 setName:@"售票线程-2"];
        // 启动线程 NSThread2 仅仅有NSThread须要手动start	
        [thread2 start];
    }
    
    // 多线程一:实际NSThread售票运行的代码,线程跑的方法
    #pragma mark - 自己定义方法,NSThread售票核心代码
    - (void)threadSaleMethod
    {
        // 1. 推断是否还有票
        // 2. 更新界面,提示当前票数
        // 3. 总票数-1
        // 4. 模拟延时
        // 要解决一个问题:在threadSaleMethod这一个方法里面。我们就把全部的票卖光!。。
        // 线程锁:所谓线程锁。就是:在改动或者推断共享资源的时候,
    				//须要把共享资源加锁,防止别的线程对
        // 共享资源进行改动。
        // 使用线程锁的方式:
        // 1. 定义锁,懒载入,且锁必须是成员变量
        if (_lock == nil) {
            _lock = [[NSLock alloc]init];
        }    
        while (YES) {
    		// 2. 使用共享资源之前。加锁		
            [_lock lock];
            if (_tickets > 0) {
                // 做了一个字符串,显示提示信息
                NSString *str = [NSString stringWithFormat:@"当前票数是%d,售票线程是%@", _tickets, [[NSThread currentThread]name]];
            
                // 主线程,UI界面中显示一下票数
                // 在多线程方法里面不能这样使用的
                //        [self appendTextView:@"12"];
                // waitUntilDone 的意思是:是否等待主线程更新完成
                [self performSelectorOnMainThread:@selector(appendTextView:)
    										withObject:str waitUntilDone:YES];
    			// 售完一张,票数减1
                _tickets--;
                // 3. 使用共享资源完成,马上解锁		
                [_lock unlock];
                // 模拟不同售票效率
                if ([[[NSThread currentThread]name] isEqualToString:@"售票线程-1"]) {
                    [NSThread sleepForTimeInterval:0.2];
                } else {
                    [NSThread sleepForTimeInterval:0.3];
                }                    
            } else {
                // 3. 使用共享资源完成。马上解锁		
                [_lock unlock];            
    			// 结束时,打印下线程名
                NSString *str = [NSString stringWithFormat:@"票已售完%@",
    							[[NSThread currentThread]name]];
    			// 主线程,UI界面中显示一下哪个线程结束了
                [self performSelectorOnMainThread:@selector(appendTextView:) 
    							withObject:str waitUntilDone:YES];
                NSLog(@"%@", str);
                // 退出循环
                break;
            }
        }
    }
    
    // 多线程二:响应button点击,通过NSInvocationOperation加入到NSOperationQueue售票
    - (IBAction)invocationSales:(id)sender
    {
        _tickets = 20;
        // 1. 定义2个NSInvocationOperation操作
        // 1.1. 操作须要调用一个target对象的selector方法。相似NSThread
        // 1.2. 第3个參数object代表:方法是能够接收參数的,且仅仅能接收一个。
        NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self
    						selector:@selector(operationSaleMethod:) object:@"Operation - 1"];
        NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self
    						selector:@selector(operationSaleMethod:) object:@"Operation - 2"];    
        // 2. 定义1个操作队列NSOperationQueue
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        // 3. 将2个操作逐一加入到操作队列,自己主动启动
        [queue addOperation:operation1];
        [queue addOperation:operation2];
    }
    // 多线程二:通过NSInvocationOperation加入到NSOperationQueue售票运行的代码。线程跑的方法
    // 相同也是多线程三:通过NSOperationQueue的block售票的核心代码,线程跑的方法
    #pragma mark - NSOperation售票,使用@synchronized(self){}
    // NSOperation售票方法,參数是上面方法定义的操作名称
    - (void)operationSaleMethod:(NSString *)operationName
    {
        // 卖票流程——在这一个方法里面,我们须要把全部的票卖光!!!

    // 1. 是否有票 // 2. 显示当前票数 // 3. 票数-1 // 4. 通过延时,模拟效率 while (YES) { // !!!

    同步锁要锁住全部抢夺资源的代码 // 平时,尽量不要用抢夺的资源做推断条件,会添加同步锁的范围,减少效率! @synchronized(self) { if (self.tickets > 0) { NSString *str = [NSString stringWithFormat:@"当前票数:%d,线程名称:%@", self.tickets, operationName]; // 主线程队列“仅仅”负责更新UI // 把全部的成员变量调用的位置都改成了getter方式调用,发挥atomickeyword // 属性调用是通过getter。这样调用才干发挥atomic的作用 [[NSOperationQueue mainQueue]addOperationWithBlock:^{ // 在NSOperationQueue的主队列中,仅仅负责更新界面UI [self appendTextView:str]; }]; self.tickets--; // 通过延时,模拟不同售票效率 if ([operationName isEqualToString:@"Operation - 1"] || [operationName isEqualToString:@"Block - 1"]) { [NSThread sleepForTimeInterval:0.2]; } else { [NSThread sleepForTimeInterval:1.0]; } } else { NSString *str = [NSString stringWithFormat:@"票已售完,线程名称:%@", operationName]; // 在NSOperationQueue的主队列中,仅仅负责更新界面UI [[NSOperationQueue mainQueue]addOperationWithBlock:^{ [self appendTextView:str]; }]; break; } }//同步代码块@synchronized,到这儿才结束 } } // 多线程三:响应button点击,通过NSOperationQueue的block售票 - (IBAction)blockSales:(id)sender { _tickets = 20; // 1,定义NSOperationQueue操作队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; // 2,通过block给操作队列加入自己定义方法,并运行 [queue addOperationWithBlock:^{ [self operationSaleMethod:@"Block - 1"]; }]; // 2,通过block给操作队列加入自己定义方法,并运行 [queue addOperationWithBlock:^{ [self operationSaleMethod:@"Block - 2"]; }]; // 2,通过block给操作队列加入自己定义方法,并运行 [queue addOperationWithBlock:^{ [self operationSaleMethod:@"Block - 3"]; }]; // 3,设置NSOperationQueue操作队列,最大并发运行任务个数 [queue setMaxConcurrentOperationCount:2]; } // 多线程四:响应button点击,通过GCD grand central dispatch售票 - (IBAction)gcdSales:(id)sender { _tickets = 20; // 1. 获取全局队列 dispatch_get_global_queue,參数1为默认优先级, // 參数2标记永远是0 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2. 创建小组 dispatch_group_create dispatch_group_t group = dispatch_group_create(); // 3. 向小组加入异步任务一。dispatch_group_async // 參数1,小组名 // 參数2,全局队列名 // 參数3,block,即指定详细要运行的方法,可带參数:名字 dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@"GCD-1"]; }); // 3. 向小组加入异步任务二,dispatch_group_async // 參数1,小组名 // 參数2,全局队列名 // 參数3,block,即指定详细要运行的方法,可带參数,名字 dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@"GCD-2"]; }); // 4. 监听小组通知 // 參数1,小组名 // 參数2,获得主队列 dispatch_get_main_queue() // 參数3,block代码块:全部异步任务都完成时,要做的事情!!! dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 提示用户没有票了!更新到界面UI [self appendTextView:@"票已售完!

    "]; }); } // 多线程四:通过GCD向小组加入的异步任务。即线程跑的方法 #pragma mark - GCD售票 详细卖票流程 - (void)gcdSaleMethod:(NSString *)gcdName { // 1. 确认票数 // 2. 更新界面 // 3. 票数-1 // 4. 模拟延时 while (YES) { if (_tickets > 0) { // 1. 确定要更新的内容 NSString *str = [NSString stringWithFormat:@"当前票数:%d, 售票线程:%@", _tickets, gcdName]; // 2. dispatch_async(),开启异步任务, // 參数1,要在哪个地方运行该异步任务:dispatch_get_main_queue() // 參数2,block指明要运行的详细异步任务:更新UI界面,而且票数-1 dispatch_async(dispatch_get_main_queue(), ^{ [self appendTextView:str]; // GCD中 对共用资源的改动也要放到获得的主队列里 _tickets--; }); // 通过延时,模拟不同售票效率 if ([gcdName isEqualToString:@"GCD-1"]) { [NSThread sleepForTimeInterval:0.2]; } else { [NSThread sleepForTimeInterval:1.0]; } } else { break; } } } @end



    
    
    H:/0730/01_ASI_ViewController.h
    //  ViewController.h
    //  ASI演练
    //  Created by apple on 13-7-30.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    #import <UIKit/UIKit.h>
    #import "ASIHTTPRequest.h"
    @interface ViewController : UIViewController <ASIHTTPRequestDelegate, ASIProgressDelegate>
    // 响应button点击,下载文件
    - (IBAction)downloadFile:(id)sender;
    @end
    

    H:/0730/01_ASI_ViewController.m
    <pre name="code" class="objc">//  ViewController.m
    //  ASI演练
    /*
    ASIproject注意事项:
    	1,不能选ARC
    	2,更改IOS 部署 目标为 IOS5.0
    	3,将ASI压缩包,解压,拖动Classes文件夹和External文件夹拖进project
    	4,尝试编译,出现错误:无法找到libxml/HTMLparser.h
    		解决方法:
    		进入build settings,找到_head search paths头文件搜索文件夹_加入:
    		${SDK_DIR}/usr/include/libxml2,并回车
    	5,再次尝试编译,出现错误:ASITestCase.h:12:9: 'GHUnitIOS/GHUnit.h' file not found
    		错误原因:没有GHUnit框架
    		解决的方法:
    		进入build phases
    		展开compile sources
    		将tests结尾的文件所有移除,按减号,即測试文件,不參与编译
    		即删除单元測试部分的代码引用
    	6,再次command B 编译,85个错误
    		解决方法:
    		非常easy,进入summary,找到链接的框架和引用,+号,加入下列iOS框架引用就可以
    		CFNetwork.framework
    		SystemConfiguration.framework
    		MobileCoreServices.framework
    		libz.dylib
    		libxml2.dylib
    	7,上述框架,在ASI提供的project样本中能够看到,再次编译OK
    	8,为了解压缩,还要加入SSZipArchive框架
    		将下面文件加入project:
    		SSZipArchive.h
    		SSZipArchive.m
    		minizip文件夹
    	9,编译OK
    */
    //  Created by apple on 13-7-30.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    #import "ViewController.h"
    #import "SSZipArchive.h"
    // 遵守两个ASI协议 <ASIHTTPRequestDelegate, ASIProgressDelegate>
    @interface ViewController ()
    {
        // 下载文件的大小,头信息字典中的文件长度,在后面进度中要用到
        CGFloat   _fileLength;
    }
    @end
    @implementation ViewController
    #pragma mark - 响应button点击,開始启动ASI框架断点续传下载文件
    - (IBAction)downloadFile:(id)sender
    {
        // 1.   指定下载文件地址
        NSString *urlString = @"http://teacher.local/~apple/itcast/download/iTunesConnect_DeveloperGuide_CN.zip";
        NSURL *url = [NSURL URLWithString:urlString];
        // 2.   设定文件保存路径及暂时缓存路径
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
    						 NSUserDomainMask, YES);
        //保存路径
        NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
    	//缓存路径
        NSString *tempPath = [documents[0]stringByAppendingPathComponent:@"book.tmp"];
        // 3.   通过URL,初始化ASIHTTPRequest实例对象,不支持ARC
        ASIHTTPRequest *request = [[[ASIHTTPRequest alloc]initWithURL:url]autorelease];
        // 4.   设置代理为当前控制器——ASI是通过代理回调的方式处理网络请求的
        [request setDelegate:self];
        // 5.   设置下载完毕的保存路径
        [request setDownloadDestinationPath:downloadPath];
        // 6.   设置暂时缓存路径
        [request setTemporaryFileDownloadPath:tempPath];
        // 7.   设置同意断点续传
        [request setAllowResumeForFileDownloads:YES];
        // 8.   设置下载进程代理——用户想知道下载的实际进展情况
        [request setDownloadProgressDelegate:self];
        // 9.   启动异步请求
        [request start];
    }
    #pragma mark - ASI代理方法
    // 2. 接收到响应头 didReceiveResponseHeaders 目的获得文件长度
    - (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
    {
        // 通过Log,我们看到了"Content-Length" = 6105204;
        // 貌似能够用来监控下载进度
        // 暂时不去管它
        NSLog(@"请求头%@", responseHeaders);
        // 在这里。我们能够知道文件长度,如果我们在这里记录下来文件的长度,如果100M
        // 须要获得的是文件的兆数会更加人性化 字节->K->M(1024)
        NSInteger length = [responseHeaders[@"Content-Length"]integerValue];
        // 文件长度计算之后,是一个小数,须要改变一下成员变量的类型
        _fileLength = (CGFloat)length / 1024 / 1024;
    }
    #pragma mark - 下载进度的代理方法
    - (void)setProgress:(float)newProgress
    {
        // 传回来的參数是一个下载进度的百分比
        // 那么,我们告诉用户还差多少M下载完毕?
        NSLog(@"%.2f", newProgress * _fileLength);
        // 100M * 0.2 = 20M
    }
    
    #pragma mark - ASI代理方法
    // 3. 请求完毕 requestFinished
    - (void)requestFinished:(ASIHTTPRequest *)request
    {
        NSLog(@"请求完毕");
        // 我们能够去做解压缩的工作了。

    由于下载工作已经完毕了!

    // 需求: // 1. 知道文件保存路径 // 2. 解压缩文件 // 2.1 定义一个压缩文件 NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"]; // 2.3 调用SSZipArchive的类方法解压缩,參数2是一个文件夹 [SSZipArchive unzipFileAtPath:downloadPath toDestination:documents[0]]; // 3. 通过文件管理者(单例),删除压缩文件 [[NSFileManager defaultManager]removeItemAtPath:downloadPath error:nil]; } #pragma mark - ASI代理方法 // 代理方法之1. 请求開始 - (void)requestStarted:(ASIHTTPRequest *)request { NSLog(@"请求開始"); } #pragma mark - ASI代理方法 // 代理方法之4. 请求失败 - (void)requestFailed:(ASIHTTPRequest *)request { NSLog(@"请求失败"); } @end



    
    
    H:/0730/02_AFN_ViewController.h
    //
    //  ViewController.h
    //  AFN断点续传演练
    //
    //  Created by apple on 13-7-30.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    // 下载文件
    - (IBAction)downloadFiles:(id)sender;
    
    @end
    

    H:/0730/02_AFN_ViewController.m
    <pre name="code" class="objc">//  ViewController.m
    //  AFN断点续传演练
    //  Created by apple on 13-7-30.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    /*
    	AFN使用步骤:
    	1,新建project的时候,勾选ARC(毕竟AFN有是人在维护的)
    	2,拖动目录AFNetworking到project中
    	3,将解压要用到的目录SSZipArchive拖到project中
    		同一时候导入它依赖的libz.dylib框架 
    	4,编译,弹出2个warning,缺少框架
    		SystemConfiguration.framework
    		MobileCoreServices.framework
    	5,展开supporting files目录,找到-->
    		project名-Prefix.pch文件,在#endif的前面加入
    		#import<SystemConfiguration/SystemConfiguration.h>
    		#import<MobileCoreServices/MobileCoreServices.h>
    	6,再次编译ok
    */
    #import "ViewController.h"
    #import "AFNetworking.h"
    #import "SSZipArchive.h"
    @interface ViewController ()
    @end
    @implementation ViewController
    #pragma mark - 下载文件
    - (IBAction)downloadFiles:(id)sender
    {
        // 1.   指定下载文件地址
        NSURL *url = [NSURL URLWithString:@"http://169.254.98.245/~apple/itcast/download/iTunesConnect_DeveloperGuide_CN.zip"];
        // 2.   指定文件保存路径
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
    							NSUserDomainMask, YES);
        NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
        // 3.   创建NSURLRequest
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        // 4.   通过固定请求,创建AFURLConnectionOperation,多态
        AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc] 
    								initWithRequest:request];
        // 5.   设置操作的输出流(在网络中的数据是以流的方式传输的,
    			//告诉操作把文件保存在第2步设置的路径中)
        [operation setOutputStream:[NSOutputStream
    					outputStreamToFileAtPath:downloadPath append:NO]];
        // 6.   设置下载进程处理块代码
        // 6.1 bytesRead 读取的字节——这一次下载的字节数
        // 6.2 totalBytesRead 读取的总字节——已经下载完的
        // 6.3 totalBytesExpectedToRead 希望读取的总字节——就是文件的总大小
        [operation setDownloadProgressBlock:^(NSUInteger bytesRead,
    			long long totalBytesRead, long long totalBytesExpectedToRead) {
            // 做下载进度百分比的工作
            NSLog(@"下载百分比:%f", (float)totalBytesRead / totalBytesExpectedToRead);
        }];
        // 7.   操作完毕块代码
        [operation setCompletionBlock:^{
            // 解压缩的顺序
            // 1. 定义要解压缩的文件 —— downloadPath
            // 2. 要解压缩的目标目录,必须是目录
            // 3. 调用类方法解压缩
            [SSZipArchive unzipFileAtPath:downloadPath toDestination:documents[0]];
            
            // 使用文件管理者,删除压缩包
            [[NSFileManager defaultManager]removeItemAtPath:downloadPath error:nil];
        }];
        // 8   启动操作
        [operation start];
    }
    @end
    

    
    
    H:/0730/04_UIWebView_ViewController.h
    //
    //  ViewController.h
    //  UIWebView演练
    //
    //  Created by apple on 13-7-30.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    // 成员属性:UIWebView控件
    @property (weak, nonatomic) IBOutlet UIWebView *localWebView;
    
    // 点击,载入PDF文件button
    - (IBAction)clickPDFButton:(id)sender;
    // 点击,载入HTMLString
    - (IBAction)loadHTMLString:(id)sender;
    
    // 点击,使用loadData载入数据
    - (IBAction)loadData:(id)sender;
    
    @end
    

    H:/0730/04_UIWebView_ViewController.m
    <pre name="code" class="objc">//  ViewController.m
    //  UIWebView演练
    //  Created by apple on 13-7-30.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    #import "ViewController.h"
    @interface ViewController ()
    @end
    @implementation ViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	// 通过自己定义方法获得MIMETYPE
        [self mimeType];
    }
    // 自己定义方法,获取MIMEType
    // 由于我们不能记住全部类型文档的MIMEType。所以我们自己动手,写一个方法
    - (NSString *)mimeType
    {
        // 一。本地文件URL生成的过程
        // 1. 绝对路径
        NSString *path = [[NSBundle mainBundle]pathForResource:@"关于.docx" ofType:nil];
        // 2 绝对路径转FILEURL
        NSURL *fileURL = [NSURL fileURLWithPath:path];
        // 二。

    网络文件URL生成的过程 // 1. 网络地址字符串 NSString *urlString = @"http://www.baidu.com"; // 2. 生成URL NSURL *webURL = [NSURL URLWithString:urlString]; // 1. 定义固定请求 NSURLRequest *request = [NSURLRequest requestWithURL:fileURL]; // 2. 定义响应,到时候,传入地址,到时候方便接收返回的response NSURLResponse *response = nil; // 3. NSConnection静态方法,发送同步请求,传入接收响应的地址 [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; NSLog(@"MIMEType %@", response.MIMEType); return response.MIMEType; } // 响应button点击事件, - (IBAction)clickPDFButton:(id)sender { [self viewLocalPDFFile]; } // 1. 我们如今准备了一个素材是PDF // 2. 我们要把这个PDF显示在webView里面 // 显示本地PDF文件在WebView - (void)viewLocalPDFFile { // 1. 定义URL // 1. 全路径 NSString *path = [[NSBundle mainBundle]pathForResource:@"iTunesConnect_DeveloperGuide_CN.pdf" ofType:nil]; // 2 全路径得到fileURL NSURL *fileURL = [NSURL fileURLWithPath:path]; // 2. 通过fileURL构建请求 NSURLRequest *request = [NSURLRequest requestWithURL:fileURL]; // 4. 重要!!!!!!设置WebView的数据侦測类型:为侦測全部类型 [_localWebView setDataDetectorTypes:UIDataDetectorTypeAll]; // 5. 使用WebView载入这个请求就可以 [_localWebView loadRequest:request]; } // 响应button点击,载入HTMLString - (IBAction)loadHTMLString:(id)sender { // 临时不考虑baseURL,集中在String上面 // 用“iOS 正則表達式”去搜索相关知识点。能够做新闻类的应用! NSString *fullHTML = @"<html><head><title>hello</title></head><body><p1>我爱你</p1></body></html>"; NSString *partHTML = @"<p1>我爱你。!!

    </p1>"; // webview是能够显示部分html代码的 [_localWebView loadHTMLString:partHTML baseURL:nil]; } // 响应button点击,载入“data数据”——NSData - (IBAction)loadData:(id)sender { // 1. pdf文件绝对路径 NSString *path = [[NSBundle mainBundle]pathForResource:@"iTunesConnect_DeveloperGuide_CN.pdf" ofType:nil]; // 2 通过 绝对路径 生成fileURL NSURL *fileURL = [NSURL fileURLWithPath:path]; // 2. 用NSData类方法载入数据,參数为fileURL NSData *data = [NSData dataWithContentsOfURL:fileURL]; // 3. 使用webView载入data类型数据 [_localWebView loadData:data MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil]; } @end


    
    
    H:/0730/05_UIWebView浏览器综合应用_ViewController.h
    //
    //  ViewController.h
    //  UIWebView Demo
    //
    //  Created by apple on 13-7-21.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController <UITextFieldDelegate, UIWebViewDelegate>
    
    // URL文本
    @property (weak, nonatomic) IBOutlet UITextField *urlText;
    // 回退button
    @property (weak, nonatomic) IBOutlet UIBarButtonItem *goBackButton;
    // 前进button
    @property (weak, nonatomic) IBOutlet UIBarButtonItem *goForwardButton;
    // 重载button
    @property (weak, nonatomic) IBOutlet UIBarButtonItem *reloadButton;
    // 停止button
    @property (weak, nonatomic) IBOutlet UIBarButtonItem *stopButton;
    
    // Web视图
    @property (weak, nonatomic) IBOutlet UIWebView *webView;
    
    // 回退
    - (IBAction)goBack:(id)sender;
    // 前进
    - (IBAction)goForward:(id)sender;
    // 刷新
    - (IBAction)reloadURL:(id)sender;
    
    // 提交表单
    - (IBAction)submit:(id)sender;
    
    @end
    

    H:/0730/05_UIWebView浏览器综合应用_ViewController.m
    //  ViewController.m
    //  UIWebView 浏览器综合演示
    //  Created by apple on 13-7-21.
    //  Copyright (c) 2013年 itcast. All rights reserved.
    #import "ViewController.h"
    @interface ViewController ()
    // 訪问指定URL字符串的内容。仅由文本框回车事件调用
    - (void)gotoURLString:(NSString *)urlString;
    // 訪问指定的URL内容
    - (void)gotoURL:(NSURL *)url;
    // 获得本地文件的MIMEType
    - (NSString *)MIMEType:(NSString *)fileName;
    @end
    @implementation ViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [self MIMEType:@"001.网络基础.pdf"];
    	// 调用自己定义測试方法
        [self testLoadHTMLFile];
    }
    // 測试载入本地HTML文件
    - (void)testLoadHTMLFile
    {
        // 測试载入本地HTML文件。须要指定MIMETYPE
        NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"demo.html" ofType:nil];
    	// baseURL基址,以便查找CSS JS jpg等
        NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]resourcePath]
    						isDirectory:YES];
        // 仅仅有载入的html文件才须要指定baseURL路径,告诉浏览器去哪里找图片、样式表等文件
        [_webView loadData:[NSData dataWithContentsOfFile:dataPath]
    					MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:baseURL];
    }
    
    // 自己定义方法,获得本地文件的MIMEType
    - (NSString *)MIMEType:(NSString *)fileName
    {
        // 依据文件名称,得到绝对路径
        NSString *path = [[NSBundle mainBundle]pathForResource:fileName ofType:nil];
        // 依据绝对路径,得到fileURL
        NSURL *url = [NSURL fileURLWithPath:path];
        // 依据url 创建固定请求
        NSURLRequest *request = [NSURLRequest requestWithURL: url];
        // 定义响应,以便接收响应内容
        NSURLResponse *response = nil;
        // 发送同步请求,并传入响应的地址,以便接收响应
        [NSURLConnection sendSynchronousRequest:request
    					returningResponse:&response error:nil];
        NSLog(@"MIMEType is %@", [response MIMEType]);
        return [response MIMEType];
    }
    #pragma mark - UIWebView载入内容的測试方法
    // 载入HTML字符串
    - (void)testLoadHTMLString
    {
        // 測试载入HTML字符串
        NSString *html = @"<html><head><title>红楼梦</title></head><body><h1>世外仙姝</h1></body></html>";
        [_webView loadHTMLString:html baseURL:nil];
    }
    // 载入部分HTML字符串測试
    - (void)testLoadPartHTMLString
    {
        // 測试载入部分HTML字符串,不须要显示整个网页内容时,通常使用此方法
        NSString *partHtml = @"<h1>寂寞林</h1>";
        [_webView loadHTMLString:partHtml baseURL:nil];
    }
    
    // 载入本地PDF文件
    - (void)testLoadPDFFile
    {
        // 測试载入本地PDF,须要指定MIMETYPE
        NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"001.网络基础.pdf" ofType:nil];
        [_webView loadData:[NSData dataWithContentsOfFile:dataPath]
    			MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil];
    }
    // 载入本地文本文件
    - (void)testLoadTextFile
    {
        // 測试载入本地文本文件,须要指定MIMETYPE
        NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"关于.txt" ofType:nil];
        [_webView loadData:[NSData dataWithContentsOfFile:dataPath]
    			MIMEType:@"text/plain" textEncodingName:@"UTF-8" baseURL:nil];
    }
    
    #pragma mark - UITextField代理方法
    // 文本框回车事件
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
    	// 假设被回车的是地址栏,且不为空
        if (textField == _urlText && textField.text.length > 0) {
    		// 退出键盘
            [textField resignFirstResponder];
    		// 调用自己定义方法,转到URLstring方法
            [self gotoURLString:textField.text];
        }
        return YES;
    }
    
    #pragma mark - 自己定义方法,回车后,调用訪问指定URL内容
    // 訪问指定URL字符串的内容,仅由文本框事件调用。文本框回车时候调用的
    - (void)gotoURLString:(NSString *)urlString
    {
        NSURL *url = nil;
        // 推断是否是httpURL
        if ([urlString hasPrefix:@"http://"]) {
            // URL中有中文的,是须要加百分号的!
            url = [NSURL URLWithString:[urlString
    				stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        } else if ([urlString hasPrefix:@"file://"]) {
            // 推断给定參数是否已经是完整的url路径,避免出现前进后退后,
    				//URL变成完整URL无法訪问的情况
            if ([urlString hasPrefix:@"file://localhost/"]) {
                // 注意此处不能使用fileURLWithPath方法?

    ?

    ?????

    ???

    ?

    // 由于fileURLWithPath是将绝对路径,转成fileURL // 而此时,已经是fileURL了 url = [NSURL URLWithString:urlString]; } else { // 假设没有localhost前缀的,说明是新输入的本地文件,须要转换url。 // 检測字串范围 NSRange range = [urlString rangeOfString:@"file://"]; // 截取剩余部分作为文件名称 NSString *fileName = [urlString substringFromIndex:range.length]; // 依据文件名称,生成文件绝对路径 NSString *path = [[NSBundle mainBundle]pathForResource:fileName ofType:nil]; // 推断绝对路径是否存在 if ([[NSFileManager defaultManager]fileExistsAtPath:path]) { // 若存在,将绝对路径转成fileURL url = [NSURL fileURLWithPath:path]; } else { url = nil; } } } // 假设到这儿url仍为空,说明,转换失败,输入地址栏内容有误 if (url == nil) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"输入地址不对。请又一次输入!" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; // 设置文本框输入焦点 [_urlText becomeFirstResponder]; } else { // 地址正确,下一步,调用自己定义方法,訪问指定的URL内容 [self gotoURL:url]; } } // 地址正确,下一步,调用自己定义方法,訪问指定的URL内容 - (void)gotoURL:(NSURL *)url { // 使用转换后的URL字符串替代用户输入的URL文本框内容 // absoluteString?

    ?? [_urlText setText:[url absoluteString]]; // 1, 依据url 创建固定请求 NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 2, 设置浏览器,自己主动侦測全部数据类型 [_webView setDataDetectorTypes:UIDataDetectorTypeAll]; // 3, webView 载入请求 [_webView loadRequest:request]; } // 响应button点击,JS 提交表单 - (IBAction)submit:(id)sender { // 获取当前页面的url NSString *url = [_webView stringByEvaluatingJavaScriptFromString:@"document.location.href"]; NSLog(@"url %@", url); // 获取当前页面的标题 NSString *title = [_webView stringByEvaluatingJavaScriptFromString:@"document.title"]; NSLog(@"title %@", title); // 提交表单 [_webView stringByEvaluatingJavaScriptFromString:@"document.forms[0].submit(); "]; } #pragma mark - UIWebViewDelegate 代理方法 // 网页中的每个请求都会被触发这种方法。返回NO代表不运行这个请求(经常使用于JS与iOS之间通讯) - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSLog(@"将要载入请求"); return YES; } #pragma mark - IBActions // 调用浏览器webView默认的,回退操作 - (IBAction)goBack:(id)sender { [_webView goBack]; } // 调用浏览器webView默认的,前进操作 - (IBAction)goForward:(id)sender { [_webView goForward]; } // 调用浏览器webView默认的,刷新操作 - (IBAction)reloadURL:(id)sender { [_webView reload]; } #pragma mark - UIWebViewDelegate 代理方法 // 网页開始载入的时候调用 - (void)webViewDidStartLoad:(UIWebView *)webView { NSLog(@"開始载入"); } #pragma mark - UIWebViewDelegate 代理方法 // 网页载入完毕的时候调用 - (void)webViewDidFinishLoad:(UIWebView *)webView { NSLog(@"载入完毕"); } #pragma mark - UIWebViewDelegate 代理方法 // 网页载入出错的时候调用 - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { NSLog(@"载入出错%@", [error localizedDescription]); } @end


    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    GIt如何进行代码管理
    GIt如何安装使用
    selenium+xpath在不同层级的写法
    Java+Selenium 常见问题QA
    Java+Selenium如何解决空指针
    python 发邮件
    用apscheduler写python定时脚本
    http断点续传的原理
    好的代码是重构出来的
    python写excel总结
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4712772.html
Copyright © 2020-2023  润新知