您的位置:首页 > 移动开发 > IOS开发

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

2017-05-12 14:51 441 查看

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;
}
}

}


全部实现过程就是这些,仅供参考。如有疑问欢迎骚扰
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息