Розташування файлів Sqlite Основні дані


91

Зазвичай файл сховища sqlite для додатків основних даних знаходиться в

Бібліотека> Підтримка додатків> Симулятор iPhone> 7.1 (або будь-яка версія, яку ви використовуєте)> Програми> (Яка папка містить вашу програму)> Документи

, але я не можу знайти його в IOS 8. Я б припустив, що вони просто додадуть папку 8.0 всередині папки iPhone Simulator, але її там немає. Хтось зміг його знайти?


2
Я майже впевнений, що ваше запитання є дублікатом, враховуючи, що я поставив його за тиждень до вашого запитання. Буде вдячно, якщо ви дозволите мені отримати кредит за це питання, враховуючи, що це перше питання, яке я коли-небудь задавав, і, схоже, у вас вже є репутація @HenryGlendening
enlyte

Перевірте це , як перевірити DBPATH stackoverflow.com/a/27358291/3840428
Nagarjun

Дотримуйтесь за цим один ... stackoverflow.com/questions/24290989 / ...
Tunvir Рахман Tusher

2
Хтось знає, як отримати файли CoreData з власне пристрою? Раніше я робив це через iTunes у старих версіях Xcode, але, оскільки Xcode 8 / iOS10, я не думаю, що файли CoreData зберігаються в каталозі документів програми, отже, вони не відображаються в iTunes. Чи є спосіб отримати файли CoreDate з пристрою на вашому комп’ютері?
Bocaxica

1
Я не знаю, чому вони продовжують це рухати. Вони повинні їх десь покласти і просто залишити.
RegularExpression

Відповіді:


135

Мені вдалося знайти файл sqlite, і він знаходиться в цьому шляху зараз:

Бібліотека / Розробник / CoreSimulator / Пристрої / (цифри та літери) / дані / Контейнери / Дані / Застосування / (цифри та літери) / Документи /

(цифри та літери) означає папку, яка буде унікальною для вашого додатка / комп’ютера, але виглядатиме так: 779AE2245-F8W2-57A9-8C6D-98643B1CF01A

Мені вдалося його знайти, зайшовши в appDelegate.m, прокрутивши до

- (NSURL *)applicationDocumentsDirectory 

і NSLogging зворотний шлях, наприклад:

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    NSLog(@"%@",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory  inDomains:NSUserDomainMask] lastObject]);

    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
 }

Це дасть вам ваш унікальний шлях, що полегшить вам роботу, оскільки складно знайти його за допомогою 2 безіменних папок / рядків букв і цифр.

Свіфт 4.2:

let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
print(paths[0])

4
Використовуйте xcrun simctl listдля отримання списку назв симуляторів та їх UUID.
Сенді Чепмен

1
Зверніть увагу, що якщо ви використовуєте спільну базу даних для групи програм (наприклад, коли ви використовуєте розширення), шлях буде Бібліотека / Розробник / CoreSimulator / Пристрої / $ number / data / Containers / Shared / AppGroup / $ number / Name.sqlite
andreacipriani

7
Зауважте, що у 2019 році Library/Developer/CoreSimulator/Devices/(numbers and letters)/data/Containers/Data/Application/(numbers and letters)/Documents/це вже не відповідає дійсності. Тепер ви знайдете .sqlite та пов’язані з ним два файлиLibrary/Developer/CoreSimulator/Devices/(numbers and letters)/data/Containers/Data/Application/(numbers and letters)/Library/Application Support/
Gang Fang

@GangFang Я намагаюся перетворити мій код Objective C, який побудований в Xcode 7, на останню швидку версію і створити новий проект, так як я можу перенести цей два різні файли .sqlite в одне місце.
Санджай Шах

85

Жодна з відповідей не згадує найпростіший спосіб фактично отримати розташування файлу БД.

Це навіть не вимагає від вас модифікації вихідного коду, оскільки це простий перемикач часу роботи в XCode.

  1. Виберіть Редагувати схему ... біля кнопки Виконати.

    редагувати схему

  2. Виберіть Виконати / Аргументи та додайте наступні два варіанти:

    -com.apple.CoreData.SQLDebug 1
    -com.apple.CoreData.Logging.stderr 1

    варіант

  3. Запустіть програму, і ви побачите в журналах:

    журнали


2
Це справді найпростіше і найкраще рішення. Дякую!
Омід Аріян

Для мене журнал не з'являється, ви можете мені допомогти?
Августо,

