当前位置: 首页 > 编程日记 > 正文

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技术的时候,抢夺的内存资源必须是“原子属性”——atomic2. 抢夺的资源在使用的时候,//一定要用属性的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:@"\n%@", 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,不能选ARC2,更改IOS 部署 目标为 IOS5.03,将ASI压缩包,解压,拖动Classes文件夹和External文件夹拖进project4,尝试编译,出现错误:无法找到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.frameworkSystemConfiguration.frameworkMobileCoreServices.frameworklibz.dyliblibxml2.dylib7,上述框架,在ASI提供的project样本中能够看到,再次编译OK8,为了解压缩,还要加入SSZipArchive框架将下面文件加入project:SSZipArchive.hSSZipArchive.mminizip文件夹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实例对象,不支持ARCASIHTTPRequest *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.frameworkMobileCoreServices.framework5,展开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.   创建NSURLRequestNSURLRequest *request = [NSURLRequest requestWithURL:url];// 4.   通过固定请求,创建AFURLConnectionOperation,多态AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];// 5.   设置操作的输出流(在网络中的数据是以流的方式传输的,//告诉操作把文件保存在第2步设置的路径中)[operation setOutputStream:[NSOutputStreamoutputStreamToFileAtPath: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文件,须要指定MIMETYPENSString *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];// 依据绝对路径,得到fileURLNSURL *url = [NSURL fileURLWithPath:path];// 依据url 创建固定请求NSURLRequest *request = [NSURLRequest requestWithURL: url];// 定义响应,以便接收响应内容NSURLResponse *response = nil;// 发送同步请求,并传入响应的地址,以便接收响应[NSURLConnection sendSynchronousRequest:requestreturningResponse:&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,须要指定MIMETYPENSString *dataPath = [[NSBundle mainBundle]pathForResource:@"001.网络基础.pdf" ofType:nil];[_webView loadData:[NSData dataWithContentsOfFile:dataPath]MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil];
}
// 载入本地文本文件
- (void)testLoadTextFile
{// 測试载入本地文本文件,须要指定MIMETYPENSString *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;// 推断是否是httpURLif ([urlString hasPrefix:@"http://"]) {// URL中有中文的。是须要加百分号的。url = [NSURL URLWithString:[urlStringstringByAddingPercentEscapesUsingEncoding: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


转载于:https://www.cnblogs.com/jzssuanfa/p/7233206.html

相关文章:

Error:java: 错误: 不支持发行版本 14

Error:java: 错误: 不支持发行版本 14修改全局设置修改module设置在我换了电脑把IDEA的project转移过来之后&#xff0c;开始出现了问题 修改全局设置 修改 Files -> Settings -> Project Structure -> Project -> Project Language Level->选择版本比当前jdk版…

python简说(十五)MD5加密

def my_md5(s): news str(s).encode() m hashlib.md5(news) return m.hexdigest()转载于:https://www.cnblogs.com/wangtingting920416/p/10099896.html

[错误]xstring(525) : warning C4530:

"warning C4530:" 在编译选项中添加上 -GX 就好了&#xff0c;详情参MSDN. 作用&#xff1a;remove _ATL_MIN_CRT Link option

程序模拟电影院窗口卖票,多线程Demo

某电影院目前正在上映国产大片&#xff0c;共有100张票&#xff0c;而它有3个窗口卖票&#xff0c;请设计一个程序模拟该电影院卖票 卖电影票Demo实现步骤1.SellTicket类2.SellTicketDemo测试类3.测试结果4.问题反思4.1 相同的票出现了多次4.2 出现了负数的票实现步骤 1. 定义一…

(C#加密)幻术-大踲无形

首先:我看下面的代码只是知道大概的原理核心算法还是不太清楚~~有清楚的麻烦回复下谢谢咯咯--这也是看Msdn就是把在一个图片上隐藏数据 usingSystem;usingSystem.Drawing;usingSystem.Collections;usingSystem.ComponentModel;usingSystem.Windows.Forms;usingSystem.Data;usin…

01 python爬虫

--- 转载于:https://www.cnblogs.com/haima/p/10107708.html

【BZOJ3963】[WF2011]MachineWorks cdq分治+斜率优化

【BZOJ3963】[WF2011]MachineWorks Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM)的经理&#xff0c;公司使用更加先进的机械设备生产先进的机器。原来的那一台生产机器已经坏了&#xff0c;所以你要去为公司买一台新的生产机器。你的任务是在转型期…

金山发布《2006年度信息安全报告》

2006年度&#xff0c;国内的互联网环境因接踵而至的信息安全事件一再掀起了波澜。作为国内领先的信息安全厂商&#xff0c;金山毒霸同数千万国内用户一起见证了对病毒、对流氓软件发出的各种绝技杀手锏。 2007年2月8日&#xff0c;金山软件正式发布了《中国互联网2006年度信息安…

Nginx+Apache Yii2.0 配置方案

最近用Yii2.0框架做了个小项目&#xff0c;虽然项目本身业务逻辑不复杂&#xff0c;但是由于本身业务逻辑的特殊性&#xff0c;在上午9点到12点之间系统访问量会突然上升&#xff08;浏览量和用户上传文件量&#xff09;。导致系统单纯的部署在Apache下&#xff0c;支撑不了这么…

RobotFramework下的http接口自动化Set Request Body 关键字的使用

Set Request Body关键字用来设置http 请求时的body 信息&#xff0c;尤其是在post 请求时&#xff0c;经常需要用到这个关键字。 该关键字接收一个参数&#xff0c;[ body ] 示例1&#xff1a;登录博客园&#xff08;http://www.cnblogs.com/&#xff09;时&#xff0c;设置登录…

JDK11使用IDEA,配置JavaFX

JDK11使用IDEA&#xff0c;配置JavaFX1.下载javaFX相关的包2.在实际Demo中试验哪里少了添加哪里导入lib文件夹&#xff0c;之后点击OK配置VMoption配置成功3.运行&#xff0c;大功告成1.下载javaFX相关的包 需要下载对应的包&#xff0c;进入openjfx.cn网站下载 https://gluon…

写了一个PPT,用于公司内部培训

匆忙写成&#xff0c;以后会慢慢补充请用力一击中等规模的并发程序设计http://files.cnblogs.com/jobs/2007-5-9-concurrent-ppt.rar2007-5-10修改版&#xff08;带参考文档&#xff09;http://files.cnblogs.com/jobs/2007-5-10-concurrent-ppt.rar转载于:https://www.cnblogs…

终端bash美化(FC)

终端bash美化(FC) 用Linux也已经一年多了&#xff0c;感觉几乎还是什么都不会。大概是一直再做一些没多大意义的事的缘故吧&#xff0c;就像今天些的内容一样。以前搞了一段时间的GENTOO&#xff0c;发现里面的bash提示&#xff08;也就是&#xff3b;userhostname directory]$…

List and ArrayList

List<> and ArrayList Class DiagramsUsing the Bit Complement of the BinarySearch() Result代码1using System; 2using System.Collections.Generic; 3class Program 4{ 5 static void Main() 6 { 7 List<string> list new List<string>();…

spring boot jpa 整合

1&#xff0c;Eclipse JPA Tool配置 https://www.cnblogs.com/wgslucky/p/10109300.html 2&#xff0c;项目地址 https://gitee.com/wgslucky/springboot-jpa 转载于:https://www.cnblogs.com/wgslucky/p/10109869.html

安装JDK1.8+环境配置

安装JDK1.8环境配置1.下载JDK2.安装JDK3.环境配置3.1 新建系统变量3.2 添加Path路径3.3 使用cmd命令行验证是否环境配置成功1.下载JDK 直接官网下载&#xff1a;http://www.oracle.com 下载链接https://www.oracle.com/java/technologies/javase-downloads.html#JDK8 选择自己…

Nodejs.热部署方法

在开发中我们修改了一点代码后要去重启服务器才能看到结果&#xff0c;为了省去这个过程我们以往经常使用热部署代码的方法 下面是使用“supervisor”来达到热部署能力的方法: sudo npm install -g supervisor #安装 supervisor app.js #启动 如果碰到如下提示, 则表示路径没…

SortedList 泛型类

SortedList 泛型类 请参见 示例 成员 全部折叠 全部展开 语言筛选器&#xff1a; 全部 语言筛选器&#xff1a; 多个 语言筛选器&#xff1a; Visual Basic 语言筛选器&#xff1a; C# 语言筛选器&#xff1a; C语言筛选器&#xff1a; J# 语言筛选器&#xff1a; JScri…

中国现代化进程专题讲座——有感

最近有上段治文老师的中国现代化进程这门课&#xff0c;感觉受益颇多。 从国外到国内&#xff0c;从古代到如今&#xff0c;讲论点、论据&#xff0c;评论历史人物、历史事件&#xff0c;讲的很宏大&#xff0c;很深刻。我并没有特意捧他&#xff0c;而是深深被其思想的深刻、言…

java运行出现JNI错误,JDK8和JDK11都安装了

java运行出现JNI错误&#xff0c;JDK8和JDK11都安装了1. 问题描述2. 尝试办法3. 解决办法3.1 解决方法&#xff1a;3.2 测试结果成功1. 问题描述 因为编程的需要&#xff0c;所以我安装了JDK8和JDK11&#xff0c;在安装好了之后配置好了环境变量&#xff0c;之后打开Eclipse的…

爱不释手(Typingfaster)1.78beta,重大升级,欢迎试用,期待反馈。

爱不释手1.78测试版主要有以下改进&#xff1a;1、改进内核&#xff0c;大幅度提高了屏显速度&#xff1b;2、增加文章分段显示功能&#xff1b;3、增加每秒按键次数统计&#xff1b;4、测试结果中划分了实际速度与名义速度&#xff0c;即实际速度&#xff1d;名义速度准确率&a…

php 网站内容采集器 Snoopy

Snoopy转载于:https://www.cnblogs.com/buxiangxin/p/7245580.html

[转]笑话: 耐力惊人的三只乌龟

某日&#xff0c;龟爸、龟妈、龟儿子三只乌龟&#xff0c;决议去郊游。带了一个山东大饼&#xff0c;和两罐海底鸡出发到XX山去。 苦爬十年&#xff0c;终於到了。席地而坐&#xff0c;卸下装备&#xff0c;准备进食。****~~~该死&#xff01;&#xff01;没带开罐器&#xff0…

如何解决代码中if…else 过多的问题

前言 if...else 是所有高级编程语言都有的必备功能。但现实中的代码往往存在着过多的 if...else。虽然 if...else 是必须的&#xff0c;但滥用 if...else 会对代码的可读性、可维护性造成很大伤害&#xff0c;进而危害到整个软件系统。现在软件开发领域出现了很多新技术、新概念…

Facial keypoints detection Kaggle 竞赛系列

3.2# Facial keypoints detection 作者&#xff1a;Stu. RuiQQ: 1026163725原文链接&#xff1a;http://blog.csdn.net/i_love_home/article/details/51051888该题主要任务是检測面部关键点位置 Detect the location of keypoints on face images 问题表述 在本问题中。要求计算…

Error:java: 无效的源发行版: 11

Error:java: 无效的源发行版: 111.问题描述2.原因查找3.解决办法3.1 打开IDEA的File—Project Structure设置3.2 修改Project SDK为自己想要切换的版本3.3 修改project languang level1.问题描述 在我的电脑中同时安装了JDK8和JDK11&#xff0c;之前本来调试好了的&#xff0c…

今天看论坛,有这样一句话,深有同感,还是家里好

就像孟宣后来对这个城市的评价&#xff1a;“这里的人活的才像人……就像那么发达国家的小城市&#xff0c;不用背负那么大的生存压力。在北京&#xff0c;如果你每天生活要30个馒头&#xff0c;那么你要挣到200到300个。而在这里&#xff0c;只需要30个馒头就可以了……”转载…

面对别人强行关机你怎么办与 定时关机

面对这个图你的第一感觉是什么?肯定是有人.....那你怎么办呢?让它继续下去!不能绝对不能!以前比较幸运的打开了几个记事本没有保存逃过了一关,可是屡试不爽呐!直到我同学出现这种情况时,幸亏我眼快,呵呵 所以问他一下!知道了这个玩意出来的命令是在运行里敲入shutdown -s如果…

iOS开发实战-基于SpriteKit的FlappyBird小游戏

写在前面 最近一直在忙自己的维P恩的事情 公司项目也是一团乱 于是...随手找了个游戏项目改了改就上线了,就当充数了. SpriteKit简介 SpriteKit是iOS 7之后苹果推出的2D游戏框架。它支持2D游戏中各种功能&#xff0c;如物理引擎&#xff0c;地图编辑&#xff0c;粒子&#xff0…

2018年12月14日 函数 总结

map() 处理序列中每个元素&#xff0c;得到迭代器&#xff0c;该迭代器 元素个数和位置与原来一致 filter() 遍历序列中的每个元素&#xff0c;判断每个元素得到布尔值&#xff0c;如果是true则留下来 people[{name:"abc","age":100},{"name":&…