选择本地图片并上传是应用开发中一个比较常见的功能。 原文出自: 转载请保留原文链接:
我们使用 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上传 Alamofire .upload(. POST , "" , file: imageNSURL) .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 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上传 Alamofire .upload(. POST , "" , file: imageNSURL) .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不熟悉的可参考我原来写过的几篇文章:
(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 )){ $streamData = file_get_contents ( 'php://input' ); } 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 )); ?> |
原文出自: 转载请保留原文链接: