我尝试使用JSON从REST API显示带有字符串的UILabel,但没有运气。我可以很好地将字符串打印到控制台,但是当尝试使用UILabel显示此字符串时,它显示为空白。
这是我正在使用的测试代码:
import UIKit
class List {
var title = String()
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let list = List()
callAPI()
let width = view.bounds.width
let height = view.bounds.height
let label: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: height/2 - 50, width: width, height: 50))
label.backgroundColor = UIColor.red
label.text = title
return label
}()
view.addSubview(label)
print("Label Text: \(list.title)")
}
}
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/")
func callAPI() {
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSMutableArray
let array = json[0] as! [String:Any]
let title = array["title"] as! String
print("Title: \(title)")
let list = List()
list.title = title
}
catch let jsonError {
print(jsonError)
}
}).resume()
}
答案 0 :(得分:0)
您似乎想要替换这些行:
let list = List()
list.title = title
使用:
label.text = title
您创建,更新和弃放List
个实例的代码,但不会尝试更新您的实际UILabel
。
创建和设置标签后,您还需要将呼叫移至callAPI()
。
答案 1 :(得分:0)
在ViewController中,您已创建了List()
的实例,但callAPI()
创建了自己的List()
实例并更新了该title属性,而不是实例中的title属性。你的ViewController。
您可以删除callAPI()
方法,将代码直接放入ViewController并直接更新label.text
,您可以callAPI
接受UILabel
类型的参数,更新它像:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let width = view.bounds.width
let height = view.bounds.height
let label: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: height/2 - 50, width: width, height: 50))
label.backgroundColor = UIColor.red
return label
}
callAPI(label)
view.addSubview(label)
print("Label Text: \(list.title)")
}
}
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/")
func callAPI(_ label: UILabel) {
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSMutableArray
let array = json[0] as! [String:Any]
let title = array["title"] as! String
print("Title: \(title)")
label.text = title
}
catch let jsonError {
print(jsonError)
}
}).resume()
}
,或者您可以callAPI
将List()
的实例作为参数并更新title
属性:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let list = List()
callAPI(list)
let width = view.bounds.width
let height = view.bounds.height
let label: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: height/2 - 50, width: width, height: 50))
label.backgroundColor = UIColor.red
label.text = list.title
return label
}
view.addSubview(label)
print("Label Text: \(list.title)")
}
}
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/")
func callAPI(_ list: List) {
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSMutableArray
let array = json[0] as! [String:Any]
let title = array["title"] as! String
print("Title: \(title)")
list.title = title
}
catch let jsonError {
print(jsonError)
}
}).resume()
}
答案 2 :(得分:0)
为什么不在异步网络功能中使用closure?
您的代码发生的是您调度网络呼叫(需要花费大量时间)。在处理网络调用时,您的代码将继续执行。这意味着在网络调用完成之前调用行label.text = title
。在某些时候,网络调用完成并执行您的代码以创建列表。但是,自设置以来,标签文本很长(以计算机术语表示)。
使用闭包,您可以指定在JSON被获取,序列化并转换为List
对象之后运行代码。
下面的代码为您的callAPI
函数添加了一个闭包参数。与任何其他参数一样,此参数的名称为completion
。执行网络调用后,您将调用此参数,并且将在该点执行传入的任何代码。
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
callAPI { (list) in
let width = self.view.bounds.width
let height = self.view.bounds.height
let label = UILabel(frame: CGRect(x: 0, y: height/2 - 50, width: width, height: 50))
label.backgroundColor = UIColor.red
label.text = list.title
DispatchQueue.main.async(execute: {
self.view.addSubview(label)
})
print("Label Text: \(list.title)")
}
}
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/")
func callAPI(completion: @escaping (_ list: List) -> Void) {
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSMutableArray
let array = json[0] as! [String:Any]
let title = array["title"] as! String
print("Title: \(title)")
let list = List()
list.title = title
completion(list)
}
catch let jsonError {
print(jsonError)
}
}).resume()
}
}
答案 3 :(得分:0)
试试这一个代码。
import UIKit
class List {
var title = String()
}
class ViewController: UIViewController {
var list = List()
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/")
override func viewDidLoad() {
super.viewDidLoad()
callAPI()
}
func setLable() {
let width = view.bounds.width
let height = view.bounds.height
let label: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: height/2 - 50, width: width, height: 50))
label.backgroundColor = UIColor.red
label.text = list.title
return label
}()
self.view.addSubview(label)
print("Label Text: \(list.title)")
}
func callAPI() {
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSMutableArray
let array = json[0] as! [String:Any]
let title = array["title"] as! String
print("Title: \(title)")
self.list.title = title
self.setLable()
}
catch let jsonError {
print(jsonError)
}
}).resume()
}
}