IOS_多线程_GET_POST_AFN_上传下载_视频播放

H:/0917/01_多线程_ViewController.m
/*
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
- (IBAction)click;
- (IBAction)click2;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end*/
//  ViewController.m
//  01-多线程
//  Created by apple on 13-9-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
/*
 1.开启后台线程执行任务,最快捷的多线程,不需要自己管理线程
 [self performSelectorInBackground:@selector(test) withObject:nil];
 
 2.GCD
		方法名是sync,同步,肯定不会开线程,无论什么队列,全在主线程id=1
		方法名是async,异步,肯定开线程,
							当队列是全局队列,开N条线程
							当队列是创建的串行队列,只开1条线程
 1> 队列类型
 * 全局队列
   * 所有添加到全局队列中的任务都是并发执行(同时执行,可能会开启多个线程)
   * dispatch_get_global_queue
 
 * 串行队列
   * 所有添加到串行队列中的任务都是按顺序执行(开一条线程) 
     串行队列,要手动创建,前面是列队名,后面的NULL代表串行
   * dispatch_queue_create("myqueue", 0);
 
 * 主队列
   * 只要添加到主队列中的任务都在主线程中执行(跟方法名没有关系)  
   * dispatch_get_main_queue
 
 2> 同步还是异步,取决于方法名(不会影响主队列,但影响全局队列、串行队列)
 * 同步:dispatch_sync,在当前线程执行任务,不会开启新的线程
 * 异步:dispatch_async,在其他线程执行任务,会开启新的线程
 
 3.NSOperation\NSOperationQueue
 1> 使用步骤
 * 创建NSOperation
 * 添加NSOperation到NSOperationQueue,会自动启动
 * 设置OperationQueue队列的同一时间最大并发执行的线程个数
 
 2> 优点
   * 更加面向对象
   * 可以控制最大并发数  maxConcurrentOperationCount
   * 添加任务(Operation)之间的依赖 addDependency	
     比如,先下载图片,之后才对图片滤镜美化工作,*/ 
#import "ViewController.h"
@interface ViewController ()
{
    NSOperationQueue *_queue;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // 实例化操作队列NSOperationQueue
    _queue = [[NSOperationQueue alloc] init];
    // 设置操作队列的最大并发数:2
    _queue.maxConcurrentOperationCount = 2;
}

