我有2种不同的JSON,并且当将collectionview中的图像按下到另一个视图控制器时,我想显示数据列表。
这些数据列表也应该是可点击的。
对于许多培训(TSCSkillName
),这将是一个SkillsName(TSCTtopicName
)
示例JSON
{
"TSCskillID": 1,
"TSCProficiency": "Product",
"TSCLevel": "Fundamental",
"TSCSkillName": "Product Usability",
"TSCskillLOGO": "images\/TSCskillLogo\/Product Usability.jpg",
"TSCskillDescription": "SKILLS Test Description"
}
第二个JSON
{
"TSCProficiency": "Product",
"TSCSkillName": "Product Usability",
"TSCskillDescription": "SKILLS Test Description",
"TSCLevel": "Fundamental",
"TSCskillLOGO": "images\/TSCskillLogo\/Product Usability.jpg",
"TSCTtopicID": 1,
"TSCTtopicName": "Trend Micro Security",
"TSCTtopicDescription": "TOPIC Test Description",
"Status": "Done",
"TSCTMemorabilia": "images\/Memorabilia"
},
{
"TSCProficiency": "Product",
"TSCSkillName": "Product Usability",
"TSCskillDescription": "SKILLS Test Description",
"TSCLevel": "Fundamental",
"TSCskillLOGO": "images\/TSCskillLogo\/Product Usability.jpg",
"TSCTtopicID": 2,
"TSCTtopicName": "Trend Micro Antivirus for Mac",
"TSCTtopicDescription": "TOPIC Test Description",
"Status": "Done",
"TSCTMemorabilia": "images\/Memorabilia"
}
// I used this data to display the images to my collectionview
struct getSkills: Codable {
let TSCProficiency, TSCSkillName, TSCskillDescription, TSCLevel: String
let TSCskillLOGO: String
let TSCTtopicID: Int?
let TSCTtopicName, TSCTtopicDescription, status, TSCTMemorabilia: String
enum CodingKeys: String, CodingKey {
case TSCProficiency = "TSCProficiency"
case TSCSkillName = "TSCSkillName"
case TSCskillDescription = "TSCskillDescription"
case TSCLevel = "TSCLevel"
case TSCskillLOGO = "TSCskillLOGO"
case TSCTtopicID = "TSCTtopicID"
case TSCTtopicName = "TSCTtopicName"
case TSCTtopicDescription = "TSCTtopicDescription"
case status = "Status"
case TSCTMemorabilia = "TSCTMemorabilia"
}
}
struct skills {
static var TSCskillLOGO : String = "Photo Location"
static var TSCskillID: String = "1"
static var TSCProficiency: String = "Skill Proficiency"
static var TSCSkillName: String = "Skill Name"
static var TSCskillDescription: String = "Skill Description"
static var TSCLevel: String = "Skill Level"
static var TSCTtopicID: String = "Trainings ID"
static var TSCTtopicName: String = "Training Name"
static var TSCTtopicDescription: String = "Training Description"
static var Status: String = "Status"
static var TSCTMemorabilia: String = "Memorabilia"
}
struct testSkills: Codable {
let TSCskillID: Int
let TSCProficiency, TSCLevel,TSCSkillName, TSCskillLOGO: String
let TSCskillDescription: String
enum CodingKeys: String, CodingKey {
case TSCskillID = "TSCskillID"
case TSCProficiency = "TSCProficiency"
case TSCLevel = "TSCLevel"
case TSCSkillName = "TSCSkillName"
case TSCskillLOGO = "TSCskillLOGO"
case TSCskillDescription = "TSCskillDescription"
}
}
class SkillsTreeViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var skillsCollectionView: UICollectionView!
@IBOutlet weak var skillsCatLbl: UILabel!
var getSkillsInfo = [getSkills]()
var testSkillsInfo = [testSkills]()
var badges: [UIImage] = []
var isBadgeLoaded = false
var retryTimes = 0
// You may check my code below
override func viewDidLoad() {
super.viewDidLoad()
skillsCollectionView.layer.cornerRadius = 10
skillsCollectionView.layer.masksToBounds = true
skillsCatLbl.text = "Network"
loadData()
}
func loadData() {
handleCollectionViewLayout(collectionView: skillsCollectionView)
getTestSkillsList {
self.addValuesToVariables {
self.handleLoading(view: self.skillsCollectionView, isDoneLoading: !self.isBadgeLoaded)
self.loadImages()
}
}
// getSkillsDetails {}
}
func addValuesToVariables(completed: @escaping () -> ()) {
skills.TSCskillLOGO = testSkillsInfo[0].TSCskillLOGO
skills.TSCProficiency = testSkillsInfo[0].TSCProficiency
skills.TSCSkillName = testSkillsInfo[0].TSCSkillName
skills.TSCskillDescription = testSkillsInfo[0].TSCskillDescription
skills.TSCLevel = testSkillsInfo[0].TSCLevel
skills.TSCskillID = String(testSkillsInfo[0].TSCskillID)
completed()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return getSkillsInfo.count
return testSkillsInfo.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let collectionviewcell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionviewcell", for: indexPath) as! FAMECell
collectionviewcell.skillsBadgePic?.addImageShadow(shadowOffset: CGSize(width: 0, height: 0), shadowColor: UIColor.black.cgColor, shadowRadius: 0.5, shadowOpacity: 5.0)
collectionviewcell.skillsBadgePic?.contentMode = .scaleAspectFit
if isBadgeLoaded {
activityIndicator.stopAnimating()
collectionviewcell.skillsBadgePic?.image = badges[indexPath.item]
}
return collectionviewcell
//collectionviewcell.skillsBadgePic?.image = getSkillsInfo[indexPath.item].image
//}
// print(getSkillsInfo[indexPath.item].image!)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("User Tapped: \(indexPath.item)")
let selectedCell = skillsCollectionView.cellForItem(at: indexPath) as! FAMECell
let mainStoryboard:UIStoryboard = UIStoryboard (name: "Main", bundle:nil)
let desVC = mainStoryboard.instantiateViewController(withIdentifier: "SkillsTreePopUpViewController") as! SkillsTreePopUpViewController
desVC.badgeTitle = testSkillsInfo[indexPath.item].TSCSkillName
desVC.badgeImage = selectedCell.skillsBadgePic?.image
desVC.badgeDescription = testSkillsInfo[indexPath.item].TSCskillDescription
desVC.skillID = testSkillsInfo[indexPath.item].TSCskillID
desVC.trainingsBtn = getSkillsInfo[indexPath.item].TSCTtopicName //getting an error on this line [array is nil]
self.present(desVC, animated: true, completion: nil)
}
func getTestSkillsList(completed: @escaping () -> ()) {
let fcat = self.skillsCatLbl.text
let siebelid = engineerProfileInfo.siebelID
let rootLink = "https://skills.dasq.com/iOS/testskills.php?"
let url = URL (string: rootLink + "id=" + siebelid + "&fcat=" + fcat!)
URLSession.shared.dataTask(with: url!) {(data, response, error) in
if error == nil {
do {
self.testSkillsInfo = try JSONDecoder().decode([testSkills].self, from: data!)
print(self.testSkillsInfo)
DispatchQueue.main.async {
completed()
}
} catch {
print("JSON Error: Skills Tree")
self.handleJSONErrorAlert()
}
} else {
self.handleNoNetAlert()
}
}.resume()
}
func getSkillsDetails(completed: @escaping () -> ()) {
let tid = skills.TSCskillID
let siebelid = engineerProfileInfo.siebelID
let rootLink = "https://skills.dasq.com/iOS/getskillspage.php"
let url = URL (string: rootLink + "sid=" + siebelid + "&tid=" + tid )
URLSession.shared.dataTask(with: url!) {(data, response, error) in
if error == nil { // getting an error here that array is nil
do {
self.getSkillsInfo = try JSONDecoder().decode([getSkills].self, from: data!)
DispatchQueue.main.async {
completed()
}
} catch {
print("JSON Error: Trainings Details")
print (error)
self.handleJSONErrorAlert()
}
} else {
self.handleNoNetAlert()
}
}.resume()
}
func loadImages(){
for index in 1...testSkillsInfo.count {
let badgeTitle = testSkillsInfo[index-1].TSCSkillName
let completeLink = "https://skills.dasq.com/" + "images/TSCskillLogo/\(badgeTitle).jpg"
let imageUrlString = completeLink.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
let url = URL(string: imageUrlString!)
let data = try? Data(contentsOf: url!)
let coloredPic = UIImage(data: data!)
badges.append(coloredPic!)
}
isBadgeLoaded = !isBadgeLoaded
print(badges.count)
self.skillsCollectionView.reloadData()
}
答案 0 :(得分:0)
请检查您可解码的结构。我为您生成了一个。该错误表明
JSON文本不是以数组开头。
因此,尝试解码“ TopicName”,它是“ TopicNameElement”的数组
技能名称
struct SkillName: Codable {
let tsCskillID: Int
let tscProficiency, tscLevel, tscSkillName, tsCskillLOGO: String
let tsCskillDescription: String
enum CodingKeys: String, CodingKey {
case tsCskillID = "TSCskillID"
case tscProficiency = "TSCProficiency"
case tscLevel = "TSCLevel"
case tscSkillName = "TSCSkillName"
case tsCskillLOGO = "TSCskillLOGO"
case tsCskillDescription = "TSCskillDescription"
}
}
主题名称
typealias TopicName = [TopicNameElement]
struct TopicNameElement: Codable {
let tscProficiency, tscSkillName, tsCskillDescription, tscLevel: String
let tsCskillLOGO: String
let tscTtopicID: Int
let tscTtopicName, tscTtopicDescription, status, tsctMemorabilia: String
enum CodingKeys: String, CodingKey {
case tscProficiency = "TSCProficiency"
case tscSkillName = "TSCSkillName"
case tsCskillDescription = "TSCskillDescription"
case tscLevel = "TSCLevel"
case tsCskillLOGO = "TSCskillLOGO"
case tscTtopicID = "TSCTtopicID"
case tscTtopicName = "TSCTtopicName"
case tscTtopicDescription = "TSCTtopicDescription"
case status = "Status"
case tsctMemorabilia = "TSCTMemorabilia"
}
}