如何检查存储在核心数据库中的内容?

我正在开发一个依赖于核心数据的应用程序。我能够输入数据到一个文本字段并存储它。

但我需要知道数据是否被存储了。

我正在尝试为我的 tableView 创建一个 detailView,但是没有得到任何结果。现在我想知道是因为我的代码出了问题,还是因为数据被正确地存储了。

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

85582 次浏览

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

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

要打开 sqlite文件,您需要一个工具。

给你下载 SQLite 浏览器。

在模拟器中运行你的应用程序。应用程序应该被复制到你 Mac 上的一个路径,看起来像这样:

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

一旦找到了应用程序,就必须深入挖掘才能找到 sqlite db (它通常位于 Document 下面)。

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

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

编辑方案,并将其添加到“ Arguments Passed on Launch”中

- com.apple. CoreData.SQLDebug 1

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

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

接下来是 Ios 8模拟器的文档目录在哪里

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

对我来说非常有效;)

我在 iPhone 模拟器文件夹里找不到。 然后我通过打印日志中的 doc 路径找到了这个文件夹:

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

以下是我的解决方案(适用于 iOS9) :

我使用一个自动化程序/bash 脚本,它在 sqlliteBrowser 中打开数据库。该脚本在模拟器中找到最新安装的应用程序。 说明:

  1. 为 SQLite 安装 DB 浏览器(http://sqlitebrowser.org/)
  2. 在 Apple Automator 中创建新的工作流。
  3. 拖动“ Run Shell script block”并粘贴以下代码:
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

enter image description here

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

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)在 AppStore 下载程式,例如 SQLPro

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

干得好! 你会看到这样的东西: enter image description here

在 Swift 3中,你有 NSPersistentContainer,你可以像下面这样检索路径:

persistentContainer.persistentStoreCoordinator.persistentStores.first?.url

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

就 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-打开终端并粘贴:

xcrun xctrace list devices

如果您已经访问了 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");
}

作为一个菜鸟的答案,我花了相当多的时间来弄明白。 我所遵循的步骤如下:

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

斯威夫特4,5

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

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

你的 modelName.sqlite档案会在那里。

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

只需添加 viewDidLoad:

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

其他的解决方案要么是旧的,要么不能很容易或很快地指向 SQLite 文件,所以我使用 FileManager.SearchPathDirectory.applicationSupportDirectory提出了自己的解决方案,它可以得到 SQLite 文件所在的确切路径。

使用 FileManager.default的解决方案 # 1:
func whereIsMySQLite() {
let path = FileManager
.default
.urls(for: .applicationSupportDirectory, in: .userDomainMask)
.last?
.absoluteString
.replacingOccurrences(of: "file://", with: "")
.removingPercentEncoding
    

print(path ?? "Not found")
}
使用 NSPersistentContainer.defaultDirectoryURL()的解决方案 # 2:
func whereIsMySQLite() {
let path = NSPersistentContainer
.defaultDirectoryURL()
.absoluteString
.replacingOccurrences(of: "file://", with: "")
.removingPercentEncoding


print(path ?? "Not found")
}

无论是 whereIsMySQLite()将打印路径,您可以简单地复制粘贴到您的 Mac 在这里:

Finder > Go > Go to file

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

以下是获取应用程序数据的方法:

浏览由我开发的 iOS 应用程序在设备上创建的文件,在工作站上?

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

使用 核心数据实验室这样的工具是定位核心数据库、查看和分析内容的一种简单方便的方法。

更多信息请点击: https://betamagic.nl/products/coredatalab.html

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

我发现找到并打开.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/

令人惊讶的是没有人提到这一点,但是假设你的核心数据存储是轻巧的,你可以做一个快速和肮脏的转储其内容没有第三方工具在终端这样做:

$ sqlite3 <path-to-file.sqlite>


// Dump everything
sqlite> .dump


// Dump just one type
sqlite> .dump ZSOMETYPE


// ^D to exit

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

请将此行添加到 applicationDidFinishLaunching of AppDelegate 中。 它会给我们文件的路径。 但是核心数据库在 ./Library/Application Support/中,名为 projectname.sqlite

打开 Mac OS 终端并键入以下命令

xcrun simctl get_app_container booted com.ondevtratech.PlannerCoreData




xcrun simctl get_app_container booted <bundle <>identifier>

打开一具尸体:

Brewinstall ——木桶数据库浏览器 for-sqlite

Open < < App path: sql lite.App > > < < . sqlite DB path > >

例如: 用于 SQLite.app/DTMPlanner.sqlite 的 open-a/Applications/DB 浏览器