- (IBAction)click {
	// 操作1:NSBlockOperation
    NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载645645645645645-%@", [NSThread currentThread]);
    }];
	// 操作2:NSOperation
    NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"滤镜-%@", [NSThread currentThread]);
    }];
    // op2依赖于op(op执行完,才能执行op2),如先下载图片,再进行美化操作
    [op2 addDependency:op];
	// 添加操作1到操作队列,(会自动开启)
    [_queue addOperation:op];
	// 添加操作1到操作队列,(会自动开启)
    [_queue addOperation:op2];
    //------------------1次添加20个操作到操作队列------------------
    for (int i = 0; i<20; i++) {
        NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"下载图片-%@", [NSThread currentThread]);
        }];
        [_queue addOperation:op];
    }
    //-------------异步全局队列,下载图片,完毕后回到主线程----------------
    dispatch_async(dispatch_get_global_queue
							(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"下载图片-%@", [NSThread currentThread]);
        UIImage *image = nil;
        // 下载完毕,想回到主线程,更新UI界面,同步或异步,只要是主线程队列
        dispatch_sync(dispatch_get_main_queue(), ^{
            _imageView.image = image;
            NSLog(@"刷新ImageView-%@", [NSThread currentThread]);
        });
		// 下载完毕,也可以在主线程中执行方法setImage:,参数是:image
        [_imageView performSelectorOnMainThread:@selector(setImage:) 
								withObject:image waitUntilDone:YES];
    });
}
- (IBAction)click2 {
    NSLog(@"click2-%@", [NSThread currentThread]);
	// performSelectorInBackground最快捷的多线程,不需要自己管理线程
    [self performSelectorInBackground:@selector(test) withObject:nil];    
	// GCD的三种队列之:全局队列 global_queue
    dispatch_queue_t queue = 
				  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	// GCD的三种队列之:串行队列 要手动创建queue_create,第2个参数0即串行
    dispatch_queue_t queue = dispatch_queue_create("myqueue", 0);
	
    dispatch_sync(queue, ^{ // 耗时操作
        NSLog(@"dispatch_async-%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{ // 耗时操作
        NSLog(@"dispatch_async-%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{ // 耗时操作
        NSLog(@"dispatch_async-%@", [NSThread currentThread]);
    });
	
	// C框架中,只要create copy都要release
    // dispatch_release(queue);
}

- (void)test
{
    for (int i = 0; i<900000; i++) {
        NSString *str = [NSString stringWithFormat:@"fsdfsdfdsf----%d", i];
        str = [str stringByAppendingString:@"fsdgdfgdf"];
    }
    NSLog(@"test-%@", [NSThread currentThread]);
}
@end

H:/0917/02_GET_VideosViewController.m
//  VideosViewController.m
//  02-网络请求
//  Created by apple on 13-9-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
/*
	VideosViewController,继承自表格控制器
	用于接收,从上一个控制器,传递过来的数据,进行列表显示
*/
#import "VideosViewController.h"
@interface VideosViewController : UITableViewController
@property (nonatomic, strong) NSArray *videos;
@end
@implementation VideosViewController
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView 
						numberOfRowsInSection:(NSInteger)section
{
    return _videos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView 
					cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	// 优化固定写法
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView
						dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:
				UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
	// 取出字典
    NSDictionary *video = _videos[indexPath.row];
	// 设置独一无二的数据
    cell.textLabel.text = video[@"name"];
    cell.detailTextLabel.text = [NSString stringWithFormat:@"时长:%@", video[@"length"]];
    return cell;
}
@end

H:/0917/02_GET_ViewController.m
//  ViewController.m
//  02-网络请求
//  Created by apple on 13-9-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
/*
 1.向HTTP服务器发送请求
 1> GET
 * 所有参数拼接在URL后面
 * 路径如果包含了中文等字符,需要进行转码 
   [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
 
 2> POST
 * 参数不拼接在URL后面
 * 参数放在请求体里面(body),参数包含了中文,还是需要转码
 
 2.异步\同步请求
 1> 同步请求,sendSynchronousRequest,直接拿到服务器返回的数据
 * NSData *data = [NSURLConnection sendSynchronousRequest:request 
								returningResponse:nil error:nil]
 
 2> 异步请求,sendAsynchronousRequest,返回的数据在response里面
 1) [NSURLConnection sendAsynchronousRequest:request 
				queue:<#(NSOperationQueue *)#> 
				completionHandler:^(NSURLResponse *, NSData *, NSError *) {
 
     }];
 
 2) connectionWithRequest,代理负责接收服务器返回的数据
	NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
												delegate:self];
    // 必须手动启动连接,默认就是异步请求
    [conn start];
	
	
    实现代理方法:接收服务器返回的数据,并且解析数据
 接收服务器的数据时调用(可多次调用)
 - (void)connection:(NSURLConnection *)connection 
					didReceiveData:(NSData *)data
 {
	// 这个代理方法里面,只需要拼接数据即可
    [_allData appendData:data];
 }
 
 数据接收完毕,就会调用,这儿可以正式解析返回的数据
 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {}
 */
#import "ViewController.h"
// 拿到服务器返回的视频列表数据后,要跳到VideosViewController界面去显示
#import "VideosViewController.h"
@interface ViewController () <NSURLConnectionDataDelegate>
{
	// URLConnection的代理方法didReceiveData中,拼接接收到的服务器的数据
    NSMutableData *_allData;
}
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
@end
@implementation ViewController
// 响应按钮点击,登录
- (IBAction)login0 {
    // 1.请求参数,用户名密码
    NSString *username = _username.text;
    NSString *pwd = _pwd.text;
    // 2.拼接URL
    NSString *url = [NSString stringWithFormat:@"http://169.254.109.85:8080/MJServer/login?username=%@&pwd=%@", username, pwd];
    // 对URL中的中文转码
    url = [url stringByAddingPercentEscapesUsingEncoding:
										NSUTF8StringEncoding];
    // 通过url创建 请求对象request
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL 
											URLWithString:url]];
    // 3.NSURLConnection发送同步请求,并获得服务器返回的数据(同步请求)
    NSData *data = [NSURLConnection sendSynchronousRequest:request
									returningResponse:nil error:nil];
    // 3.NSURLConnection发送异步请求,不返回值
    [NSURLConnection sendAsynchronousRequest:request
				queue:<#(NSOperationQueue *)#>
				completionHandler:^(NSURLResponse *, NSData *, NSError *) {
				// 服务器返回的内容在response里面
    }];
    // 4.解析服务器返回的JSON数据
    NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data
							options:NSJSONReadingMutableLeaves error:nil];
    // 5.如果用户名和密码错误,返回的Json中包含error
    NSString *error = result[@"error"];
    if (error) { 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
						message:error delegate:nil cancelButtonTitle:@"好的"
						otherButtonTitles:nil, nil];
        // 显示UIAlertView
		[alert show];
    } else {
        NSLog(@"登录成功-%@", result[@"videos"]);
    }
}
// 响应按钮点击,登录
- (IBAction)login {
    // 1.获取输入框的用户名和密码
    NSString *username = _username.text;
    NSString *pwd = _pwd.text;
    // 2.拼接url
    NSString *url = [NSString stringWithFormat:@"http://169.254.109.85:8080/MJServer/login?username=%@&pwd=%@", username, pwd];
    // 重要!!!!URL参数中的中文必须转码
    url = [url stringByAddingPercentEscapesUsingEncoding:
									NSUTF8StringEncoding];
    // 根据url创建 请求对象request
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL 
											URLWithString:url]];
    // 3.通过request创建Connection对象,并且设置URLConnection的代理
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
													delegate:self];
    // 4.手动启动Connection,默认就是异步请求,其他交给代理处理
    [conn start];
    _allData = [NSMutableData data];
}
#pragma mark URLConnection的代理方法,接收到服务器的数据时调用(可能多次调用)
- (void)connection:(NSURLConnection *)connection 
					didReceiveData:(NSData *)data
{
	// 在代理方法didReceiveData,只需要拼接字符串即可
    [_allData appendData:data];
}
#pragma mark URLConnection的代理方法,数据接收完毕,就会调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // 4.解析服务器返回的JSON
    NSDictionary *result = [NSJSONSerialization JSONObjectWithData:_allData
							 options:NSJSONReadingMutableLeaves error:nil];
    // 5.如果用户名和密码错误,返回数据就会包含error
    NSString *error = result[@"error"];
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" 
					message:error delegate:nil cancelButtonTitle:@"好的"
											otherButtonTitles:nil, nil];
        [alert show];
    } else {
        // 跳到视频列表界面,performSegueWithIdentifier,list是SB中连线设置的
        [self performSegueWithIdentifier:@"list" sender:result[@"videos"]];
    }
}
// 为跳到下一个控制器,作准备,实质是把上面的参数sender传递到下面方法sender
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
	// VideosViewController是要跳至的目标控制器,继承成tableViewController
    VideosViewController *videosVC = segue.destinationViewController;
	// 成员数组,记住当前控制器从服务器要回来的数据,result[@"videos"]
    videosVC.videos = sender;
}
@end

