传递数据委托和协议 swift
passing data delegates and protocols swift
大家好,希望你们一切顺利,我正在研究 swift 的代表和协议。我的 viewcontroller
遇到了一些问题,它说 found nil while unwrapping an Optional value
将值作为参数之一传递时,我不确定该怎么做,因为如果我打印 artistViewModel?.artistName
我确实得到了数据。我不确定这是否与异步或完成处理程序有关。
这是我的 viewcontroller
的代码
import UIKit
import Alamofire
import SwiftyJSON
protocol artistViewModelDelegate {
func loadArtistViewModel(data: ArtistViewModel)
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, artistSearchDelegate {
@IBOutlet weak var tableView: UITableView!
var data: [ArtistItem] = []
var delegate: artistViewModelDelegate!
var artistViewModel: ArtistViewModel?
var params = [API_CONSTANTS.URL_TYPES.PARAMETERS.TERM: "Maroon 5", API_CONSTANTS.URL_TYPES.PARAMETERS.MEDIA: API_CONSTANTS.URL_TYPES.PARAMETERS.MUSIC]
override func viewDidLoad() {
super.viewDidLoad()
getItunesData()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "artistCell", bundle: nil), forCellReuseIdentifier: "artistCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "artistCell", for: indexPath) as! artistCell
cell.artistName.text = data[indexPath.row].artistName
cell.albumName.text = data[indexPath.row].albumName
cell.genre.text = data[indexPath.row].genre
cell.trackPrice.text = "$\(String(data[indexPath.row].trackPrice))"
cell.albumArtwork.load(url: data[indexPath.row].artwork)
cell.layer.cornerRadius = 5
cell.layer.masksToBounds = true
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
artistViewModel = ArtistViewModel(artist: data[indexPath.row])
let artistViewController = storyboard?.instantiateViewController(withIdentifier: "ArtistViewController") as! ArtistViewController
delegate.loadArtistViewModel(data: artistViewModel!) // ----> Unexpectedly found nil while unwrapping an Optional value
present(artistViewController, animated: true, completion: nil)
}
func getItunesData(){
Alamofire.request(API_CONSTANTS.URL_TYPES.URL, method: .get, parameters: params).responseJSON
{ response in
if response.result.isSuccess {
let json = JSON(response.result.value)
self.data = ArtistModel(json: json).artistItems
self.tableView.reloadData()
} else {
}
}
}
func didTapSearch(artist: String) {
params = [API_CONSTANTS.URL_TYPES.PARAMETERS.TERM:"\(artist)"]
getItunesData()
}
@IBAction func searchButton(_ sender: Any) {
let popupSearchVC = storyboard?.instantiateViewController(withIdentifier: "popupSearchView") as! PopupViewController
popupSearchVC.delegate = self
present(popupSearchVC, animated: true, completion: nil)
}
}
此处 ArtistViewController
将接收数据
import UIKit
class ArtistViewController: UIViewController, artistViewModelDelegate {
func loadArtistViewModel(data: ArtistViewModel) {
print(data.artistName)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
而对于模型 ArtistViewModel
import Foundation
class ArtistViewModel {
var artistId: Int
var artistName: String
var artwork: URL
var albumName: String
var releaseDate: String
var genre: String
var trackPrice: Double
init(artist: ArtistItem){
self.artistId = artist.artistId
self.artistName = artist.albumName
self.artwork = artist.artwork
self.albumName = artist.albumName
self.releaseDate = artist.releaseDate
self.genre = artist.genre
self.trackPrice = artist.trackPrice
}
}
Hope you guys can help me with this one. Cheers
根据您的代码,您的 delegate
字段未设置。 !
将强制展开可选的 delegate
字段。你必须在调用它之前设置你的 delegate
。
直接给它赋值,或者用optional chaining.
例如,您可以:
- 在
viewDidLoad()
方法中设置一个值为delegate
,例如
override func viewDidLoad() {
super.viewDidLoad()
// HERE
self.delegate = ArtistViewController()
getItunesData()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "artistCell", bundle: nil), forCellReuseIdentifier: "artistCell")
}
- 仅在使用
delegate?.loadArtistViewModel(_:)
设置时调用委托。
您可以将 var delegate: artistViewModelDelegate!
替换为 var delegate: artistViewModelDelegate?
以防止此类错误。
大家好,希望你们一切顺利,我正在研究 swift 的代表和协议。我的 viewcontroller
遇到了一些问题,它说 found nil while unwrapping an Optional value
将值作为参数之一传递时,我不确定该怎么做,因为如果我打印 artistViewModel?.artistName
我确实得到了数据。我不确定这是否与异步或完成处理程序有关。
这是我的 viewcontroller
import UIKit
import Alamofire
import SwiftyJSON
protocol artistViewModelDelegate {
func loadArtistViewModel(data: ArtistViewModel)
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, artistSearchDelegate {
@IBOutlet weak var tableView: UITableView!
var data: [ArtistItem] = []
var delegate: artistViewModelDelegate!
var artistViewModel: ArtistViewModel?
var params = [API_CONSTANTS.URL_TYPES.PARAMETERS.TERM: "Maroon 5", API_CONSTANTS.URL_TYPES.PARAMETERS.MEDIA: API_CONSTANTS.URL_TYPES.PARAMETERS.MUSIC]
override func viewDidLoad() {
super.viewDidLoad()
getItunesData()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "artistCell", bundle: nil), forCellReuseIdentifier: "artistCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "artistCell", for: indexPath) as! artistCell
cell.artistName.text = data[indexPath.row].artistName
cell.albumName.text = data[indexPath.row].albumName
cell.genre.text = data[indexPath.row].genre
cell.trackPrice.text = "$\(String(data[indexPath.row].trackPrice))"
cell.albumArtwork.load(url: data[indexPath.row].artwork)
cell.layer.cornerRadius = 5
cell.layer.masksToBounds = true
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
artistViewModel = ArtistViewModel(artist: data[indexPath.row])
let artistViewController = storyboard?.instantiateViewController(withIdentifier: "ArtistViewController") as! ArtistViewController
delegate.loadArtistViewModel(data: artistViewModel!) // ----> Unexpectedly found nil while unwrapping an Optional value
present(artistViewController, animated: true, completion: nil)
}
func getItunesData(){
Alamofire.request(API_CONSTANTS.URL_TYPES.URL, method: .get, parameters: params).responseJSON
{ response in
if response.result.isSuccess {
let json = JSON(response.result.value)
self.data = ArtistModel(json: json).artistItems
self.tableView.reloadData()
} else {
}
}
}
func didTapSearch(artist: String) {
params = [API_CONSTANTS.URL_TYPES.PARAMETERS.TERM:"\(artist)"]
getItunesData()
}
@IBAction func searchButton(_ sender: Any) {
let popupSearchVC = storyboard?.instantiateViewController(withIdentifier: "popupSearchView") as! PopupViewController
popupSearchVC.delegate = self
present(popupSearchVC, animated: true, completion: nil)
}
}
此处 ArtistViewController
将接收数据
import UIKit
class ArtistViewController: UIViewController, artistViewModelDelegate {
func loadArtistViewModel(data: ArtistViewModel) {
print(data.artistName)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
而对于模型 ArtistViewModel
import Foundation
class ArtistViewModel {
var artistId: Int
var artistName: String
var artwork: URL
var albumName: String
var releaseDate: String
var genre: String
var trackPrice: Double
init(artist: ArtistItem){
self.artistId = artist.artistId
self.artistName = artist.albumName
self.artwork = artist.artwork
self.albumName = artist.albumName
self.releaseDate = artist.releaseDate
self.genre = artist.genre
self.trackPrice = artist.trackPrice
}
}
Hope you guys can help me with this one. Cheers
根据您的代码,您的 delegate
字段未设置。 !
将强制展开可选的 delegate
字段。你必须在调用它之前设置你的 delegate
。
直接给它赋值,或者用optional chaining.
例如,您可以:
- 在
viewDidLoad()
方法中设置一个值为delegate
,例如
override func viewDidLoad() {
super.viewDidLoad()
// HERE
self.delegate = ArtistViewController()
getItunesData()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "artistCell", bundle: nil), forCellReuseIdentifier: "artistCell")
}
- 仅在使用
delegate?.loadArtistViewModel(_:)
设置时调用委托。
您可以将 var delegate: artistViewModelDelegate!
替换为 var delegate: artistViewModelDelegate?
以防止此类错误。