@Augusto Я не можу вам тут допомогти, але якщо ви задасте нове запитання щодо цього, люди, ймовірно, можуть відповісти на нього та допомогти вам.
гіпервузол

Чудова відповідь! Це має бути прийнятою відповіддю. Також є який-небудь спосіб, про який ви знаєте, щоб змінити колір цього виводу на консолі, крім параметрів Xcode? Було б непогано, якби це
виділилося

Дякую за підказку! Шлях постійно змінюється, для мене зараз (iOS 13.3.1) шлях є / Users / *** / Library / Developer / CoreSimulator / Devices / A91CEB1C-B15D-46B5-9B83-DB22056DEFD1 / data / Containers / Shared / AppGroup / B835599A- CA36-432F-871A-17EDA181CC54 / Тож краще отримувати його з інформації про налагодження CoreData, а не намагатися вгадати самостійно.
AlKir

52

Спробуйте цей простий 3 крок

  1. Скопіюйте наступний код у didFinishLaunchingWithOptionsсвій appdelegate.mі додайте точку розриву передNSLog()

    (BOOL)application:(UIApplication *)application  
    
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSLog(@"%@",[paths objectAtIndex:0]);
     }

Або в Свіфт:

let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
print(paths[0])

введіть тут опис зображення

2. Відкрийте Finder-> Go -> Go to folder і вставте шлях, скопійований з кроку 1

введіть тут опис зображення

3. Я !!! Ви знаходитесь у своєму пункті призначення.


2
Для використання swift3: NSSearchPathForDirectoriesInDomains (.applicationSupportDirectory, .userDomainMask, true)
Yohst

38

Якщо у вашій програмі використовуються основні дані, це просто питання пошуку файлу sqlite у терміналі:

find ~ -name app_db_file_name.sqlite

У результатах буде вказаний повний шлях до папок симулятора, що містять вашу програму.


2
@AlexWei Я бажаю, щоб Apple додала кнопку в меню "Файл" до "Розкрити папку документів Simulator у пошуку" або щось подібне. Здається смішним, що його все ще немає, враховуючи, що вони постійно змінюють місце зберігання файлів ...
DiscDev

1
У разі інші зацікавлені, я додав цю команду в якості псевдоніма для моєї .profile: alias myapp_simulator_db="find ~/Library/Developer/CoreSimulator/Devices -name MyApp.sqlite". Це зручно, коли вам потрібно повторно запускати цю команду.
тост

sudo find ~ -name app_db_file_name.sqlite мені допомогло
Кадір Хуссейн,

21

Я зламав цей однокласник ( Gist ): find ~/Library/Developer/CoreSimulator/Devices/ -name device.plist -exec sh -c "/usr/libexec/PlistBuddy -c \"print UDID\" '{}' | tr '\n' ' '" \; -exec sh -c "/usr/libexec/PlistBuddy -c \"print name\" '{}' | tr '\n' ' '" \; -exec sh -c "/usr/libexec/PlistBuddy -c \"print runtime\" '{}' | sed -n 's/com\.apple\.CoreSimulator.SimRuntime\.\(.*\)/\1/p'" \;

Це друкує:

14F313C8-3813-4E38-903E-2010C136B77B iPad Retina iOS-8-0
1F6B82A2-C467-479A-8CAF-074BE507AC8E iPad Air iOS-8-0
2DA83944-BE5D-4342-B330-08F67A932D8C iPad 2 iOS-7-1
48703432-A5C5-4606-9369-0D21B53EB1E8 iPhone 4s iOS-7-1
4AFB71CC-6752-4F9A-A239-4DC9CA53A8B8 iPhone 5s iOS-8-0
53A65771-DF50-4A5C-A8D2-4D1C3A5D0F60 iPhone 5 iOS-7-1
6B97C174-5914-4E89-8D17-943F0E2703BA iPhone 5 iOS-8-0
6C2DF3E9-FA26-4391-8B66-72E1467D6297 iPad 2 iOS-8-0
7F85E299-A3C2-4704-8B44-2984F6F995F5 iPad Retina iOS-7-1
8B9EDFFD-2240-476B-88AD-06ABE8F9FF51 iPhone 6 Plus iOS-8-0
97691E5D-5C38-4875-8AA7-C2B1E4ABCBB5 Resizable iPhone iOS-8-0
9BBF3408-6CA4-4CE0-BD4E-B02001F1262B iPhone 5s iOS-7-1
C9237847-F0AA-44BC-A74E-C08C2E0F7A6C Resizable iPad iOS-8-0
CC44C1BA-F39C-4410-AE34-4ABBD7806D45 iPad Air iOS-7-1
CDF4D811-5011-4464-8291-5CDA378375EA iPhone 6 iOS-8-0
E77DE00C-E244-4F25-A5E2-E6581614D5A2 iPhone 4s iOS-8-0