H:/0917/03_POST_VideosViewController.m
//  VideosViewController.m
//  02-网络请求
//  Created by apple on 13-9-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
/*
#import <UIKit/UIKit.h>
@interface VideosViewController : UITableViewController
@property (nonatomic, strong) NSArray *videos;
@end
*/
#import "VideosViewController.h"
@interface VideosViewController ()
@end
@implementation VideosViewController
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView
						numberOfRowsInSection:(NSInteger)section
{
    return _videos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
					cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    NSDictionary *video = _videos[indexPath.row];
    cell.textLabel.text = video[@"name"];
    cell.detailTextLabel.text = [NSString stringWithFormat:@"时长:%@", video[@"length"]];
    return cell;
}
@end

H:/0917/03_POST_ViewController.m
//  ViewController.m
//  02-网络请求
//  Created by apple on 13-9-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
/*
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
- (IBAction)login;
@end
*/
/*
 1.向HTTP服务器发送请求
 1> GET
 * 所有参数拼接在URL后面
 * 路径如果包含了中文等字符,需要进行转码 
   [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
 
 2> POST
 * 参数不拼接在URL后面
 * 参数放在请求体里面(body),参数包含了中文,还是需要转码
 
 2.异步\同步请求
 1> 同步请求
 * NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]
 
 2> 异步请求
 1) [NSURLConnection sendAsynchronousRequest:request queue:<#(NSOperationQueue *)#> completionHandler:^(NSURLResponse *, NSData *, NSError *) {
 
     }];
 
 2) NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
    // 默认就是异步请求
    [conn start];
    实现代理方法:接收服务器返回的数据,并且解析数据
 #pragma mark 接收到服务器的数据时就会调用一次(可能会调用多次)
 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
 {
    [_allData appendData:data];
 }
 
 #pragma mark 请求结束(数据接收完毕)就会调用
 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {}
 */
