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