Оновлення:

Як хтось вказував тут , можна також бігти, xcrun simctl list devicesщоб отримати подібний результат:

== Devices ==
-- iOS 7.0 --
-- iOS 7.1 --
    iPhone 4s (48703432-A5C5-4606-9369-0D21B53EB1E8) (Shutdown)
    iPhone 5 (53A65771-DF50-4A5C-A8D2-4D1C3A5D0F60) (Shutdown)
    iPhone 5s (9BBF3408-6CA4-4CE0-BD4E-B02001F1262B) (Shutdown)
    iPad 2 (2DA83944-BE5D-4342-B330-08F67A932D8C) (Shutdown)
    iPad Retina (7F85E299-A3C2-4704-8B44-2984F6F995F5) (Shutdown)
    iPad Air (CC44C1BA-F39C-4410-AE34-4ABBD7806D45) (Shutdown)
-- iOS 8.1 --
    iPhone 4s (0763EF65-DD0D-4FAD-84C7-2DE63D416526) (Shutdown)
    iPhone 5 (868ED444-8440-4115-AF37-F419CC682D2F) (Shutdown)
    iPhone 5s (E0455E5D-7315-4EC8-B05E-76284728244C) (Shutdown)
    iPhone 6 Plus (72554908-FF99-4B8F-9B87-65255ED08CFC) (Shutdown)
    iPhone 6 (32AA8133-53A4-4BE0-8CE5-0C7A87E81CAF) (Shutdown)
    iPad 2 (4AF84DE8-CBA2-47AE-A92A-0C0CEF9F41F8) (Booted)
    iPad Retina (69238B44-AAFD-4CD5-AAEA-C182D0BC300D) (Shutdown)
    iPad Air (E580AD99-0040-4EC1-B704-0C85567E6747) (Shutdown)
    Resizable iPhone (32E872FC-6513-41AB-A5B9-B23EB7D10DC8) (Shutdown)
    Resizable iPad (99997922-4A9F-4574-9E3E-EF45F893F4A2) (Shutdown)

18

Якщо ви використовуєте Swift , це поверне абсолютний шлях до каталогу документів:

func applicationDirectoryPath() -> String {
    return NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last! as String
}

1
Повинен бути названий "func documentDirectoryPath ()", що саме там ви збираєтеся ...
Йохст

13

Я написав скрипт bash для пошуку розташування вашої папки Програми та папки Даних Програми в симуляторі, ви можете завантажити її тут . Розпакувавши скрипт, ви зможете перейти до папки, в якій знаходиться скрипт, і використовувати його. Якщо ви зателефонуєте йому без опцій, він надасть вам список встановлених симуляторів iOS. Потім ви можете використовувати параметри, щоб знайти свою програму. Написання:

./simulatorAppFolders -s "iPad Air" -i iOS-8-0 -a <MyApp>

знайде папку програми та папку домашньої області для вашої програми на симуляторі iPad Air iOS 8. Ось приклад:

MacBook-Air:_posts user$ ./simulatorAppFolders -s "iPad Air" -i iOS-8-0 -a MyApp
App folder = /Users/james/Library/Developer/CoreSimulator/Devices/6A9DEE93-FAEF-4BF4-9989-BC14CD38AEA0/data/Containers/Bundle/Application/8F64CD7F-A227-43D6-98AC-41D3919827CB
dataFolder = /Users/james/Library/Developer/CoreSimulator/Devices/6A9DEE93-FAEF-4BF4-9989-BC14CD38AEA0/data/Containers/Data/Application/96C40A21-5A5C-4399-839C-B155B8A72932

Оновлення

Оновлено оригінальний сценарій, який дозволяє шукати за типом пристрою за допомогою параметра -d. Я також написав інший скрипт, який створює низку розумно названих папок, щоб ви могли знайти свою заявку та документи заявки. Цей скрипт створить папку під назвою iOS_SIMULATORS у вашому домі, і ви зможете легко перейти до неї звідти.