#import "ViewController.h"
#import "VideosViewController.h"
@interface ViewController () <NSURLConnectionDataDelegate>
{
    NSMutableData *_allData;
}
@end
@implementation ViewController
- (IBAction)login {
    // 1.获取输入框内容
    NSString *username = _username.text;
    NSString *pwd = _pwd.text;
    // 2.post的请求路径
    NSString *url = [NSString stringWithFormat:
					@"http://169.254.178.47:8080/MJServer/login"]; 
    // 通过url创建MutableURLRequest,post专用请求
    NSMutableURLRequest *request = [NSMutableURLRequest
							requestWithURL:[NSURL URLWithString:url]];
    // 必须指定请求方法:POST,大小写无关
    request.HTTPMethod = @"POST";
    // 请求体HTTPBody,中文依然必须转码
    NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@",
												 username, pwd];
    request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
    // 3.发送异步请求,设置代理为当前控制器,默认就是异步请求
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
							delegate:self];
    // 4.必须手动开启conn
    [conn start];
    _allData = [NSMutableData data];
}
#pragma mark 接收到服务器的数据时就会调用一次(可能会调用多次)
- (void)connection:(NSURLConnection *)connection 
				didReceiveData:(NSData *)data
{
	// 唯一作用就是,拼接数据
    [_allData appendData:data];
}
#pragma mark 请求结束(数据接收完毕)就会调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // 4.解析服务器返回的JSON
    NSDictionary *result = [NSJSONSerialization JSONObjectWithData:_allData
							options:NSJSONReadingMutableLeaves error:nil];
    // 5.数据处理
    NSString *error = result[@"error"];
    if (error) { // 如果有错误
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
					message:error delegate:nil cancelButtonTitle:@"好的"
											otherButtonTitles:nil, nil];
        [alert show];
    } else {
        // 跳到视频列表界面,performSegueWithIdentifier,list是sb中连线指定的
        [self performSegueWithIdentifier:@"list" sender:result[@"videos"]];
    }
}
// 为跳至下一个控制之前,作准备,即填充数据,sender是上面传到这儿的,即result[@"videos"]
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
	// 1,先导入头文件,实例化要跳转的目标控制器,并为其成员数组赋值,即result[@"videos"]
    VideosViewController *videosVC = segue.destinationViewController;
    videosVC.videos = sender;
}
@end

