我正在制作一个依赖 Core Data 的应用程序。我能够在文本字段中输入数据并存储它。
但我需要知道数据是否被存储。
我正在尝试为我的 tableView 制作一个 detailView,但没有得到任何结果。现在我想知道是因为我的代码做错了什么,或者数据是否被正确存储。
如何查看应用程序的 CoreData 数据库中存储的内容?
这是我的解决方案(适用于 iOS 9):
我使用 automator/bash 脚本在 sqllitebrowser 中打开数据库。该脚本在模拟器中查找最新安装的应用程序。指示:
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
斯威夫特 4, 5
AppDelegate
在>>didFinishLaunchingWithOptions
函数中添加这一行:
print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!")
你的modelName.sqlite
文件会在那里。
您可以使用任何免费的 SQLite 浏览器工具(例如http://sqlitebrowser.org/ )打开它。
如果您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)。
其他解决方案要么是旧的,要么不能轻松或快速地将您引导到 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 > 前往 > 前往文件夹
存储 db 的文件夹最近已更改,并且不是您希望找到的文件夹。这是我用来解决这个问题的方法:首先将此代码添加到您的 viewDidLoad 或 applicationDidFinishLaunching:
#if TARGET_IPHONE_SIMULATOR
// where are you?
NSLog(@"Documents Directory: %@", [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
#endif
从这里得到这个: ios 8 模拟器的文档目录在哪里
这将在运行时显示您的应用在控制台中的实际位置。然后使用SQLiteBrowser检查 SQLite DB 的内容。
对我来说就像一个魅力;)
就 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
如前所述,您可以使用 sqllite 命令行工具。
但是,您也可以设置调试标志,这将在它们通过核心数据执行时转储所有 sql 命令。
编辑方案,并将其添加到“启动时传递的参数”中
-com.apple.CoreData.SQLDebug 1
在 Swift 3 中,你有NSPersistentContainer
并且你可以从那里检索路径,如下所示:
persistentContainer.persistentStoreCoordinator.persistentStores.first?.url
(假设您只使用一个持久存储)
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”的文件夹中打开文件。
定位 Core Data 数据库以及查看和分析内容的一种简单方便的方法是使用Core Data Lab之类的工具。
更多信息:https ://betamagic.nl/products/coredatalab.html
免责声明:我是这个工具的创造者。
从这里下载 SQLite 浏览器。
在模拟器中运行您的应用程序。该应用程序应复制到 Mac 上如下所示的路径:
/Users/$your username$/Library/Application Support/iPhone Simulator/$your iphone simulator version$/Applications/
找到您的应用程序后,您必须深入挖掘以找到 sqlite db(通常在 Documents 下)。
作为一个菜鸟的答案,我花了很多时间来弄清楚它。我遵循的步骤是:
Command(Windows) + Shift + G
。~/Library/Developer
my.db
在 SQLite 中创建的数据库名称。由于没有人指出,如何从物理设备中获取 sqlite DB。
以下是获取应用程序数据的方法:
在工作站上浏览我正在开发的 iOS 应用程序在设备上创建的文件?
打开 .xcappdata 文件(右键单击 > 显示包内容)后,您通常会在 AppData/Library/Application Support 文件夹中找到 DB 文件。
我无法在 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
我发现查找和打开 .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/
很惊讶没有人提到这一点,但假设您的核心数据存储是 sqlite,您可以在终端中执行此操作,无需 3rd 方工具即可对其内容进行快速和脏转储:
$ sqlite3 <path-to-file.sqlite>
// Dump everything
sqlite> .dump
// Dump just one type
sqlite> .dump ZSOMETYPE
// ^D to exit
如果您已经访问过 sqlite、shm 和 wal 文件,则在终端中运行命令将 WAL 文件合并到 sqlite 文件中。
$ sqlite3 persistentStore
sqlite> PRAGMA wal_checkpoint;
Press control + d
运行上述命令后,您可以在 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")
}
对于目标-c
/**
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");
}
只需添加 viewDidLoad:
debugPrint(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!")
请将此行添加到 AppDelegate 的 applicationDidFinishLaunching 中。它将为我们提供文档的路径。但核心数据数据库./Library/Application Support/
同名projectname.sqlite
。
打开 Mac OS 终端并键入以下命令
xcrun simctl get_app_container booted com.ondevtratech.PlannerCoreData
xcrun simctl get_app_container booted <bundle <>identifier>
打开数据库:
brew install --cask db-browser-for-sqlite
打开 << 应用路径:sql lite.app >> <<.sqlite 数据库路径>>
例如: open -a /Applications/DB\ Browser\ for\ SQLite.app /DTMPlanner.sqlite