选择本地图片并上传是应用开发中一个比较常见的功能。
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1174.html
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1174.html
我们使用 UIImagePickerController 可以很方便的从系统“照片”中选择图片,但我们会发现选择完毕后,通过图片的 info[UIImagePickerControllerReferenceURL] 得到的是一个引用路径,格式如下:
用这个路径是没法上传文件的。想要把选择的图片上传,通常我们会想到如下两种方式:
不管使用模拟器还是真机调试,运行后可以看到图片上传成功了:
1
|
assets-library: //asset/asset.PNG?id=90B54369-5E79-433D-B74A-E8E0870EAF27&ext=PNG |
方法一:先将图片保存到一个临时文件夹下,再上传
下面样例在 imagePickerController 选择图片后,使用 fileManager 将其复制保存到应用的文档目录下,再将复制过来的图片上传。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
import UIKit import Alamofire class ViewController : UIViewController , UIImagePickerControllerDelegate , UINavigationControllerDelegate { override func viewDidLoad() { super .viewDidLoad() } //选取相册 @IBAction func fromAlbum(sender: AnyObject ) { //判断设置是否支持图片库 if UIImagePickerController .isSourceTypeAvailable(. PhotoLibrary ){ //初始化图片控制器 let picker = UIImagePickerController () //设置代理 picker.delegate = self //指定图片控制器类型 picker.sourceType = UIImagePickerControllerSourceType . PhotoLibrary //弹出控制器,显示界面 self .presentViewController(picker, animated: true , completion: { () -> Void in }) } else { print ( "读取相册错误" ) } } //选择图片成功后代理 func imagePickerController(picker: UIImagePickerController , didFinishPickingMediaWithInfo info: [ String : AnyObject ]) { //获取选择的原图 let pickedImage = info[ UIImagePickerControllerOriginalImage ] as ! UIImage //将选择的图片保存到Document目录下 let fileManager = NSFileManager .defaultManager() let rootPath = NSSearchPathForDirectoriesInDomains (. DocumentDirectory , . UserDomainMask , true )[0] as String let filePath = "(rootPath)/pickedimage.jpg" let imageData = UIImageJPEGRepresentation (pickedImage, 1.0) fileManager.createFileAtPath(filePath, contents: imageData, attributes: nil ) //上传图片 if (fileManager.fileExistsAtPath(filePath)){ //取得NSURL let imageNSURL: NSURL = NSURL . init (fileURLWithPath: filePath) //使用Alamofire上传 .responseString { response in print ( "Success: (response.result.isSuccess)" ) print ( "Response String: (response.result.value)" ) } } //图片控制器退出 picker.dismissViewControllerAnimated( true , completion: nil ) } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |
方法二:使用PhotoKit获取选择图片的真实路径,再上传
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
在这里留下你想说的话。 import UIKit import Alamofire import Photos class ViewController : UIViewController , UIImagePickerControllerDelegate , UINavigationControllerDelegate { override func viewDidLoad() { super .viewDidLoad() } //选取相册 @IBAction func fromAlbum(sender: AnyObject ) { //判断设置是否支持图片库 if UIImagePickerController .isSourceTypeAvailable(. PhotoLibrary ){ //初始化图片控制器 let picker = UIImagePickerController () //设置代理 picker.delegate = self //指定图片控制器类型 picker.sourceType = UIImagePickerControllerSourceType . PhotoLibrary //弹出控制器,显示界面 self .presentViewController(picker, animated: true , completion: { () -> Void in }) } else { print ( "读取相册错误" ) } } //选择图片成功后代理 func imagePickerController(picker: UIImagePickerController , didFinishPickingMediaWithInfo info: [ String : AnyObject ]) { //选择图片的引用路径 let pickedURL: NSURL = info[ UIImagePickerControllerReferenceURL ] as ! NSURL let fetchResult: PHFetchResult = PHAsset .fetchAssetsWithALAssetURLs([pickedURL], options: nil ) let asset: PHAsset = fetchResult.firstObject as ! PHAsset PHImageManager .defaultManager() .requestImageDataForAsset(asset, options: nil , resultHandler: { (imageData: NSData ?, dataUTI: String ?, orientation: UIImageOrientation , info: [ NSObject : AnyObject ]?) in //获取实际路径 let imageNSURL: NSURL = info![ "PHImageFileURLKey" ] as ! NSURL print ( "路径:" ,imageNSURL) print ( "文件名:" ,imageNSURL.lastPathComponent) //使用Alamofire上传 .responseString { response in print ( "Success: (response.result.isSuccess)" ) print ( "Response String: (response.result.value)" ) } }) //图片控制器退出 picker.dismissViewControllerAnimated( true , completion: nil ) } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |
但如果使用真机调试的话,虽然我们得到了图片的真实路径和文件名,但还是无法上传。所以上传图片还是建议使用方法一。
附录:
(1)本文样例使用 Alamofire 上传文件,对于Alamofire不熟悉的可参考我原来写过的几篇文章:
Swift - HTTP网络操作库Alamofire使用详解1(配置,以及数据请求)Swift - HTTP网络操作库Alamofire使用详解2(文件上传)
(2)服务端php代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?php /** php 接收流文件 * @param String $file 接收后保存的文件名 * @return boolean */ function receiveStreamFile( $receiveFile ){ $streamData = isset( $GLOBALS [ 'HTTP_RAW_POST_DATA' ])? $GLOBALS [ 'HTTP_RAW_POST_DATA' ] : '' ; if ( empty ( $streamData )){ } if ( $streamData != '' ){ $ret = file_put_contents ( $receiveFile , $streamData , true); } else { $ret = false; } return $ret ; } //定义服务器存储路径和文件名 $receiveFile = $_SERVER [ "DOCUMENT_ROOT" ]. "/uploadFiles/hangge.zip" ; $ret = receiveStreamFile( $receiveFile ); echo json_encode( array ( 'success' =>(bool) $ret )); ?> |
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1174.html