H:/0917/04_AFN_ViewController.m
//  ViewController.m
//  04-AFN框架使用,因为ASI已停止更新~
//  Created by apple on 13-9-17.
/*
	AFN依赖3个框架
	security.framework
	systemConfiguration.framework
	mobileCoreServices.framework
*/  
#import "ViewController.h"
#import "AFNetworking.h"
@interface ViewController ()
@end
@implementation ViewController
- (IBAction)click {
    // 1.设置baseURL路径,域名
    NSURL *baseURL = [NSURL URLWithString:
							@"http://169.254.178.47:8080/MJServer"];
	// 通过baseURL创建AFN客户端						
    AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:baseURL];
    // 2.封装请求,多态,因返回URLMutableRequest,参数:方式,路径,请求参数为字典
    NSURLRequest *request = [client requestWithMethod:@"POST" 
							path:@"login" parameters:@{
                             @"username" : @"母鸡",
                             @"pwd" : @"124353"
     }];
    // 3.通过block构造AFHTTPRequestOperation
    AFHTTPRequestOperation *operation = 
			[client HTTPRequestOperationWithRequest:request
			success:^(AFHTTPRequestOperation *operation, id responseObject) {
		// 成功后,解析服务器返回的数据	
        NSDictionary *json = [NSJSONSerialization 
							JSONObjectWithData:responseObject 
							options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@", json);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
		// 失败后,dosomething...
    }];
	// 手动开启AFHTTPRequestOperation
    [operation start];
}
@end

H:/0917/05_下载_ViewController.m
//  ViewController.m
//  05-文件下载
//  Created by apple on 13-9-17.
/*
	AFN依赖3个框架
	security.framework
	systemConfiguration.framework
	mobileCoreServices.framework

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
- (IBAction)download;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
*/
#import "ViewController.h"
// 需导入第3方框架
#import "AFNetworking.h"
@interface ViewController () <NSURLConnectionDataDelegate>
{
	// 唯一作用,拼接数据
    NSMutableData *_imgData;
	// Content-Length
    int _imgTotalLength;
}
@end
@implementation ViewController
/*
	下载图片方式一
	使用默认的NSURLRequest即GET方式下载图片,见方法 defaultDownLoad
	其中设置了代理为当前控制器,遵守协议,处理以下方法:
	didReceiveResponse,从response中head字典中取出:Content-Length
	didReceiveData,唯一作用,拼接数据,更新进度
	connectionDidFinishLoading,下载图片完毕,设置imageView
*/
- (void) defaultDownLoad
{
	// 使用默认的NSURLRequest即GET方式下载图片
	_imgData = [NSMutableData data];
	NSURLConnection *conn = [NSURLConnection 
					connectionWithRequest:[NSURLRequest
					requestWithURL:[NSURL 
					URLWithString:@"http://169.254.178.47:8080/MJServer/lufy.png"]] 
					delegate:self];
	[conn start];
}
#pragma mark 开始接到服务器的响应就会调用
- (void)connection:(NSURLConnection *)connection 
			didReceiveResponse:(NSURLResponse *)response
{
	// 将URLResponse转成子类HTTPURLResponse
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
	// 从response中head字典中取出:Content-Length
    _imgTotalLength = [httpResponse.allHeaderFields[@"Content-Length"]
					   intValue];
}
#pragma mark 接收到服务器返回的数据时调用,可多次调用
- (void)connection:(NSURLConnection *)connection 
					didReceiveData:(NSData *)data
{
	// 唯一作用,拼接数据
    [_imgData appendData:data];
    // 更新进度
    _progressView.progress = (double)_imgData.length / _imgTotalLength;
}
#pragma mark 服务器的数据接收完毕就会调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"下载完毕");
	// 将图片data设置在imageView上面
    _imageView.image = [UIImage imageWithData:_imgData];
}


