2016-06-27 250 views
1

处理将数据存储在Firebase上并将数据加载到我的TableView中的应用程序。必须从我找到的教程中稍微更改(旧)代码,以便我希望有人能够发现我犯的错误。用户可以添加一个事件:名称,日期,描述(所有字符串)和图像。这些数据被载入到三个“标签”和图像顶部。为什么我的代码不工作? - setObjectForKey:key不能为零

import UIKit 
import Firebase 
import FirebaseDatabaseUI 

class EventViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 

    //outlets for text & image 
    @IBOutlet weak var photoImageView: UIImageView! 

    @IBOutlet weak var eventName: UITextField! 
    @IBOutlet weak var eventDate: UITextField! 
    @IBOutlet weak var eventDes: UITextView! 

    //Database connection 
    let rootref = FIRDatabase().reference() 
    var imagePicker: UIImagePickerController = UIImagePickerController() 



    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    @IBAction func submitEvent(sender: AnyObject) { 

     let name = eventName.text 
     let date = eventDate.text 
     let text = eventDes.text 
     var data: NSData = NSData() 

     if let image = photoImageView.image { 
      data = UIImageJPEGRepresentation(image,0.1)! 
     } 

     let base64String = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) 

     let user: NSDictionary = ["name":name!, "date":date!, "text":text!, "photoBase64":base64String] 

     //Add firebase child node 
     let event = FIRDatabase().reference().child(name!) 

     // Write data to Firebase 
     event.setValue(user) 

     navigationController?.popViewControllerAnimated(true) 
    } 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     view.endEditing(true) 
     super.touchesBegan(touches, withEvent: event) 
    } 

    //UIImagePickerControllerDelegate methods 

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { 
     imagePicker.dismissViewControllerAnimated(true, completion: nil) 
     photoImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage 
    } 

    func imagePickerControllerDidCancel(picker: UIImagePickerController) { 
     dismissViewControllerAnimated(true, completion: nil) 
    } 

    @IBAction func addPicture(sender: AnyObject) { 
     if(UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)) { 
      imagePicker = UIImagePickerController() 
      imagePicker.delegate = self 
      imagePicker.sourceType = .Camera 

      presentViewController(imagePicker, animated: true, completion: nil) 
     } else { 
      imagePicker.allowsEditing = false 
      imagePicker.sourceType = .PhotoLibrary 
      imagePicker.delegate = self 
      presentViewController(imagePicker, animated: true, completion:nil) 
     } 
    } 
} 

我TABLEVIEWCONTROLLER

import UIKit 
import Firebase 

class EventTableViewController: UITableViewController { 

    @IBOutlet weak var eventImage: UIImageView! 
    @IBOutlet weak var eventName: UILabel! 
    @IBOutlet weak var eventDate: UILabel! 
    @IBOutlet weak var eventText: UITextView! 

    let rootref = FIRDatabase().reference() 
    var items = [NSDictionary]() 


    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 
     items = [NSDictionary]() 

     FIRDatabase.load() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    //TableView Data 
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return items.count 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 

     configureCell(cell, indexPath: indexPath) 

     return cell 
    } 

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
     if editingStyle == .Delete { 

      let dict = items[indexPath.row] 
      let name = dict["name"] as! String 

      // delete data from firebase 

      let event = FIRDatabase().reference().child(name) 
      event.removeValue() 
     } 
    } 

    // MARK:- Configure Cell 

    func configureCell(cell: UITableViewCell, indexPath: NSIndexPath) { 
     let dict = items[indexPath.row] 

     eventName.text = dict["name"] as? String 
     eventDate.text = dict["name"] as? String 
     eventText.text = dict["name"] as? String 

     let base64String = dict["photoBase64"] as! String 
     populateImage(cell, imageString: base64String) 
    } 

    func populateImage(cell:UITableViewCell, imageString: String) { 

     let decodedData = NSData(base64EncodedString: imageString, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) 

     let decodedImage = UIImage(data: decodedData!) 

     cell.imageView!.image = decodedImage 
    } 

    //load data from Firebase 
    func loadDataFromFirebase() { 

     UIApplication.sharedApplication().networkActivityIndicatorVisible = true 


      rootref.observeEventType(.Value, withBlock: { snapshot in 
       var tempItems = [NSDictionary]() 


      for item in snapshot.children { 
       let child = item as! FIRDataSnapshot 
       let dict = child.value as! NSDictionary 
       tempItems.append(dict) 
      } 

      self.items = tempItems 
      self.tableView.reloadData() 
      UIApplication.sharedApplication().networkActivityIndicatorVisible = false 

     }) 
    } 
} 

IMAGE让我的工作

My app so far

回答

2

看这句话的想法:

let user: NSDictionary = ["name":name!, "date":date!, "text":text!, "photoBase64":base64String] 

你是在这里做了很多的强制解包。事实上,你在很多地方都做了很多的强制解包。当你这样做时,你会说:“我百分之百确定这里总是有价值的”。避免这几乎所有的成本。该行应该看起来像这样。

if let unwrappedName = name , unwrappedDate = date, unwrappedText = text{ 
    let user: NSDictionary = ["name":unwrappedName, "date":unwrappedDate, "text":unwrappedText, "photoBase64":base64String] 
} 

像这样展开选项会让您的应用程序崩溃。你应该在这里放置一个断点来看看什么值是零。每次你使用!你应该仔细考虑它。

+0

这个。现在人们编写代码就好像'!'会在需要时奇迹般地创建有效值! –

+1

开始Swift程序员应该假装强制 - 解包操作符不存在。在D&D术语中,在武器解锁之前,您必须获得一定数量的经验值。 :) –

+0

所以这里最好的建议是删除我所有的武力解开?但它一直给我一个错误,如果我删除“!”...对不起,因为在这里的菜鸟它已经像一个星期已经试图将这个应用程序连接到firebase :( 将在几个小时内回家再次测试生病让你更新.. – Orangez

0

我相信这个错误是你设置数据库连接的地方。

您有:let rootref = FIRDatabase().reference()

它应该是:let rootref = FIRDatabase().database().reference()

我得到了同样的错误,这个固定为我。

相关问题