2017-09-13 26 views
2

我似乎无法使这个自定义单元格的tableView工作。我得到一个运行时错误TableView在未捕获异常'NSUnknownKeyException'下崩溃,这个类不是密钥x的关键值编码。

终止应用程序由于未捕获的异常“NSUnknownKeyException”, 原因:“[setValue方法:forUndefinedKey:]:此类不是关键 值编码兼容的关键causeCampaignDescription。”

奇怪的是,该属性不是那样调用。这是细胞文件MainViewControllerTableViewCell

// 
// MainViewControllerTableViewCell.swift 
// 
// 
// Created by on 9/13/17. 
// Copyright © 201. All rights reserved. 
// 

import UIKit 

class MainViewControllerTableViewCell: UITableViewCell { 


    @IBOutlet weak var causeCampaignImageView: UIImageView! 



    @IBOutlet weak var causeDescription: UILabel! 


    @IBOutlet weak var daysToFinishLabel: UILabel! 


    @IBOutlet weak var raisedOverTotalLabel: UILabel! 


    @IBOutlet weak var percentageCompletedLabel: UILabel! 

    @IBOutlet weak var goalProgresView: UIProgressView! 


    //card used on 
    @IBInspectable var cornerradius : CGFloat = 2 

    @IBInspectable var shadowOffSetWidth : CGFloat = 0 

    @IBInspectable var shadowOffSetHeight : CGFloat = 5 

    @IBInspectable var shadowColor : UIColor = UIColor.black 

    @IBInspectable var shadowOpacity : CGFloat = 0.5 



    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(_ selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

    override func layoutSubviews() { 
     layer.cornerRadius = cornerradius 
     layer.shadowColor = shadowColor.cgColor 
     layer.shadowOffset = CGSize(width: shadowOffSetWidth, height: shadowOffSetHeight) 
     let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerradius) 
     layer.shadowPath = shadowPath.cgPath 
     layer.shadowOpacity = Float(shadowOpacity) 
    } 


} 

,这是保持表视图MainViewController视图控制器:

// 
// ViewController.swift 
// 
// 
// Created by on 1/28/17. 
// Copyright © 2017. All rights reserved. 
// 

import UIKit 
import Alamofire 
import SwiftyJSON 
import Firebase 


class MainViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 

    var campaignRowsData = [CauseCampaign]() 

    var serverFetchCampaignsUrl = Config.Global._serverUrl 



    @IBOutlet weak var campaignTableView: UITableView! 


    //show navigation controller bar 

    var facebookID = "", twitterID = "",firebaseID = "" 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     //hide bar from navigation controller 

     setToolbar() 

     campaignTableView.delegate=self 

     campaignTableView.dataSource=self 

     campaignTableView.separatorColor = UIColor(white: 0.95, alpha: 1) 

     recoverUserDefaults() 

     getCampaignList() 



     //print(facebookID, twitterID, firebaseID) 

    } 


    func setToolbar(){ 
     //hide bar from navigation controller 
     self.navigationController?.isNavigationBarHidden = false 

     self.navigationItem.setHidesBackButton(true, animated: false) 

     self.navigationController?.navigationBar.barTintColor = UIColor.purple 



    } 

    func getCampaignList(){ 

     Alamofire.request(serverFetchCampaignsUrl+"/campaigns/get/all/user/\(twitterID)/firebase/\(firebaseID)/cat/0", method: .get).validate().responseJSON { response in 
      switch response.result { 
      case .success(let data): 


       let campaignCausesJSON = JSON(campaignCausesData: data) 

       self.parseCampaignCausesListResponse(campaignCausesJSON) 

       //alternative thread operation 


       DispatchQueue.main.async { 
        self.campaignTableView.reloadData() 

       } 

      case .failure(let error): 
       print(error) 
      } 
     } 

    } 

    func parseCampaignCausesListResponse(_ campaignCausesJSON:JSON){ 

     if let activeCampaignCount = campaignCausesJSON["active_campaigns_count"].string { 
      //Now you got your value 
      print("TOTAL_ACTIVE_CAMPAIGNS",activeCampaignCount) 
      CampaignsGlobalDataManagerUtil.campaignTotalCount = Int(activeCampaignCount)! 
     } 

     if let contributorUserId = campaignCausesJSON["contributor_user_id"].string { 
      //Now you got your value 
      print("CONTRIBUTOR_USER_ID",contributorUserId) 
      CurrentUserUtil.contributorUserId = contributorUserId 
     } 

     if let userTwitterFollowersQty = campaignCausesJSON["user_twitter_followers_qty"].int { 
      //Now you got your value 
      print("USER_TWITTER_FOLLOWERS_QTY",userTwitterFollowersQty) 
      CurrentUserUtil.twitterFollowersCount = Int(userTwitterFollowersQty) 
     } 

     //Parsing campaigns object array 

      campaignCausesJSON["camp_array"].arrayValue.map({ 

      let campaignCause:JSON = $0 

      parseCampaign(campaignCause) 
      }) 




    } 
    //TODO:CHANGE TO DATATAPE OBJECT 
    func parseCampaign(_ causeCampaign:JSON){ 

     let causeCampaignObject: CauseCampaign = CauseCampaign(); 

     causeCampaignObject.description = causeCampaign["cause_description"].stringValue 


     causeCampaignObject.id = causeCampaign["campaign_id"].stringValue 


     if let contributorsQty = causeCampaign["contributors_qty"].int{ 
      causeCampaignObject.contributorsQty = contributorsQty 

     } 

     causeCampaignObject.currencySymbol = causeCampaign["currency_symbol"].stringValue 

     if let currentContributions = causeCampaign["current_contributions"].float{ 
      causeCampaignObject.currentContributions = currentContributions 

     } 

     if let goal = causeCampaign["goal"].float { 
      causeCampaignObject.goal = goal 
     } 

     if let goalPercentageAchieved = causeCampaign["goal_percentage_achieved"].float{ 
      causeCampaignObject.goalPercentageAchieved = causeCampaign["goal_percentage_achieved"].float! 
     } 

     causeCampaignObject.hashtag = causeCampaign["hashtag"].stringValue 

     causeCampaignObject.name = causeCampaign["name"].stringValue 

     if let remainingAmmountToGoal = causeCampaign["remaining_ammount_to_goal"].float{ 
      causeCampaignObject.remainingAmmountToGoal = remainingAmmountToGoal 
     } 

     if let picUrl = causeCampaign["pic_url"].stringValue as? String { 
      causeCampaignObject.picUrl = picUrl 
     } 

     if let campaignStartingDate = causeCampaign["created_at"].string{ 
      causeCampaignObject.campaignStartingDate = campaignStartingDate 
     } 

     if let campaignEndingDate = causeCampaign["campaign_ending_date"].string{ 
      causeCampaignObject.campaignEndingDate = campaignEndingDate 

     } 


     var foundationsArray = [Foundation]() 

     causeCampaign["foundations"].arrayValue.map({ 

      let id = $0["foundation_id"].stringValue 
      let twitterUsername = $0["twitter_username"].stringValue 
      let picPath = $0["pic_path"].stringValue 
      let name = $0["name"].stringValue 

      let foundation:Foundation = Foundation(id,twitterAccount: twitterUsername,picPath: picPath,name: name) 

      foundationsArray.append(foundation) 
     }) 


     causeCampaignObject.foundations = foundationsArray 


     campaignRowsData.append(causeCampaignObject) 

//  foundations = "<null>"; 

//innecesario 
//  SACAR DE LA REQUEST INICIAL??? 
//  "went_inactive_date" = "<null>"; 
//  "tweet_id" = 900936910494810112; 


    } 




    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return campaignRowsData.count 

    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = campaignTableView.dequeueReusableCell(withIdentifier: "campaignCell", for: indexPath) as! MainViewControllerTableViewCell 

    //setting card attributes 
     print("ROW",campaignRowsData[indexPath.row].description) 
     let campaignCause:CauseCampaign = campaignRowsData[indexPath.row] 

     if let desc = campaignCause.description as? String{ 
       cell.causeDescription.text = desc 
     } else { 
      print("NULL") 
     } 

     return cell 
    } 


    func recoverUserDefaults(){ 
     if let fbID = UserDefaults.standard.object(forKey: Config.Global._facebookIdUserDefaults) as? String { 
      facebookID = fbID 
     }else{ 
      print("FACEBOOK ID IS NULL") 
     } 



     if let twtID = UserDefaults.standard.object(forKey: Config.Global._twitterIdUserDefaults) as? String{ 
      twitterID = twtID 
     }else{ 
      print("TWITTER ID IS NULL") 
     } 


     if let firID = UserDefaults.standard.object(forKey: Config.Global._firebaseIdUserDefaults) as? String{ 
      firebaseID = firID 
     }else{ 
      print("TWITTER ID IS NULL") 
     } 

     return 
    } 



} 
  1. 应用崩溃如果线路reloadData未被注释(I甚至不知道什么时候和如果我应该使用这个)
  2. 如果我设置标签,你不能看到任何东西在scree N,我看到空白卡,但同样,只要我去掉reloadData崩溃
  3. 有没有causeCampaignDescription,现在它被称为causeDescription,所以我不知道为什么错误不断提的是,现场
  4. 数据desc是确定因为我打印它,它有正确的内容,所以它不是

可能是什么问题?

+0

在代码中搜索'causeCampaignDescription'。您可能忘记将它从界面构建器中删除(Storyboards/Xibs) – sheetal

+0

您将'causeCampaignDescription'重命名为'causeDescription',但您的故事板或NIB最有可能仍然提及旧名称。去IB的那个领域,检查那个控制点的出口。我敢打赌,你会发现那个旧名字仍然在那里引用。 – Rob

回答

1

在项目中搜索causeCampaignDescription通常会调出包含过时键路径的违规xib和/或故事板。然而,这是我的经验是,Xcode不是总是100%可靠的关于xibs和故事里寻找物品,所以如果Xcode的搜索功能不会找到它,在终端这一命令将其调高通俗易懂:

find /path/to/your/project/directory -name .git -prune -or -type f -exec grep causeCampaignDescription {} \; -print 

一旦在xib或storyboard中找到违规物品,请将其更改为正确的字符串,并且应该解决您的问题。

+0

你是我最好的朋友。非常感谢你。我是ios的新手,我非常信任xcode,在故事板上正确管理更改。我最近看过视频推荐不要使用故事板...在再次使用它之前我会考虑两次... https://www.youtube.com/watch?v = g6yz5oX5iWc – Juan

相关问题