【问题标题】:How can I check what is stored in my Core Data Database?如何检查存储在我的核心数据数据库中的内容?
【发布时间】:2012-05-01 15:35:41
【问题描述】:

我正在制作一个依赖于 Core Data 的应用程序。我可以在文本字段中输入数据并存储它。

但我需要知道是否正在存储数据。

我正在尝试为我的 tableView 制作一个 detailView,但我没有得到任何结果。现在我想知道是因为我的代码做错了什么,或者数据是否被正确存储。

如何查看应用的 CoreData 数据库中存储的内容?

【问题讨论】:

    标签: ios core-data


    【解决方案1】:

    这是我的解决方案(适用于 iOS 9):

    我使用 automator/bash 脚本在 sqllitebrowser 中打开数据库。该脚本在模拟器中查找最新安装的应用程序。 说明:

    1. 为 SQLite 安装数据库浏览器 (http://sqlitebrowser.org/)
    2. 在 Apple Automator 中创建新的工作流程。
    3. 拖动“运行 Shell 脚本块”并粘贴此代码:
    cd ~/Library/Developer/CoreSimulator/Devices/
    cd `ls -t | head -n 1`/data/Containers/Data/Application 
    cd `ls -t | head -n 1`/Documents
    open -a DB\ Browser\ for\ SQLite ./YOUR_DATABASE_NAME.sqlite
    

    1. (可选)将此工作流转换为应用程序,保存并将其拖到您的 Dock 中。要刷新数据库,只需点击应用图标即可。

    【讨论】:

    • 在第 3 步第 3 行中,我需要将 Documents 替换为 Library/Application\ Support,然后它成功了,谢谢!
    • 这适用于我在 Xcode 10 cd ~/Library/Developer/CoreSimulator/Devices/ cd ls -dt */ | head -n 1/data/Containers/Data/Application cd ls -dt */ | head -n 1/Library/Application\ Support open -一个 DB\ Browser\ for\ SQLite ./YOUR_DATABASE_NAME.sqlite
    • 我用下面的问题得到了导演,然后我在这里用最后一行打开数据库。
    【解决方案2】:

    斯威夫特 4、5

    AppDelegate>>didFinishLaunchingWithOptions函数中加入这一行:

    print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!")
    

    您的modelName.sqlite 文件将在那里。

    您可以使用任何免费的 SQLite 浏览器工具(例如 http://sqlitebrowser.org/)打开它。

    【讨论】:

    • 这对我来说效果更好:// Use this for inspecting the Core Data if let directoryLocation = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).last { print("Documents Directory: \(directoryLocation)Application Support") }
    • 代码显示“文档目录:file:///var/mobile/Containers/Data/Application/C8A58192-D5CD-4278-8AC6-905C883C73A4/Documents/”。没有“modelName.sqlite”。如何获取整个目录?
    • @Muz,在模拟器上试一试,然后在终端或 Finder 中复制并粘贴文件路径 > 前往 > 前往文件夹。
    • @Vahid,我发现原因是我不是在模拟器上而是在设备上运行。模拟器和设备上的输出不同。
    【解决方案3】:

    如果您使用sqlite 作为Core Data 的存储介质,您可以在模拟器中运行您的应用并尝试检查位于沙盒库文件夹中的数据库文件。

    路径应类似于:~/Library/Application Support/iPhone Simulator/5.1/Applications/3BF8A4B3-4959-4D8F-AC12-DB8EF4C3B6E1/Library/YourAppName.sqlite

    要打开sqlite 文件,您需要一个工具。我使用一个名为 Liya (http://itunes.apple.com/us/app/liya/id455484422?mt=12) 的免费工具。

    【讨论】:

    • 嗨:-) 我有那个程序 abs 甚至没有想到这一点:-) 但它不是基于 SQLite 文件。但是默认情况下会生成一个 SQLite 不是吗?它有项目名称吗?
    • 如果你创建了 Xcode 项目并勾选了“Core Data”选项,是的。你应该检查你的 AppDelegate.m 文件,试图找到用于核心数据存储的文件类型。
    • 由于模拟器文件夹不断变化,我正在使用 SimPholders,它将它们本地化:simpholders.com
    • 我面临的唯一问题是,如果关系是一对多,我可以使用任何工具,如 Liya 或 DBSqlitebrowser,然后我无法跟踪相关数据。就像在一对一的数据库中显示在 ZID 列中生成的 id 一样,该 id 在连接的实体中是可追溯的,但在一对多的情况下,没有创建任何列,也没有任何可以关联它们的 id。 - 在领域浏览器中,即使是一对多,我也可以轻松查看对象。
    • 如果我的应用无法在模拟器上运行怎么办?
    【解决方案4】:

    其他解决方案要么陈旧,要么无法轻松快速地将您引导至 SQLite 文件,因此我使用FileManager.SearchPathDirectory.applicationSupportDirectory 提出了自己的解决方案,该解决方案可获取 sqlite 文件所在的确切路径。

    func whereIsMySQLite() {
        let path = FileManager
            .default
            .urls(for: .applicationSupportDirectory, in: .userDomainMask)
            .last?
            .absoluteString
            .replacingOccurrences(of: "file://", with: "")
            .removingPercentEncoding
    
        print(path ?? "Not found")
    }
    

    whereIsMySQLite() 将在此处打印您可以在 Mac 上简单复制粘贴的路径:

    Finder > 前往 > 前往文件夹

    【讨论】:

      【解决方案5】:

      存储 db 的文件夹最近已更改,不在您希望找到的位置。这是我用来解决这个问题的方法: 首先将此代码添加到您的 viewDidLoad 或 applicationDidFinishLaunching:

          #if TARGET_IPHONE_SIMULATOR
          // where are you?
          NSLog(@"Documents Directory: %@", [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
          #endif
      

      从这里得到这个:where is the documents directory for the ios 8 simulator

      这将在运行时显示您的应用在控制台中的实际位置。 然后使用SQLiteBrowser 检查您的 SQLite DB 的内容。

      对我来说就像一个魅力;)

      【讨论】:

      • 谢谢兄弟,你拯救了我的一天。
      • 它不在文档中,而是在库文件夹中。感谢您的回答
      【解决方案6】:

      就 macOS Sierra 版本 10.12.2 和 Xcode 8 而言

      文件夹应该在这里:

      /Users/$username$/Library/Developer/CoreSimulator/Devices/$DeviceID$/data/Containers/Data/Application/$ApplicationID$/Library/Application Support/xyz.sqlite

      要获取设备 ID - 打开终端并粘贴:

      instruments -s devices
      

      【讨论】:

      • 获取设备ID:打开终端并粘贴instruments -s devices 找到iPhone型号,最后它有设备ID
      【解决方案7】:

      如前所述,您可以使用 sqllite 命令行工具。

      但是,您也可以设置调试标志,当它们通过核心数据执行时,它将转储所有 sql 命令。

      编辑方案,并将其添加到“启动时传递的参数”中

      -com.apple.CoreData.SQLDebug 1

      【讨论】:

        【解决方案8】:

        在 Swift 3 中,您拥有 NSPersistentContainer,您可以像这样从那里检索路径:

        persistentContainer.persistentStoreCoordinator.persistentStores.first?.url
        

        (假设您只使用一个持久存储)

        【讨论】:

          【解决方案9】:

          1) 获取模拟器的sql数据库路径。

          NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
          NSLog(@"%@", [paths objectAtIndex:0]);
          

          2) 打开查找器。按 Cmd+Shift+G。粘贴您从第 1 段中获得的内容。例如:

          /Users/USERNAME/Library/Developer/CoreSimulator/Devices/701BAC5F-2A42-49BA-B733-C39D563208D4/data/Containers/Data/Application/DCA9E9C7-5FEF-41EA-9255-6AE9A964053C/Documents
          

          3) 像SQLPro 这样在AppStore 程序中下载。

          4) 在名为“ProjectName.sqlite”的文件夹中打开文件。

          干得好!你会看到这样的东西:

          【讨论】:

            【解决方案10】:

            使用 Core Data Lab 之类的工具可以轻松方便地定位 Core Data 数据库并查看和分析内容。

            更多信息在这里:https://betamagic.nl/products/coredatalab.html

            免责声明:我是这个工具的创造者。

            【讨论】:

            • 太棒了。谢谢!
            【解决方案11】:

            here 下载 SQLite 浏览器。

            在模拟器中运行您的应用。该应用程序应复制到 Mac 上的路径,如下所示:

            /Users/$your username$/Library/Application Support/iPhone Simulator/$your iphone simulator version$/Applications/
            

            一旦你找到你的应用,你必须深入挖掘才能找到 sqlite db(它通常在 Documents 下)。

            【讨论】:

              【解决方案12】:

              作为一个菜鸟的答案,我花了很多时间来弄清楚它。 我遵循的步骤是:

              1. 打开查找器并按Command(Windows) + Shift + G
              2. 进入文件夹添加~/Library/Developer
              3. 搜索您创建的数据库名称,在我的例子中它是 SQLite 中的my.db
              4. 为 SQLite 下载并安装 DB 浏览器。
              5. 点击打开数据库。
              6. 现在从查找器中拖放数据库文件。

              【讨论】:

                【解决方案13】:

                由于没有人指出,如何从物理设备获取sqlite DB。

                获取应用数据的方法如下:

                Browse the files created on a device by the iOS application I'm developing, on workstation?

                打开 .xcappdata 文件后(右键 > Show Package Content),您通常会在 AppData/Library/Application Support 文件夹中找到 DB 文件。

                【讨论】:

                  【解决方案14】:

                  很惊讶没有人提到这一点,但假设您的核心数据存储是 sqlite,您可以在终端中执行此操作,无需 3rd 方工具即可对其内容进行快速而肮脏的转储:

                  $ sqlite3 <path-to-file.sqlite>
                  
                  // Dump everything
                  sqlite> .dump
                  
                  // Dump just one type
                  sqlite> .dump ZSOMETYPE
                  
                  // ^D to exit
                  

                  【讨论】:

                    【解决方案15】:

                    我无法在 iPhone Simulator 文件夹中找到它。 然后我通过在日志中打印文档路径找到了该文件夹:

                    NSLog(@"The Path is %@", 
                      [[[NSFileManager defaultManager] URLsForDirectory:
                         NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
                    

                    原来的路径是这样的:

                    // /Users/<username>/Library/Developer/CoreSimulator/Devices/<app specific id>/data/Containers/Data/Application/<id>/Documents/coredata.sqlite
                    

                    【讨论】:

                      【解决方案16】:

                      如果您已经访问过 sqlite、shm 和 wal 文件,则在终端中运行命令将 WAL 文件合并到 sqlite 文件中。

                      $ sqlite3 persistentStore
                      sqlite> PRAGMA wal_checkpoint;
                      Press control + d
                      

                      运行上述命令后,您可以在 sqlite 文件中看到数据。


                      将 sqlite 文件复制到桌面的实用程序(请更改桌面路径并提供绝对路径,~ 符号将不起作用。

                      对于iOS 10.0+,您可以使用 persistentContainer.persistentStoreCoordinator.persistentStores.first?.url

                      我已经创建了将 sqlite 文件复制到您想要的位置的实用程序函数(仅适用于模拟器)。 您可以使用它喜欢的实用程序

                      import CoreData
                      
                      
                      let appDelegate = UIApplication.shared.delegate as! AppDelegate
                      UTility.getSqliteTo(destinationPath: "/Users/inderkumarrathore/Desktop", persistentContainer: appDelegate.persistentContainer)
                      

                      这里是的实用方法的定义

                      /**
                       Copies the sqlite, wal and shm file to the destination folder. Don't forget to merge the wal file using the commands printed int the console.
                       @param destinationPath Path where sqlite files has to be copied
                       @param persistentContainer NSPersistentContainer
                      */
                      public static func getSqliteTo(destinationPath: String, persistentContainer: NSPersistentContainer) {
                        let storeUrl = persistentContainer.persistentStoreCoordinator.persistentStores.first?.url
                        
                        let sqliteFileName = storeUrl!.lastPathComponent
                        let walFileName = sqliteFileName + "-wal"
                        let shmFileName = sqliteFileName + "-shm"
                        //Add all file names in array
                        let fileArray = [sqliteFileName, walFileName, shmFileName]
                        
                        let storeDir = storeUrl!.deletingLastPathComponent()
                        
                        // Destination dir url, make sure file don't exists in that folder
                        let destDir = URL(fileURLWithPath: destinationPath, isDirectory: true)
                      
                        do {
                          for fileName in fileArray {
                            let sourceUrl = storeDir.appendingPathComponent(fileName, isDirectory: false)
                            let destUrl = destDir.appendingPathComponent(fileName, isDirectory: false)
                            try FileManager.default.copyItem(at: sourceUrl, to: destUrl)
                            print("File: \(fileName) copied to path: \(destUrl.path)")
                          }
                        }
                        catch {
                          print("\(error)")
                        }
                        print("\n\n\n ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NOTE ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n")
                        print("In your terminal run the following commands to merge wal file. Otherwise you may see partial or no data in \(sqliteFileName) file")
                        print("\n-------------------------------------------------")
                        print("$ cd \(destDir.path)")
                        print("$ sqlite3 \(sqliteFileName)")
                        print("sqlite> PRAGMA wal_checkpoint;")
                        print("-------------------------------------------------\n")
                        print("Press control + d")      
                      }
                      

                      对于

                      /**
                       Copies the sqlite, wal and shm file to the destination folder. Don't forget to merge the wal file using the commands printed int the console.
                       @param destinationPath Path where sqlite files has to be copied
                       @param persistentContainer NSPersistentContainer
                       */
                      + (void)copySqliteFileToDestination:(NSString *)destinationPath persistentContainer:(NSPersistentContainer *)persistentContainer {
                        NSError *error = nil;
                        NSURL *storeUrl = persistentContainer.persistentStoreCoordinator.persistentStores.firstObject.URL;
                        NSString * sqliteFileName = [storeUrl lastPathComponent];
                        NSString *walFileName = [sqliteFileName stringByAppendingString:@"-wal"];
                        NSString *shmFileName = [sqliteFileName stringByAppendingString:@"-shm"];
                        //Add all file names in array
                        NSArray *fileArray = @[sqliteFileName, walFileName, shmFileName];
                        
                        // Store Directory
                        NSURL *storeDir = storeUrl.URLByDeletingLastPathComponent;
                      
                        // Destination dir url, make sure file don't exists in that folder
                        NSURL *destDir = [NSURL fileURLWithPath:destinationPath isDirectory:YES];
                        
                        for (NSString *fileName in fileArray) {
                          NSURL *sourceUrl = [storeDir URLByAppendingPathComponent:fileName isDirectory:NO];
                          NSURL *destUrl = [destDir URLByAppendingPathComponent:fileName isDirectory:NO];
                          [[NSFileManager defaultManager] copyItemAtURL:sourceUrl toURL:destUrl error:&error];
                          if (!error) {
                            RLog(@"File: %@ copied to path: %@", fileName, [destUrl path]);
                          }
                        }
                        
                        
                        NSLog(@"\n\n\n ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NOTE ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n");
                        NSLog(@"In your terminal run the following commands to merge wal file. Otherwise you may see partial or no data in %@ file", sqliteFileName);
                        NSLog(@"\n-------------------------------------------------");
                        NSLog(@"$ cd %@", destDir.path);
                        NSLog(@"$ sqlite3 %@", sqliteFileName);
                        NSLog(@"sqlite> PRAGMA wal_checkpoint;");
                        NSLog(@"-------------------------------------------------\n");
                        NSLog(@"Press control + d");
                      }
                      

                      【讨论】:

                      • 我会看看这个 - 自从我查看核心数据以来已经有一段时间了:-)
                      • @JeffKranenburg 不是问题:),我遇到了同样的问题,并想制定一些解决方案来解决获取核心数据 sqlite 存储的问题。这个方法解决了我的目的,我希望其他人可以从这个方法中受益
                      【解决方案17】:

                      只需在 viewDidLoad 中添加:

                      debugPrint(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
                      

                      【讨论】:

                        【解决方案18】:

                        我发现查找和打开 .sqlite 数据库的最佳方法是使用此脚本:

                        lsof -Fn -p $(pgrep YOUR_APP_NAME_HERE) | grep .sqlite$ | head -n1
                        

                        无论出于何种原因,我的 Mac 上的输出总是有一个额外的 n 字符,所以我不得不将它复制并粘贴到 open 命令。如果您找到正确的命令,请随意修改上述命令。

                        对于最好的 SQLite 浏览器,我推荐 TablePlus。

                        采纳自: https://lukaszlawicki.pl/how-to-quickly-open-sqlite-database-on-ios-simulator/

                        【讨论】:

                          【解决方案19】:

                          print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!")

                          请将此行添加到 AppDelegate 的 applicationDidFinishLaunching 中。 它将为我们提供文档的路径。 但核心数据的数据库位于./Library/Application Support/,名称为projectname.sqlite

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-05-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多