为什么我下载到同一条路径时会得到不同的图像? [英] why i get different image when downloading to the same path?
问题描述
我正在尝试调试用于上传图像的一大块代码,并从我自己的服务器下载该图像。
图像路径为
我们可以看到,该文件夹中有两个图像,相同图像,但不同的名称。当我在下载图像时硬编码路径时,我得到了一个奇怪的结果
如果avatarPath!= nil {
let x =http://localhost/Twitter/Avatar/52/avatar.jpeg
let imageURL = URL(string:x)
let session = URLSession(configuration :.default)
let task = session.dataTask(with:imageURL!,completionHandler:{(data,response,error)in
DispatchQueue.main.async {
if let imageData = data {
self.avatarImage.image = UIImage(data:imageData)
}
}
})
task.resume()
}
// avatar的圆形旅行者
avatarImage.layer.cornerRadius = avatarImage.bounds.width / 20
avatarImage.clipsToBounds = true
//为导航控制器提供标题
self.navigationItem.title = username.uppercased()
activityIndicator.stopAnimating()
}
当我写x =
但当我更改为let x =
I一旦在第一次上传图像时实际使用了该图像,我不知道为什么那个图像再次出现。我还没有实现缓存图像。为什么会这样?
这里是完整的源代码
import UIKit
class HomepageVC:UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate {
@IBOutlet weak var avatarImage:UIImageView!
@IBOutlet weak var usernameLabel:UILabel!
@IBOutlet weak var fullnameLabel:UILabel!
@IBOutlet weak var emailLabel:UILabel!
@IBOutlet weak var editAvatarButton:UIButton!
@IBOutlet weak var activityIndicator:UIActivityIndicatorView!
覆盖func viewDidLoad(){
super.viewDidLoad()
activityIndicator.startAnimating()
// mendeklarasikan变量用户yang berasal dari superglobal变量di appdelegate
let username = userInfo?[username] as!字符串
让fullname = userInfo?[fullname]为!字符串
让email = userInfo?[email]为!字符串
让avatarPath = userInfo?[avatar]为?字符串
//更新用户界面文本&标签
usernameLabel.text = username.uppercased()
fullnameLabel.text = fullname.capitalized
emailLabel.text = email
//更新用户界面头像
如果avatarPath!= nil {
let x =http://localhost/Twitter/Avatar/52/pogba.jpeg
let imageURL = URL(string:x)
let session = URLSession(configuration:.default)
let task = session.dataTask(with:imageURL!,completionHandler:{(data
,补偿,错误)DispatchQueue.main.async {
如果让imageData = data {
self.avatarImage.image = UIImage(data:imageData)
}
}
})
task.resume()
}
// avatar的圆形传递者
avatarImage.layer.cornerRadius = avatarImage.bounds.width / 20
avatarImage.clipsToBounds = true
/ /给导航控制器的标题
self.navigationItem.title = username.uppercased()
activityIndicator.stopAnimating()
}
@IBAction func logoutButtonDidPressed(_ sender:Any){
// menghapus data userDefault yang sudah ada
UserDefaults.standard.removeObject(forKey:parsedJSON)
UserDefaults.standard.synchronize()
// menuju ke login page dengan modal segue
let storyboard = UIStoryboard(name:Main,bundle:nil)
let loginVC = storyboard.instantiateViewController(withIdentifier:loginVC)
present(loginVC,animated: true,完成:nil)
}
@IBAction func editProfilePictureButtonDidPressed(_ sender:Any){
//用户akan memilih照片dari图书馆atau dari相机nya
让imagePickerController = UIImagePickerController()
imagePickerController.dele gate = self
imagePickerController.allowsEditing = true
let actionSheet = UIAlertController(标题:Photo Source,消息:请选择你的来源,preferredStyle :.actionSheet)
//动作相机
让actionCamera = UIAlertAction(标题:相机,样式:.default){(动作)
如果UIImagePickerController.isSourceTypeAvailable(.camera){
imagePickerController.sourceType = .camera
self.present(imagePickerController,animated:true,completion:nil)
} else {
self.showAlert(alertTitle:Opppss,alertMessage:相机无法使用/不可用,actionTitle:OK)
print(相机无法使用/不可用)
}
}
//动作照片库
让actionPhotoLibrary = UIAlertAction(标题:照片库, style:.default){(action)in
imagePickerCon troller.sourceType = .photoLibrary
self.present(imagePickerController,animated:true,completion:nil)
}
//动作取消
let actionCancel = UIAlertAction(标题:取消,样式:.cancel,处理程序:nil)
actionSheet.addAction(actionCamera)
actionSheet.addAction(actionPhotoLibrary)
actionSheet.addAction(actionCancel)
self.present(actionSheet,animated:true,completion:nil)
}
func imagePickerController(_ picker:UIImagePickerController,didFinishPickingMediaWithInfo info:[String:Any]){
让image = info [UIImagePickerControllerOriginalImage]为! UIImage
avatarImage.image = image
picker.dismiss(animated:true,completion:nil)
//调用上传文件的函数server
uploadAvatar()
}
func imagePickerControllerDidCancel(_ picker:UIImagePickerController){
picker.dismiss(animated:true,completion:nil)
}
//自定义HTTP请求正文上传图片文件
func createBodyWithParams(_ parameters:[String:String] ?, filePathKey:String?,imageDataKey:Data,boundary:String) - >数据{
var body = Data();
if参数!= nil {
for(key,value)参数! {
body.appendString( - \(boundary)\\\\ n)
body.appendString(Content-Disposition:form-data; name = \\( key)\\\\\\\ n)
body.appendString(\(value)\\\\ n)
}
}
// kita set agar image yang di upload kemudian berformat .jpg
let filename =avatar.jpeg
let mimetype =image / jpeg
body.appendString( - \(boundary)\\\\ n)
body.appendString(Content-Disposition:form-data; name = \ \(filePathKey!)\; filename = \\(filename)\\\\\ n)
body.appendString(Content-Type:\(mimetype)\\ \ \\\\\ n)
body.append(imageDataKey)
body.appendString(\\\\ n)
body。 appendString( - \(boundary) - \\\\ n)
返回正文数据
}
//上传图片e ke服务器
func uploadAvatar(){
// mendapatkan ID dari用户默认变量
let id = userInfo![id]如! String
// membuat request
let url = URL(string:http://localhost/Twitter/uploadAvatar.php)!
var request = URLRequest(url:url)
request.httpMethod =POST
//参数yang akan dikirim di dalam request body
//参数ini dibutuhkan karena uploadAvatar.php membutuhkan inputan ID
let param = [id:id]
// membuat Boundary
let boundary =Boundary-\ (UUID()。uuidString)
request.setValue(multipart / form-data; boundary = \(boundary),forHTTPHeaderField:Content-Type)
// mengassign image yang akan di upload dan melakukan kompresi
let imageData = UIImageJPEGRepresentation(avatarImage.image!,0.5)
//如果没有压缩,则返回...不要继续代码
如果imageData == nil {
返回
}
//构建http body
request.httpBody = createBodyWithParams(param,filePathKey:file,imageDataKey:imageData !, boundary:boundary)
// filePathKey berupa文件'agar nanti di PHP $ _FILES bisa didentifikasi,contohnya $ _FILES ['file'] [tmp_name]
// launc session
URLSession.shared.dataTask(with:请求){数据,响应,错误
DispatchQueue.main.async(执行:{
如果错误== nil {
// maka tampilkan $ returnArray dari PHP(来自服务器的响应消息)
do {
// json包含来自php的$ returnArray
让json =尝试JSONSerialization.jsonObject(with:data!,options:[])为? NSDictionary
//声明新的parseJSON来存储json
guard let parsedJSON = json else {
print(解析时出错)
return
}
print(parsedJSON)
//从PHP中的$ returnArray [id]获取id - parseJSON [id]
let id = parsedJSON [id]
//成功上传
if id!= nil {
//保存用户信息yang berasal dari server
UserDefaults.standard.set(parsedJSON,forKey:parsedJSON)
userInfo = UserDefaults.standard.object(forKey:parsedJSON)as? NSDictionary
// jika tidak adaidkiriman dari服务器,maka ada错误消息
} else {
//获取主队列与用户进行通信
DispatchQueue.main.async(执行:{
let message = parsedJSON [message] as!String
self .showAlert(alertTitle:opppps,alertMessage:message,actionTitle:OK)
})
}
//错误ketika melakukan JSON序列化
} catch {
//获取主队列与用户进行通信
DispatchQueue.main.async(执行:{
let message = error.localizedDescription
self.showAlert(alertTitle:SorryBroooo,alertMessage:message,act ionTitle:OK)
})
}
//错误ketika koneksi ke服务器
} else {
//让主队列与用户进行通信
DispatchQueue.main.async(执行:{
let message = error!.localizedDescription
self.showAlert(alertTitle:oppps,alertMessage :message,actionTitle:OK)
})
}
})
} .resume( )
}
}
//扩展数据
扩展数据{
mutating func appendString(_ string :String){
let data = string.data(using:String.Encoding.utf8,allowLossyConversion:true)
append(data!)
}
}
使用此代码时
让session = URLSession(配置:.default )
您已自动注册默认缓存策略,它使用此处指定的基于持久磁盘的缓存链接:
https://developer.apple.com/documentation/ foundation / urlsessionconfiguration / 1411560-default
如果要删除所有缓存策略,请改用此代码
让session = URLSession(配置:.ephemeral)
I am trying to debug a chunk of code used to upload an image and download that image from my own server.
The image path is "http://localhost/Twitter/Avatar/52/avatar.jpeg"
as we can see, there are two images in that folder, same image but different name. I got a weird result when I hard coded the path when downloading the image
if avatarPath != nil {
let x = "http://localhost/Twitter/Avatar/52/avatar.jpeg"
let imageURL = URL(string: x)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: imageURL!, completionHandler: { (data, response, error) in
DispatchQueue.main.async {
if let imageData = data {
self.avatarImage.image = UIImage(data: imageData)
}
}
})
task.resume()
}
// round courner of avatar
avatarImage.layer.cornerRadius = avatarImage.bounds.width/20
avatarImage.clipsToBounds = true
//Give title to navigation controller
self.navigationItem.title = username.uppercased()
activityIndicator.stopAnimating()
}
when I write let x = "http://localhost/Twitter/Avatar/52/pogba.jpeg"
I go the same image as the path, like this
but when I change to let x = "http://localhost/Twitter/Avatar/52/avatar.jpeg"
I got different image, like this
I once used that image actually when the first time uploading an image, but I don't know why that image appears again. I have not implemented caching image yet. why this happens?
here is the full source code
import UIKit
class HomepageVC: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@IBOutlet weak var avatarImage: UIImageView!
@IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var fullnameLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!
@IBOutlet weak var editAvatarButton: UIButton!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator.startAnimating()
// mendeklarasikan variable user yang berasal dari superglobal variable di appdelegate
let username = userInfo?["username"] as! String
let fullname = userInfo?["fullname"] as! String
let email = userInfo?["email"] as! String
let avatarPath = userInfo?["avatar"] as? String
// update user interface text & Label
usernameLabel.text = username.uppercased()
fullnameLabel.text = fullname.capitalized
emailLabel.text = email
// update user interface avatar
if avatarPath != nil {
let x = "http://localhost/Twitter/Avatar/52/pogba.jpeg"
let imageURL = URL(string: x)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: imageURL!, completionHandler: { (data, response, error) in
DispatchQueue.main.async {
if let imageData = data {
self.avatarImage.image = UIImage(data: imageData)
}
}
})
task.resume()
}
// round courner of avatar
avatarImage.layer.cornerRadius = avatarImage.bounds.width/20
avatarImage.clipsToBounds = true
//Give title to navigation controller
self.navigationItem.title = username.uppercased()
activityIndicator.stopAnimating()
}
@IBAction func logoutButtonDidPressed(_ sender: Any) {
//menghapus data userDefault yang sudah ada
UserDefaults.standard.removeObject(forKey: "parsedJSON")
UserDefaults.standard.synchronize()
//menuju ke login page dengan modal segue
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVC = storyboard.instantiateViewController(withIdentifier: "loginVC")
present(loginVC, animated: true, completion: nil)
}
@IBAction func editProfilePictureButtonDidPressed(_ sender: Any) {
// user akan memilih photo dari library atau dari camera nya
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
let actionSheet = UIAlertController(title: "Photo Source", message: "please choose your source", preferredStyle: .actionSheet)
// action camera
let actionCamera = UIAlertAction(title: "Camera", style: .default) { (action) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
} else {
self.showAlert(alertTitle: "Opppss", alertMessage: "camera can't be used / not available", actionTitle: "OK")
print("camera can't be used / not available")
}
}
// action photo library
let actionPhotoLibrary = UIAlertAction(title: "Photo Library", style: .default) { (action) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}
//action cancel
let actionCancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(actionCamera)
actionSheet.addAction(actionPhotoLibrary)
actionSheet.addAction(actionCancel)
self.present(actionSheet, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
avatarImage.image = image
picker.dismiss(animated: true, completion: nil)
// call func of uploading file to server
uploadAvatar()
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
// custom HTTP request body to upload image file
func createBodyWithParams(_ parameters: [String: String]?, filePathKey: String?, imageDataKey: Data, boundary: String) -> Data {
var body = Data();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
// kita set agar image yang di upload kemudian berformat .jpg
let filename = "avatar.jpeg"
let mimetype = "image/jpeg"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body as Data
}
// uploading image ke server
func uploadAvatar() {
// mendapatkan ID dari User Default variable
let id = userInfo!["id"] as! String
// membuat request
let url = URL(string: "http://localhost/Twitter/uploadAvatar.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// parameter yang akan dikirim di dalam request body
// parameter ini dibutuhkan karena uploadAvatar.php membutuhkan inputan ID
let param = ["id" : id]
// membuat Boundary
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// mengassign image yang akan di upload dan melakukan kompresi
let imageData = UIImageJPEGRepresentation(avatarImage.image!, 0.5)
// if not compressed, return ... do not continue to code
if imageData == nil {
return
}
// constructing http body
request.httpBody = createBodyWithParams(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary)
// filePathKey berupa 'file' agar nanti di PHP $_FILES bisa didentifikasi, contohnya $_FILES['file'][tmp_name]
// launc session
URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async(execute: {
if error == nil {
// maka tampilkan $returnArray dari PHP (response message from server)
do {
// json containes $returnArray from php
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
// declare new parseJSON to store json
guard let parsedJSON = json else {
print("Error while parsing")
return
}
print(parsedJSON)
// get id from $returnArray["id"] in PHP - parseJSON["id"]
let id = parsedJSON["id"]
// successfully uploaded
if id != nil {
// save user information yang berasal dari server
UserDefaults.standard.set(parsedJSON, forKey: "parsedJSON")
userInfo = UserDefaults.standard.object(forKey: "parsedJSON") as? NSDictionary
// jika tidak ada "id" kiriman dari server, maka ada error message
} else {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = parsedJSON["message"] as! String
self.showAlert(alertTitle: "opppps", alertMessage: message, actionTitle: "OK")
})
}
// error ketika melakukan JSON serialization
} catch {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = error.localizedDescription
self.showAlert(alertTitle: "SorryBroooo", alertMessage: message, actionTitle: "OK")
})
}
// error ketika koneksi ke server
} else {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = error!.localizedDescription
self.showAlert(alertTitle: "oppps", alertMessage: message, actionTitle: "OK")
})
}
})
}.resume()
}
}
// extend data
extension Data {
mutating func appendString(_ string : String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
When you use this code
let session = URLSession(configuration: .default)
you had automatically signed up for default caching policies, it uses persistent disk based cache as specified in this link: https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411560-default
if you want to remove all the caching policies, use this code instead
let session = URLSession(configuration: .ephemeral)
这篇关于为什么我下载到同一条路径时会得到不同的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!