Прекрасно, я відредагував ваш сценарій, щоб створити ще один, який перевстановить усі дані симулятора певної програми. Велике спасибі Джеймсе!
Мартін

Дякую! Прекрасне рішення для поширеного PITA.
David Hersey

6

Мені вдалося знайти папку симуляторів з наступним висновком консолі:

NSLog(@"app dir: %@",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);

у моєму випадку це було (Xcode 6 beta)

app dir: file:///Users/user/Library/Developer/CoreSimulator/Devices/D00C56D4-DDA3-47B0-9951-27D3B9EC68E8/data/Applications/6ABF3E54-37F5-4AD1-A223-F7467F601FB6/Documents/

6

На основі відповідей Майклза, це для Swift 3

    func applicationDirectoryPath() -> String {
        return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as String
    }

Єдине рішення тут!
Fattie

5

Для Swift 3.0

let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
print(paths[0])

Ви можете дізнатись про місцезнаходження Coredata в Xcode 8.2


5

Після нових оновлень Xcode я виявив, що файли sql тепер зберігаються в новій папці, /Library/Application Supportце може бути унікальною ситуацією, але якщо ви не знайшли файли sql у папці документів, знайдіть їх тут:

~/Library/Developer/CoreSimulator/Devices/[@device_id@]/data/Containers/Data/Application/[@application_id@]/Library/Application Support/

до того, як його було збережено в Documentsпапці:

~/Library/Developer/CoreSimulator/Devices/[@device_id@]/data/Containers/Data/Application/[@application_id@]/Documents/


4

Для SWIFT 3:

Скопіюйте вставте цей код у didFinishLaunchingWithOptions

 print(NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last! as String)

Це мені допомогло. але коли я намагаюся перейти до цього шляху через термінал, він пише: Немає такого файлу або каталогу, але коли я намагаюся перейти до опції папки, він насправді існує.
Кадір Хуссейн,

Це працювало для мене на OSX. Мені потрібно було пройти ще 1 каталог у каталозі "Підтримка додатків" з назвою <назва мого додатка>, щоб штрафувати файл .sqlite.
Jacksonsox

3

Для швидкого 3

print(NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last! as String)

2

Як Джеймс Снук я створив власний сценарій, щоб забезпечити простіший доступ до програм-симуляторів. Я думаю, що це може бути корисно багатьом людям, які сюди потрапляють, крім мене.

На відміну від його сценарію, мій не є інструментом пошуку, він створює повну (і зручну для читання) структуру папок з усіма пристроями / середовищами виконання та розміщує в них м’які посилання на програми.

Ви можете отримати це в цьому звіті .

Запустіть його щоразу, коли встановлюєте програму в симуляторі, або просто запускайте щоразу, коли збираєтеся за якою-небудь причиною отримувати програму (вона буде оновлюватися та відкривати папку пристроїв у Finder).


Ви можете адаптувати цей сценарій для автоматизації деяких речей. Але я повинен сказати, що ця програма з графічним інтерфейсом, яку я щойно знайшов, звучить як дійсно корисна альтернатива, якщо ви просто хочете отримати доступ до папок програми :)
fbeeper

Це теж досить приємно, але я віддаю перевагу другому сценарію, опублікованому Джеймсом Снуком, оскільки він також створює м’які посилання на каталоги даних.
Девід Герсі,

2

Якщо ви не вказали жодного каталогу, тоді ви можете використати наведений нижче код для друку каталогу за замовчуванням:

print (NSPersistentContainer.defaultDirectoryURL ())


1

Для 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)

Якщо ви вже мали доступ до файлів sqlite, shm та wal, тоді запустіть команди в терміналі, щоб об'єднати файл WAL у файл sqlite.

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

Після запуску вищевказаних команд ви зможете побачити дані у своєму файлі sqlite.


Ось визначення методу корисності для

/**
 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");
}

0

Свіфт 3.x

Знайдіть функцію didFinishLaunchingWithOptions у вашому файлі AppDelegate та передайте там цей код.

let path = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)
print("\(path)")

0

Стрімкий 4.x

    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
    print(paths[0])

0

Свіфт 4.2

let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        print(paths[0])

-1

Ви можете використовувати наступний код.

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    **print(persistentContainer.persistentStoreDescriptions)**
    return true
}

Він надрукує розташування постійного сховища основних даних, тобто sqlite

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.