//--------------------下载图片方式二:使用AFN下载图片,getPath更直接简洁
// 响应点击,开始下载图片data
- (IBAction)download {
    // 1.设置baseUrl路径
    NSURL *baseURL = [NSURL URLWithString:@"http://169.254.178.47:8080/MJServer"];
	// 2.根据baseURL,构建AFHTTPClient
    AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:baseURL];
	// 3.AFHTTPClient的getPath方法,GET请求,如果是POST只改方法名即可
    [client getPath:@"lufy.png" parameters:nil 
		    success:^(AFHTTPRequestOperation *operation, id responseObject) {
		// 下载成功,设置imageView
        _imageView.image = [UIImage imageWithData:responseObject];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        // 失败时,调用
    }];    
}
//--------------------下载图片方式三:使用AFN下载图片,不用代理,一个方法搞定
- (void)test
{	
    // 1.设置baseurl路径
    NSURL *baseURL = [NSURL URLWithString:@"http://169.254.178.47:8080/MJServer"];
    AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:baseURL];
    // 2.requestWithMethod:path:方法 封装URLRequest请求
    NSURLRequest *request = [client requestWithMethod:@"GET"
							path:@"lufy.png" parameters:nil];
    // 3.通过请求,构造AFHTTPRequestOperation
    AFHTTPRequestOperation *operation = [client
				HTTPRequestOperationWithRequest:request
				success:^(AFHTTPRequestOperation *operation, 
				id responseObject) {
		// 下载成功,设置imageView
        _imageView.image = [UIImage imageWithData:responseObject];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
		// 失败时,调用 
    }];
    // 4.手动开启AFHTTPRequestOperation
    [operation start];
    // 5.设置监听器,监听下载进度
    // bytesRead 当前传递的字节数
    // totalBytesRead 已经传递的总字节数
    // totalBytesExpectedToRead 总长度
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, 
			long long totalBytesRead, long long totalBytesExpectedToRead) {
        _progressView.progress = (double)totalBytesRead/totalBytesExpectedToRead;
    }];
}
@end

H:/0917/06_上传_ViewController.m
//  ViewController.m
//  06-文件上传
//  Created by apple on 13-9-17.
/*
将Xcode中的文件,弄到模拟器里面去,android是Push
iOS中用代码:UIImageWriteToSavedPhotoAlbum([UIImage imageNamed:@"1.jpg"],nil,nil,nil);

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)getPhoto;
- (IBAction)upload;
@end
*/
#import "ViewController.h"
#import "AFNetworking.h"
@interface ViewController () <UIActionSheetDelegate,
			UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@end
