UIImage从json请求返回nil到mysql数据库以获得tableView单元格图像?
Posted
技术标签:
【中文标题】UIImage从json请求返回nil到mysql数据库以获得tableView单元格图像?【英文标题】:UIImage returning nil from json request to mysql database for tableView cell image? 【发布时间】:2017-07-31 00:08:22 【问题描述】:我无法将图像返回到 tableView 单元格。
当我将所有的 recipientImg 参数更改为字符串时,一切运行正常,但是当我将 recipientImg 参数更改为 UIImage 时,我得到了(下载的数据 致命错误:在展开可选值时意外发现 nil) (lldb)
Ps 我正在尝试将数据库中的文件路径作为图像返回。其他两个字符串在 tableView 中作为字符串返回,但我无法让 imageView 返回图像。
有什么建议吗?
This is the JSON file on the server from the database 我也在数据库中使用 RecipientImg 作为 [varchar]
这里是 viewermodel1.swift
import UIKit
class viewedMeModel1: NSObject
//properties
var username: String?
var messageDetail: String?
var recipientImg: UIImage?
//empty constructor
override init()
//construct with parameters
init(username: String, messageDetail: String, recipientImg: UIImage)
self.username = username
self.messageDetail = messageDetail
self.recipientImg = recipientImg
//prints object's current state
这里是viewedMeModel2.swift
import UIKit
protocol viewedMeModel2Protocol: class
func itemsDownloaded(items: NSArray)
class viewedMeModel2: NSObject
weak var delegate: viewedMeModel2Protocol!
var data = Data()
let urlPath: String = "http://" //this will be changed to the path where .php lives
func downloadItems()
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) (data, response, error) in
if error != nil
print("Failed to download data")
else
print("Data downloaded")
self.parseJSON(data!)
task.resume()
func parseJSON(_ data:Data)
var jsonResult = NSArray()
do
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
catch let error as NSError
print(error)
var jsonElement = NSDictionary()
let locations = NSMutableArray()
for i in 0 ..< jsonResult.count
jsonElement = jsonResult[i] as! NSDictionary
let location = viewedMeModel1()
//the following insures none of the JsonElement values are nil through optional binding
if let username = jsonElement["Username"] as? String,
let messageDetail = jsonElement["MessageDetail"] as? String,
let recipientImg = jsonElement["RecipientImg"] as? UIImage
location.username = username
location.messageDetail = messageDetail
location.recipientImg = recipientImg
locations.add(location)
DispatchQueue.main.async(execute: () -> Void in
self.delegate.itemsDownloaded(items: locations)
)
这里是viewedMeController.swift 导入 UIKit
class ViewerViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, viewedMeModel2Protocol
var feedItems: NSArray = NSArray()
var selectedLocation : viewedMeModel1 = viewedMeModel1()
@IBOutlet weak var viewedMe: UITableView!
override func viewDidLoad()
super.viewDidLoad()
self.viewedMe.delegate = self
self.viewedMe.dataSource = self
let ViewedMeModel2 = viewedMeModel2()
ViewedMeModel2.delegate = self
ViewedMeModel2.downloadItems()
// Do any additional setup after loading the view.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func itemsDownloaded(items: NSArray)
feedItems = items
self.viewedMe.reloadData()
func numberOfSections(in tableView: UITableView) -> Int
return feedItems.count
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// Return the number of feed items
return feedItems.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
// Retrieve cell
let cellIdentifier: String = "basicCell"
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
// Get the location to be shown
let item: viewedMeModel1 = feedItems[indexPath.row] as! viewedMeModel1
// Get references to labels of cell
cell.UIImage?.image = item.recipientImg!
return cell
【问题讨论】:
还有一句话,你的命名约定真的很糟糕,你应该总是对类和协议使用大写的名字,而对变量名使用驼峰式命名。 【参考方案1】:问题在于您的viewedMeModel2.swift,在这一行:
let recipientImg = jsonElement["RecipientImg"] as? UIImage
条件解包结果总是返回recipientImg = nil,因为jsonElement["RecipientImg"]是一个字符串,它不能被强制转换为UIImage。 您应该将代码重写为:
if let username = jsonElement["Username"] as? String,
let messageDetail = jsonElement["MessageDetail"] as? String,
let recipientImgString = jsonElement["RecipientImg"] as? String
location.username = username
location.messageDetail = messageDetail
location.recipientImg = UIImage(named: recipientImgString)
【讨论】:
这非常正确,但我很确定 UIImage(named: String) 初始化程序仅用于您存储在应用程序主包中的图像。 (您本地存储在图像资产文件夹中的图像) 你说得对,我只是假设 PO 将图像存储在他的图像资产中,因为他的示例 json 的内容。是的,我的 UIImage(name:) 可能是错误的 :) 完全不用担心!您可能是正确的,他将它们存储在本地。只是想指出这一点,以防他不是,仅此而已! :) 实际上我并没有在本地存储图像。我正在使用 mysql 数据库,并将图像文件存储在我的文件系统上。我只是将图像的路径存储在数据库中【参考方案2】:我的猜测是 jsonElement["RecipientImg"]
返回 String
而不是 UIImage
,所以你得到 nil
因为你不能将字符串转换为图像。尝试从jsonElement["RecipientImg"]
获取图像网址,然后从该网址创建UIImage
。像这样的:
let imageURL = jsonElement["RecipientImg"] as? String
let myImage = UIImage(contentsOfFile: imageURL)
如果您要获取某种数据对象,也可以使用 UIImage 初始化程序 init?(data: Data)
。
同样,jsonElement["RecipientImg"]
的对象可能无法转换为UIImage
,我猜它是String
。找出它是什么以及你可以将它转换成什么,然后使用文档中适当的 UIImage
初始化程序。
https://developer.apple.com/documentation/uikit/uiimage
【讨论】:
以上是关于UIImage从json请求返回nil到mysql数据库以获得tableView单元格图像?的主要内容,如果未能解决你的问题,请参考以下文章
iPhone - UIImage imageWithData 返回 nil