2017-09-13 90 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

相關問題