@implementation ViewController
// 响应按钮点击,选取要上传的相片
- (IBAction)getPhoto {
	// 构造并弹出UIActionSheet动作列表,供用户选择相片来源
    UIActionSheet *sheet = [[UIActionSheet alloc]
				initWithTitle:@"请选择图片" delegate:self
				cancelButtonTitle:@"取消" destructiveButtonTitle:nil
				otherButtonTitles:@"拍照", @"相册", nil];
    [sheet showInView:self.view.window];
}
// UIActionSheet的代理方法,当用户点击了动作列表中的某个按钮时候调用
- (void)actionSheet:(UIActionSheet *)actionSheet
			clickedButtonAtIndex:(NSInteger)buttonIndex
{
	// 实例化照片选择器,UIImagePickerController,并根据按钮索引设置相片来源
    UIImagePickerController *vc = [[UIImagePickerController alloc] init];
    switch (buttonIndex) {
        case 0: // 拍照
            vc.sourceType = UIImagePickerControllerSourceTypeCamera;
            break;
        case 1: // 相册
            vc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            break;
        default:
            break;
    }
    // 设置ImagePickerController的代理为当前控制器,处理选择相片之后的事件
    vc.delegate = self;
    // 展示相片选择控制器
    [self presentViewController:vc animated:YES completion:nil];
}
#pragma mark ImagePickerController的代理方法,拍照完毕或从相册中取完相片时调用
- (void)imagePickerController:(UIImagePickerController *)picker
					didFinishPickingMediaWithInfo:(NSDictionary *)info
{
	// 获取源图
    UIImage *image = info[UIImagePickerControllerOriginalImage];
	// 设置imageView
    _imageView.image = image;
    // 选择相片完毕,必须手动关闭控制器UIImagePickerController
    [picker dismissViewControllerAnimated:YES completion:nil];
}
// 响应按钮点击,AFN构造multipartFormRequest上传图片到服务器
- (IBAction)upload {
    // 1.设置基准路径
    AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL 
						 URLWithString:@"http://169.254.178.47:8080/MJServer"]];
    // 2.构建NSURLRequest,multipartFormRequestWithMethod
    NSURLRequest *request = [client multipartFormRequestWithMethod:@"POST" 
							path:@"upload" parameters:@{
							@"username" : @"123",
							@"pwd":@"456"}
        constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        // 上传Default.png
        [formData appendPartWithFileURL:[[NSBundle mainBundle]
							URLForResource:@"Default" withExtension:@"png"]
							name:@"file" error:nil];
        // 上传新获得的图片文件
        NSData *data = UIImagePNGRepresentation(_imageView.image);
        [formData appendPartWithFileData:data name:@"file"
								fileName:@"456.png" mimeType:@"image/png"];
            
        // 上传artifacts.xml
        [formData appendPartWithFileURL:[[NSBundle mainBundle] 
						URLForResource:@"artifacts" withExtension:@"xml"] 
						name:@"file" error:nil];
        
        // 上传epl-v10.html
        [formData appendPartWithFileURL:[[NSBundle mainBundle] 
						URLForResource:@"epl-v10" withExtension:@"html"] 
						name:@"file" error:nil];
    }];
    
    // 3.通过请求构造AFHTTPRequestOperation
    AFHTTPRequestOperation *operation = [client
							HTTPRequestOperationWithRequest:request
							success:nil failure:nil];
	// 4.手动启动AFHTTPRequestOperation
    [operation start];
}
@end

H:/0917/07_视频播放_PlayViewController.m
//  PlayViewController.m
//  07-视频播放
//  Created by apple on 13-9-17.
/*
	播放音乐:AVAudioFoundation
	播放音效:SystemSoundID
	播放视频:MPMoviePlayerViewController 只能全屏
	播放视频:MPMoviePlayerController
			 尺寸可以任意大小,继承自NSObject,但成员有view
			 PlayerController状态改变的时候,不是用代理,而是通知
			 当didFinish的时候,收听到了通知,并手动退出全屏
			 
	autoresizingMask 随着屏幕宽高自动伸缩~~~
    _player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |
									UIViewAutoresizingFlexibleHeight;
									
	#pragma mark 要想横屏,必须支持自动旋转
	- (BOOL)shouldAutorotate
	{
		return YES;
	}
	#pragma mark 要想横屏,必须只支持横屏方向
	- (NSUInteger)supportedInterfaceOrientations
	{
		return UIInterfaceOrientationMaskLandscape;
	}
*/
#import "PlayViewController.h"
#import <MediaPlayer/MediaPlayer.h>
/*
	本控制器,是由上一个控制器,利用trigger segues方法modal(非push)过来的,
	performSegueWithIdentifier:@"play",play是SB中写死的
	而且切换过程中,SB中设置了无动画,
	一进入本控制器,即开始横屏且全屏播放视频
	一旦didFinish播放完毕,则退出全屏
	一旦退出全屏,则dismiss本控制器,回显上一个控制器	
*/
@interface PlayViewController ()
{
	// 成员:视频播放控制器
    MPMoviePlayerController *_player;
}
@end
@implementation PlayViewController
- (void)viewDidLoad
{
    [super viewDidLoad];	
	// 从mainBundle中加载视频文件,url
    NSURL*url = [[NSBundle mainBundle] URLForResource:@"sample_iTunes" 
												withExtension:@"mov"];
	// 根据url,实例化 视频播放控制器											
    _player = [[MPMoviePlayerController alloc] initWithContentURL:url];
    // 设置 视频播放控制器 为全屏播放
    _player.view.frame = self.view.bounds;
	// autoresizingMask 随着屏幕宽高自动伸缩~~~
    _player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |
									UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:_player.view];
    // 手动播放 视频播放控制器
    [_player play];
    // 监听通知
    // 播放状态改变的通知:播放\暂停
    [[NSNotificationCenter defaultCenter] addObserver:self 
			selector:@selector(stateChange)
			name:MPMoviePlayerPlaybackStateDidChangeNotification object:_player];
    // 播放完毕的通知:目的是退出全屏
    [[NSNotificationCenter defaultCenter] addObserver:self
			selector:@selector(didFinish) 
			name:MPMoviePlayerPlaybackDidFinishNotification object:_player];
    // 截取到某个时间段的图片的通知
    [[NSNotificationCenter defaultCenter] addObserver:self
			selector:@selector(captureImage:) 
			name:MPMoviePlayerThumbnailImageRequestDidFinishNotification
			object:_player];
    // 当用户退出全屏的通知时,就回到上一个控制器
    [[NSNotificationCenter defaultCenter] addObserver:self
			selector:@selector(exitFullScreen) 
			name:MPMoviePlayerDidExitFullscreenNotificationobject:_player];
    // 截图,精确播放到第3.0秒和第7.0秒时,发送通知,并将截的图作参传递过去 
	// 这儿有个陷阱,必须是小数,单位是秒
    [_player requestThumbnailImagesAtTimes:@[@3.0, @7.0]
						timeOption:MPMovieTimeOptionExact];
}
#pragma mark 要想横屏,必须支持自动旋转
- (BOOL)shouldAutorotate
{
    return YES;
}
#pragma mark 要想横屏,必须只支持横屏方向
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

