打开时能看到零吗?

时间:2017-05-03 00:41:41

标签: ios swift cocoa-touch firebase

我试图在打开时找到nil在哪里。这是我的代码片段。发现致命错误的行位于:

第一档:

date = dateFormatter().date(from: dictionary[kDATE] as! String)!

第二档:

self.allLists.append(ShoppingList.init(dictionary: currentList))

这是来自shoppingList.swift文件,该函数在控制器中调用

import Foundation
import Firebase

class ShoppingList{
    let name: String
    var totalPrice: Float
    var totalItems: Int
    var id: String
    var date: Date
    var ownerId: String

    init(_name: String, _totalPrice: Float = 0, _id: String = "") {
        name = _name
        totalPrice = _totalPrice
        totalItems = 0
        id = _id
        date = Date()
        ownerId = "1234"
    }

    //creates shopping list item from this dictionary

    init(dictionary: NSDictionary) {

        name = dictionary[kNAME] as! String
        totalPrice = dictionary[kTOTALPRICE] as! Float
        totalItems = dictionary[kTOTALITEMS] as! Int
        id = dictionary[kSHOPPINGLISTID] as! String
        date = dateFormatter().date(from: dictionary[kDATE] as! String)!
        ownerId = dictionary[kOWNERID] as! String
    }

    func dictionaryFromItem(item: ShoppingList) -> NSDictionary {

        return NSDictionary(objects: [item.name, item.totalPrice, item.totalItems, item.id, dateFormatter().string(from: item.date), item.ownerId], forKeys: [kNAME as NSCopying, kTOTALPRICE as NSCopying, kTOTALITEMS as NSCopying, kSHOPPINGLISTID as NSCopying, kDATE as NSCopying, kOWNERID as NSCopying])

    }

这是控制器:

import UIKit
import KRProgressHUD


class AllListsViewController: UIViewController, UITableViewDataSource,UITableViewDelegate{


    @IBOutlet weak var tableView: UITableView!

    var allLists:[ShoppingList] = []
    var nameTextField: UITextField!

    override func viewDidLoad() {

        super.viewDidLoad()
        loadLists()

    }

    //MARK: TableView DataSource

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return allLists.count
    }

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

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        let shoppingList = allLists[indexPath.row]

        cell.textLabel?.text = shoppingList.name

        return cell
    }

    //MARK: IBActions


    @IBAction func addBarButonItemPressed(_ sender: Any) {

        let alertController = UIAlertController(title: "Create Shopping List", message: "Enter the shopping list name", preferredStyle: .alert)

        alertController.addTextField{ (nameTextField) in

            nameTextField.placeholder = "Name"
            self.nameTextField = nameTextField
        }

        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel){ (action) in


        }

        let saveAction = UIAlertAction(title: "Save", style: .default){ (action) in

            if self.nameTextField.text != ""{

                self.createShoppingList()

            }else{

                KRProgressHUD.showWarning(message: "Name is empty!")
            }

        }

        alertController.addAction(cancelAction)
        alertController.addAction(saveAction)

        self.present(alertController,animated: true, completion:nil)


    }

    //MARK: LoadList


    func loadLists(){

        //.values has all the info of the child

        firebase.child(kSHOPPINGLIST).child("1234").observe(.value, with: {
            snapshot in

            self.allLists.removeAll()

            //if we actually received smthing from firebase

            if snapshot.exists(){

                let sorted = ((snapshot.value as! NSDictionary).allValues as NSArray).sortedArray(using: [NSSortDescriptor(key: kDATE,ascending: false)])

                for list in sorted {

                    let currentList = list as! NSDictionary

                    self.allLists.append(ShoppingList.init(dictionary: currentList))

                }

            } else {

                print("no snapshot")
            }

            self.tableView.reloadData()

        })


    }


    //MARK: Helper functions

    func createShoppingList(){


        let shoppingList = ShoppingList(_name: nameTextField.text!)

        shoppingList.saveItemInBackground(shoppingList: shoppingList){ (error) in

            if error != nil{

                KRProgressHUD.showError(message: "Error creating shopping list")
                return

            }
        }
    }
}

数据格式化程序也是另一个文件中的一个小函数。

import Foundation
import UIKit

private let dateFormat = "yyyyMMDDHHmmss"

func dateFormatter() -> DateFormatter {

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = dateFormat

    return dateFormatter

}

1 个答案:

答案 0 :(得分:1)

所以你在这一行上有一个强制向下倾斜和强制可选的解包:

date = dateFormatter().date(from: dictionary[kDATE] as! String)!

您的字典未返回字符串,或者字典中的字符串无法作为日期处理。我猜这是第一个问题,因为日期通常存储为epoch

尝试使用此代替上面的行。在顶部添加断点并逐步执行:

print(dictionary[kDATE])
if let dictValue = dictionary[kDATE] as? String {
   print(dictValue)
   if let unwrappedDate = dateFormatter().date(from: dictValue) {
       date = unwrappedDate
   }
} 

如果在第一个if-let上失败,则返回值不是字符串。如果第二个失败则问题在于日期格式化程序无法读取格式。

第一个打印可能会告诉您要投射到什么类型的线索,第二个可以帮助您修复格式。

强行展开时要小心,

optionalVar!

或用于向下转发。

unknownType as! Type

当你绝对确定价值不会为零时,你应该只使用“力”。