我很快乐。我试图指责自己。我知道这是常见问题,但我希望能得到帮助。当我运行应用程序时。我得到了"致命错误:在解开一个可选值"时意外地发现了nil。
import Foundation
import Firebase
import FirebaseDatabase
import FirebaseStorage
import FirebaseAuth
struct TodoItemDatabase {
var eventID: String!
var title: String!
var staff: String!
var location: String!
var starts: String!
var ends: String!
var rpeat: String!
var imageName: String!
var description: String!
var secondPhoto: String!
var ref: FIRDatabaseReference?
var key: String!
var isCompleted: Bool
init (eventID: String!, title: String,staff:String, location: String,starts: String, ends: String, rpeat: String, imageName: String, description: String, secondPhoto: String, key: String = "", isCompleted: Bool){
self.eventID = eventID
self.title = title
self.staff = staff
self.location = location
self.starts = starts
self.ends = ends
self.rpeat = rpeat
self.imageName = imageName
self.description = description
self.secondPhoto = secondPhoto
self.key = key
self.ref = FIRDatabase.database().reference()
self.isCompleted = isCompleted
}
init(snapshot: FIRDataSnapshot){
**//I get the error from here. However, I think the main reason in tableview below**
self.eventID = snapshot.value!["eventID"] as! String
self.title = snapshot.value!["title"] as! String
self.staff = snapshot.value!["staff"] as! String
self.location = snapshot.value!["location"] as! String
self.starts = snapshot.value!["starts"] as! String
self.ends = snapshot.value!["ends"] as! String
self.rpeat = snapshot.value!["rpeat"] as! String
self.imageName = snapshot.value!["imageName"] as! String
self.description = snapshot.value!["description"] as! String
self.secondPhoto = snapshot.value!["secondPhoto"] as! String
self.key = snapshot.key
self.ref = snapshot.ref
self.isCompleted = snapshot.value!["isCompleted"] as! Bool
}
func toAnyObject() -> [String: AnyObject] {
return ["eventid": eventID, "title": title, "staff": staff, "location": location, "starts": starts, "ends": ends, "rpeat": rpeat, "imageName": imageName, "description": description, "secondPhoto": secondPhoto, "isCompleted": isCompleted]
}
}
但是,当我运行应用程序时,加载tableview。看来这个错误。
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
var toDoList:[TodoItemDatabase] = [TodoItemDatabase]()
class CurrentEventViewController: UIViewController, UITableViewDelegate {
var databaseRef: FIRDatabaseReference!{
return FIRDatabase.database().reference()
}
var storageRef: FIRStorageReference!
@IBOutlet var toDoListTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toDoList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! myCell
let todoItem = toDoList[indexPath.row]
storageRef = FIRStorage.storage().referenceForURL(toDoList[indexPath.row].imageName)
storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) in
if error == nil {
dispatch_async(dispatch_get_main_queue(), {
if let data = data {
cell.myImageView.image = UIImage(data: data)
}
})
} else {
print(error!.localizedDescription)
}
}
cell.myLabel.text = todoItem.title!
return cell
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
let ref = toDoList[indexPath.row]
ref.ref?.removeValue()
toDoList.removeAtIndex(indexPath.row)
toDoListTable.reloadData()
}
}
override func viewDidAppear(animated: Bool) {
toDoListTable.reloadData()
}
override func viewWillAppear(animated: Bool) {
let postRef = FIRDatabase.database().reference().child("posts").queryOrderedByChild("isCompleted").queryEqualToValue(false)
postRef.observeEventType(.Value, withBlock: { (snapshot) in
var newPosts = [TodoItemDatabase]()
for post in snapshot.children{
**// I think the reason is the line after.**
let post = TodoItemDatabase(snapshot: post as! FIRDataSnapshot)
newPosts.insert(post, atIndex: 0)
}
toDoList = newPosts
dispatch_async(dispatch_get_main_queue(), {
self.toDoListTable.reloadData()
})
}) { (error) in
print(error.localizedDescription)
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
storageRef = FIRStorage.storage().referenceForURL(toDoList[indexPath.row].imageName)
let storageRef1 = FIRStorage.storage().referenceForURL(toDoList[indexPath.row].secondPhoto)
let itemSelected = toDoList[indexPath.row]
storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) in
if error == nil
{
dispatch_async(dispatch_get_main_queue(), {
if let data = data
{
storageRef1.dataWithMaxSize(1 * 1024 * 1024) { (data1, error) in
if error == nil
{
dispatch_async(dispatch_get_main_queue(), {
if let data1 = data1
{
let detailVC:DetailViewController = self.storyboard?.instantiateViewControllerWithIdentifier("DetailViewController") as! DetailViewController
detailVC.titleEvent = itemSelected.title
detailVC.staffEvent = itemSelected.staff
detailVC.locationEvent = itemSelected.location
detailVC.startEvent = itemSelected.starts
detailVC.endEvent = itemSelected.ends
detailVC.repeatEvent = itemSelected.rpeat
detailVC.imageDetail = UIImage(data: data)!
detailVC.descriptionDetail = itemSelected.description
detailVC.secondPhotoEvent = UIImage(data: data1)!
detailVC.key = itemSelected.key
self.presentViewController(detailVC, animated: true, completion: nil)
}
})
}
else
{
print(error!.localizedDescription)
}
}}
})
}
else
{
print(error!.localizedDescription)
}
}
}
}
答案 0 :(得分:0)
您需要有条件地解包或无法合并这些值。强行打开你的方式是不安全的。
self.eventID = snapshot.value!["eventID"] as! String
应该是
eventID = snapshot.value?["eventID"] as? String ?? ""
不幸的是,编译器喜欢在遇到可选值时建议强制解包。这几乎总是一个可怕的建议。当你遇到时,你需要养成优雅地处理Optionals的习惯.None,因为Optionals是Swift语言中不可或缺的一部分。