#pragma mark ios 5.0之前的方法
- (BOOL)shouldAutorotateToInterfaceOrientation:
					(UIInterfaceOrientation)toInterfaceOrientation
{
    return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
// 方法,播放器状态改变的时候,调用
/*
 MPMoviePlaybackState Stopped,停止
 MPMoviePlaybackState Playing, 播放
 MPMoviePlaybackState Paused, 暂停
 MPMoviePlaybackState Interrupted, 中断
 MPMoviePlaybackState SeekingForward, 快进
 MPMoviePlaybackState SeekingBackward 快退
 */
- (void)stateChange
{
    switch (_player.playbackState) {
        case MPMoviePlaybackStatePlaying:
            NSLog(@"---播放");
            // 一开始播放,就全屏,本方法如果在view未显示之前调用无效
            [_player setFullscreen:YES animated:YES];
            break;
        case MPMoviePlaybackStatePaused:
            NSLog(@"---暂停");
            break;
        case MPMoviePlaybackStateStopped:
            NSLog(@"---停止");
            break;
        default:
            break;
    }
}
// 方法,播放器截屏的时候,调用
- (void)captureImage:(NSNotification *)note
{
    UIImage *image = note.userInfo[MPMoviePlayerThumbnailImageKey];
    
    // NSLog(@"---%@", image);
    NSString *file = [NSString stringWithFormat:@"/Users/apple/Desktop/%d.jpg", arc4random()];
	// JPEGRepresentation的第2个参数是压缩比
    [UIImageJPEGRepresentation(image, 0.5) writeToFile:file atomically:YES];
}
// 方法,播放完毕的时候调用,目的是退出全屏
- (void)didFinish
{
    [_player setFullscreen:NO animated:YES];
}
// 方法,当用户退出全屏的时候调用,关闭当前控制器,回到上一个控制器
- (void)exitFullScreen
{
    [self dismissViewControllerAnimated:NO completion:nil];
}
@end

H:/0917/07_视频播放_ViewController.m
//  ViewController.m
//  07-视频播放
//  Created by apple on 13-9-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 响应按钮点击,进入下一个控制器,Identifier:@"play"是在SB连线的时候写的
- (void)play
{
    [self performSegueWithIdentifier:@"play" sender:nil];
}
@end

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值