IOS 调用WebService 实现图片上传处理的解决办法

IOS 调用WebService 实现图片上传处理的解决办法

         IOS 图像上传,包括多图上传等是比较常见的需求。由于服务端使用的编程语言不同,具体实现也有不同。本文主要介绍了 IOS中通过Webservice(C# 语言)实现图片上传。

在上车之前,我们先约法三章,把逻辑梳理一下。

1、IOS 客户端 提交数据

     IOS 我们使用 AFHTTPRequestOperation 第三方框架。使用的编程语言Swift3。我们用过 UIImagePickerViewController 对象打开相册或者拍照,在 didFinishPickingMediaWithInfo 中取到 UIImage 对象。这里需要主要的是,需要使用 Base64 对 NSData(NSData 通通过 UIImagePNGRepresentation 得到) 转换为 字符串。

使用 NSOperationQueue(OperationQueue) 线程实现多图上传。具体参考代码如下:

import UIKit

//MARK: - FileUploadDelegate
protocol FileUploadDelegate {
    
    /**
     * 上传完成回调
     * @return imageUrl String  上传成功的图片地址
     */
    func uploadDidFinishSuccess(imageUrls:String);
    
    /**
     * 上传失败
     * @return strErrorInfo String 上传失败的错误信息
     */
    func uploadDidFinishError(strErrorInfo:String);

}

//MARK: - 文件上传
/**
 * 文件上传类
 */
class FileUpload {
    
    /**
     * 图片上传
     *
     * @paramater imageTypes [String] 图片后缀
     * @imageDatas [Data]             对应图片的数据
     */
    static func uploadImages(imageTypes:[String],imageDatas:[Data], andDelegate delegate:FileUploadDelegate){
     
        let manager = AFHTTPRequestOperationManager.init()
        let strUploadUrl = String.init(format:"%@%@",K_APP_HOST,K_APP_IMAGE_UPLOAD)
        
        var request:URLRequest?
        var requestOperation:AFHTTPRequestOperation?
        var httpSerializer:AFHTTPRequestSerializer?
        
        do{
            //参数
            for i in 0..<imageDatas.count {
                
                httpSerializer = AFHTTPRequestSerializer.init()
                request = try httpSerializer?.multipartFormRequest(withMethod: "POST", urlString: strUploadUrl, parameters: nil, constructingBodyWith: { (formData:AFMultipartFormData?) in
                    formData?.appendPart(withForm: String(imageTypes[i])?.data(using: .utf8), name: "imagesType")
                    
                    let strImgTemp = imageDatas[i].base64EncodedString()
                    formData?.appendPart(withForm: strImgTemp.data(using: .utf8), name: "imagesData")
                    
                }, error: ()) as URLRequest?
                
                requestOperation = AFHTTPRequestOperation.init(request: request)
                
                //上传进度
                requestOperation?.setUploadProgressBlock({ (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
                    print("\(bytesWritten) => \(totalBytesWritten) => \(totalBytesExpectedToWrite)")
                })
                
                requestOperation?.setCompletionBlockWithSuccess({ (operation:AFHTTPRequestOperation?, responseObject:Any?) in
                    
                    var strMsg = "上传失败"
                    if let dicData:[String:AnyObject] = getWebserviceData(strResponseString: (operation?.responseString)!) {
                        
                        if let code = dicData["code"] as? Int,code == 0 {
                            print("上传成功!")
                            
                            DispatchQueue.main.async {
                                delegate.uploadDidFinishSuccess(imageUrls: dicData["data"] as! String)
                            }
                            return
                        }
                        
                        strMsg = dicData["msg"] as! String
                    }
                    
                    DispatchQueue.main.async {
                        delegate.uploadDidFinishError(strErrorInfo: strMsg)
                    }
                    
                }, failure: { (operation:AFHTTPRequestOperation?, error:Error?) in
                    print("上传失败!详见:\(String(describing: error))")
                    
                    DispatchQueue.main.async {
                        delegate.uploadDidFinishError(strErrorInfo: (error?.localizedDescription)!)
                    }
                })
                
                manager.operationQueue.addOperation(requestOperation!)
            }
        }
        catch {
            print("上传异常!详见:\(error)")
            
            DispatchQueue.main.async {
                delegate.uploadDidFinishError(strErrorInfo: error.localizedDescription)
            }
        }
        
    }
}

2、服务端接收数据

     服务端通过 HttpContext.Current.Request 接收相关请求的数据。具体代码参考如下:

		#region 图片上传
		/// <summary>
		/// 图片上传
		/// </summary>
		/// <param name="contexta"></param>
		/// <returns></returns>
		[WebMethod(Description = "进场检查-图片上传")]
		public string UploadImages()
		{
			HttpRequest httpRequest = HttpContext.Current.Request;

			ResultClass result = new ResultClass()
			{
				data = ""
			};

			try
			{
				string imagesType = httpRequest["imagesType"].ToString();
				byte[] image = Convert.FromBase64String(httpRequest["imagesData"].ToString());

				if (image != null && image.Length > 0)
				{

					//判断文件类型是否符合要求
					List<string> imgType = ConfigurationManager.AppSettings["ImageType"].Split('|').ToList();

					if (!imgType.Contains(imagesType.ToLower()))
					{
						result.code = -1;
						result.msg = "文件格式有误! \n支持的图片格式为:" + string.Join("|", imgType);
						return JsonHelper.GetJson(result);
					}

					//判断图片大小
					int size = int.Parse(ConfigurationManager.AppSettings["ImageSize"].ToString()) * 1024 * 1024;
					if (image.Length <= size)
					{

						//定义Bitmap对象
						Bitmap bmp = new Bitmap(new MemoryStream(image));

						//保存
						string fileName = DateTime.Now.ToString("yyyyMMddhhmmss") + GenerateRandomNumber(10) + "." + imagesType;
						string file = GetFileSrc() + "/" + fileName;

						bmp.Save(HttpContext.Current.Server.MapPath(file));

						//判断是否成功
						if (File.Exists(HttpContext.Current.Server.MapPath(file)))
						{
							//保存成功,返回相对地址
							result.code = 0;
							result.msg = "上传成功";

							result.data = fileName;
						}
						else
						{
							result.code = -2;
							result.msg = "图片文件保存失败";
						}
						return JsonHelper.GetJson(result);
					}
					else
					{
						result.code = -3;
						result.msg = "图片大小不超过" + size + "字节(Byte),当前图片:" + image.Length + "字节";
						return JsonHelper.GetJson(result);
					}
				}
				else
				{
					result.code = -4;
					result.msg = "文件路径有误";
					return JsonHelper.GetJson(result);
				}
			}
			catch (Exception ex)
			{
				result.code = -5;
				result.msg = ex.Message;
				return JsonHelper.GetJson(result);
			}
		}


		/// <summary>
		/// 获取保存路径
		/// </summary>
		/// <returns></returns>
		private string GetFileSrc()
		{
			//判断该域名下,是否有对应文件夹
			string dt = DateTime.Now.ToString("yyyyMMdd");
			string path = "Images/" + dt;

			if (!Directory.Exists(HttpContext.Current.Server.MapPath(path)))
				Directory.CreateDirectory(HttpContext.Current.Server.MapPath(path));

			return path;
		}


		/// <summary>
		/// 返回指定文件流数组
		/// </summary>
		/// <param name="stream"></param>
		/// <returns></returns>
		private byte[] ConvertFileToByteBuffer(Stream stream)
		{
			int b = new int();
			MemoryStream memostream = new MemoryStream();
			while ((b = stream.ReadByte()) != -1)
			{
				memostream.WriteByte((byte)b);
			}

			return memostream.ToArray();
		}

		private static char[] constant =
	  {
		'0','1','2','3','4','5','6','7','8','9',
		'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
	  };

		/// 生成随机数
		/// </summary>
		/// <param name="Length">随机数长度</param>
		/// <returns>string</returns>
                public static string GenerateRandomNumber(int Length){
                         System.Text.StringBuilder newRandom = new System.Text.StringBuilder(62);
                         Random rd = new Random();
                         for (int i = 0; i < Length; i++){
                              newRandom.Append(constant[rd.Next(62)]);
                         }
                         return newRandom.ToString();
                 }
            #endregion

JsonHelper 辅助文件:

public class JsonHelper
	{
		public JsonHelper()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		/// <summary>
		/// 把对象序列化 JSON 字符串 
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="obj">对象实体</param>
		/// <returns>JSON字符串</returns>
		public static string GetJson<T>(T obj)
		{
			//记住 添加引用 System.ServiceModel.Web 
			/**
			 * 如果不添加上面的引用,System.Runtime.Serialization.Json; Json是出不来的哦
			 */
			DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(T));
			using (MemoryStream ms = new MemoryStream())
			{
				json.WriteObject(ms, obj);
				string szJson = Encoding.UTF8.GetString(ms.ToArray());
				return szJson;
			}
		}

		/// <summary>
		/// 把JSON字符串还原为对象
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="szJson">JSON字符串</param>
		/// <returns>对象实体</returns>
		public static T ParseFormJson<T>(string szJson)
		{
			T obj = Activator.CreateInstance<T>();
			using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
			{
				DataContractJsonSerializer dcj = new DataContractJsonSerializer(typeof(T));
				return (T)dcj.ReadObject(ms);
			}
		}
	}

ResultClass 辅助类:
public class ResultClass
	{
		/// <summary>
		/// 状态 0 成功 其他 失败
		/// </summary>
		public int code { get; set; }

		/// <summary>
		/// 描述信息
		/// </summary>
		public string msg { get; set; }


		/// <summary>
		/// 返回的结果(对应查询时返回的 DataTable,其他为 "")
		/// </summary>
		private object _data;
		public object data
		{
			get
			{
				return _data == null ? "" : _data;
			}

			set
			{
				_data = value;
			}
		}

	}


全部实现过程就是这些,仅供参考。如有疑问欢迎骚扰


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追夢秋陽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值