无法打开该文件,因为尝试打开SQLite3数据库

时间:2015-09-23 16:02:46

标签: ios sqlite swift2

我正在使用FMDB库在我的iOS应用程序中使用以下代码打开sqlite 3数据库文件。

    //
//  DatabaseLoader.swift
//  Museum-App-iOS
//
//  Created by THOMAS NEEDHAM on 12/07/2015.
//  Copyright (c) 2015 THOMAS NEEDHAM. All rights reserved.
//
//  This class uses the FMDB libary from https://github.com/ccgus/fmdb 
//  Which is licenced under the MIT Licence
//  Copyright (c) 2008-2014 Flying Meat Inc.

import Foundation
import UIKit

internal class DatabaseLoader: NSObject {

var resourcesFolder:NSURL
var path:String
var database:FMDatabase!

internal override init(){
    //resourcesFolder = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as! String
    do{
            self.resourcesFolder = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("museumDB", ofType: "")!)
            self.path = try String(contentsOfURL: self.resourcesFolder)
            self.database = FMDatabase(path: self.path)
    }
    catch let error as NSError{
        NSLog("%@", error.description)
        self.path = "ERROR"
        self.database = nil
    }
    super.init()
}

internal func openDatabase() -> Bool{
    // try to open the database
    if(!database.open()){
        NSLog("Database Not Opened")
        return false
    }
    else{
        NSLog("Database Opened Successfully YAY")
        //NSLog("DB Path %@", self.getDatabasePath())
        return true
    }

}

internal func closeDatabase() -> Bool{
    // try to close the database
    if(!database.close()){
        NSLog("Database Not Closed")
        return false
    }
    else{
        NSLog("Database Closed Successfully YAY")
        return true
    }
}

internal func queryDatabase(query: String) -> FMResultSet!{
    // try to open the database
    if(!openDatabase()){
        NSLog("Database could not be opened for queries")
        return nil
    }
    else{
        NSLog("Database opened for queries")
        // try to begin a transaction with the database
        if(!database.beginTransaction()){
            NSLog("Could not begin a database transaction")
            return nil
        }
        else{
            // try to query the database
            NSLog("Database transaction started succesfully")
            let results = database.executeQuery(query)
            if(results == nil){
            NSLog("Query Failed")
                return nil
            }
            else{
                // if the query was successful return the results
                NSLog("Query Successful")
                return results
            }
        }
    }
}

internal func getDatabasePath() -> NSString{
    return database.databasePath()!
}

func copyDatabase(){
    let storePath : NSString = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last! // get the location of the documents directory
    let fileManager : NSFileManager = NSFileManager.defaultManager() // get the file manager
    var fileCopyError:NSError? = NSError(domain: "Local", code: 0, userInfo: nil) // create an error pointer
    if !fileManager.fileExistsAtPath((storePath as String) + "/museumDB" as String) { // check if the database already exists
        NSLog("Copying Database")
        let defaultStorePath : NSString! = NSBundle.mainBundle().pathForResource("museumDB", ofType: "") // get the default location of the database when the app was first installed
        if((defaultStorePath) != nil) { // if the database exists within the original location
            do {
                try fileManager.copyItemAtPath(defaultStorePath as String, toPath: storePath as String)
            } catch let error as NSError {
                fileCopyError = error
            } // copy it to the documents folder
        }
    }
    else{
        NSLog("Database Already Exists")
    }

}
}

上面的代码工作正常,直到本周早些时候的swift 2更新。现在代码崩溃并给我以下错误。

  

错误域= NSCocoaErrorDomain代码= 264"文件“museumDB”不能   被打开因为其内容的文本编码不能   确定&#34。   的UserInfo = {NSFilePath = /用户/ thomasneedham /库/开发商/ CoreSimulator /设备/ B60A965A-26C7-44C2-9643-0928BD6A2BBF /数据/容器/捆绑/应用/ 70DADB9D-0027-4B8A-8FB8-7DF47B0963DB /博物馆-APP- iOS.app/museumDB}

我尝试过谷歌搜索,但没有找到任何可以帮我解决问题的方法。我是iOS的新手,所以如果你也可以向我解释问题是什么以及你的解决方案如何解决这个问题,这对我来说是非常有帮助的。

提前致谢

1 个答案:

答案 0 :(得分:1)

此代码获取捆绑包中museumDB的路径,将其转换为NSURL,将URL引用的文件内容加载到String变量中,然后显然假设那些String内容引用了数据库确实存在的path。这无疑不是你想要的。

如果museumDB是实际数据库,通常只需直接打开数据库:

internal override init(){
    path = NSBundle.mainBundle().pathForResource("museumDB", ofType: "")!)
    database = FMDatabase(path: path)

    super.init()
}

或者,通常您会看到数据库是否存在于Documents文件夹中,如果没有,则将其从包中复制到Documents文件夹,但只需打开Documents中的数据库。 (例如,我注意到你有copyDatabase方法尝试类似的方法,但你从不打电话给这个,也不打开文件中的这个新副本。)例如你可以这样做:

func openDatabase() -> Bool {
    let fileManager = NSFileManager.defaultManager() // get the file manager
    let documentsFolder = try! fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
    let documentURL = documentsFolder.URLByAppendingPathComponent("museumDB")
    let bundleURL = NSBundle.mainBundle().URLForResource("museumDB", withExtension: nil)!

    var error: NSError?
    if !documentURL.checkResourceIsReachableAndReturnError(&error) {
        do {
            try fileManager.copyItemAtURL(bundleURL, toURL: documentURL)
        } catch let error as NSError {
            NSLog("%@", error.localizedDescription)
            return false
        }
    }

    database = FMDatabase(path: documentURL.path)
    return database.open()
}

这显然假设数据库被称为museumDB。就个人而言,我会使用museum.dbmuseum.sqlite之类的名称,但这是个人品味的问题。