【问题标题】:saving JSON response locally in database Objective C在数据库Objective C中本地保存JSON响应
【发布时间】:2017-10-18 06:11:06
【问题描述】:

我有一个用于 GET API 请求的 questioAnswer responseObject:

{"7d2c591c-9056-405c-9509-03266842b7e5"=();"f884a7d1-f9d9-4563-bb6e-94538664f3bd"=test;}

如何根据特定的调查 uuid 将其本地保存在数据库中?

【问题讨论】:

    标签: ios objective-c json core-data nsdictionary


    【解决方案1】:

    您可以将其保存在会话中。

    设置:

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    
    [userDefaults setObject:value 
                     forKey:key];
    [userDefaults synchronize];
    

    获取:

    [[NSUserDefaults standardUserDefaults] objectForKey:key];
    

    编辑

    只是为了阐述将 Core Data 添加到以前没有的项目中实际需要执行的所有步骤:

    第 1 步:添加框架

    点击您的应用程序目标(在左侧窗格中,其顶部图标带有您的应用程序名称),然后转到“构建阶段”选项卡,然后在“将二进制文件与库链接”上,单击小“+”在底部然后找到'CoreData.framework'并将其添加到您的项目中

    然后使用以下方法在所有需要它的对象上导入 coredata(非性感方式):

    斯威夫特

    import CoreData
    

    目标 C

    #import <CoreData/CoreData.h>
    

    或在您的 .pch 文件中的常见导入下方添加导入(更性感),如下所示:

    #ifdef __OBJC__
        #import <UIKit/UIKit.h>
        #import <Foundation/Foundation.h>
        #import <CoreData/CoreData.h>
    #endif
    

    第 2 步:添加数据模型

    要添加 .xcdatamodel 文件,请在右侧窗格中右键单击/控制单击您的文件(例如在资源文件夹中以确保安全)并选择添加新文件,在选择文件类型时单击核心数据选项卡然后单击“数据模型”,为其命名并单击下一步和完成,它将将其添加到您的项目中。当您单击此模型对象时,您将看到将实体添加到您的项目中的界面以及您想要的任何关系。

    第 3 步:更新 App Delegate

    在 AppDelegate.swift 上的 Swift

    //replace the previous version of applicationWillTerminate with this
    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        // Saves changes in the application's managed object context before the application terminates.
        self.saveContext()
    }
    
    func saveContext () {
        var error: NSError? = nil
        let managedObjectContext = self.managedObjectContext
        if managedObjectContext != nil {
            if managedObjectContext.hasChanges && !managedObjectContext.save(&error) {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                //println("Unresolved error \(error), \(error.userInfo)")
                abort()
            }
        }
    }
    
    // #pragma mark - Core Data stack
    
    // Returns the managed object context for the application.
    // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
    var managedObjectContext: NSManagedObjectContext {
        if !_managedObjectContext {
            let coordinator = self.persistentStoreCoordinator
            if coordinator != nil {
                _managedObjectContext = NSManagedObjectContext()
                _managedObjectContext!.persistentStoreCoordinator = coordinator
            }
        }
        return _managedObjectContext!
    }
    var _managedObjectContext: NSManagedObjectContext? = nil
    
    // Returns the managed object model for the application.
    // If the model doesn't already exist, it is created from the application's model.
    var managedObjectModel: NSManagedObjectModel {
        if !_managedObjectModel {
            let modelURL = NSBundle.mainBundle().URLForResource("iOSSwiftOpenGLCamera", withExtension: "momd")
            _managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
        }
        return _managedObjectModel!
    }
    var _managedObjectModel: NSManagedObjectModel? = nil
    
    // Returns the persistent store coordinator for the application.
    // If the coordinator doesn't already exist, it is created and the application's store added to it.
    var persistentStoreCoordinator: NSPersistentStoreCoordinator {
        if !_persistentStoreCoordinator {
            let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("iOSSwiftOpenGLCamera.sqlite")
            var error: NSError? = nil
            _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
            if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
                /*
                Replace this implementation with code to handle the error appropriately.
                abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                Typical reasons for an error here include:
                * The persistent store is not accessible;
                * The schema for the persistent store is incompatible with current managed object model.
                Check the error message to determine what the actual problem was.
                If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
                If you encounter schema incompatibility errors during development, you can reduce their frequency by:
                * Simply deleting the existing store:
                NSFileManager.defaultManager().removeItemAtURL(storeURL, error: nil)
                * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
                [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true}
                Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
                */
                //println("Unresolved error \(error), \(error.userInfo)")
                abort()
            }
        }
        return _persistentStoreCoordinator!
    }
    var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil
    
    // #pragma mark - Application's Documents directory
    
    // Returns the URL to the application's Documents directory.
    var applicationDocumentsDirectory: NSURL {
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.endIndex-1] as NSURL
    }
    

    在 Objective C 中,确保将这些对象添加到 AppDelegate.h

     @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
     @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
     @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
    
     - (NSURL *)applicationDocumentsDirectory; // nice to have to reference files for core data
    

    像这样在 AppDelegate.m 中合成之前的对象:

    @synthesize managedObjectContext = _managedObjectContext;
    @synthesize managedObjectModel = _managedObjectModel;
    @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
    

    然后将这些方法添加到 AppDelegate.m(确保将您添加的模型的名称放在显示的位置):

    - (void)saveContext{
        NSError *error = nil;
        NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
        if (managedObjectContext != nil) {
            if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }
        }
    }
    
    - (NSManagedObjectContext *)managedObjectContext{
        if (_managedObjectContext != nil) {
            return _managedObjectContext;
        }
    
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            _managedObjectContext = [[NSManagedObjectContext alloc] init];
            [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        }
        return _managedObjectContext;
    }
    
    - (NSManagedObjectModel *)managedObjectModel{
        if (_managedObjectModel != nil) {
            return _managedObjectModel;
        }
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAMEOFYOURMODELHERE" withExtension:@"momd"];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        return _managedObjectModel;
    }
    
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
    {
        if (_persistentStoreCoordinator != nil) {
            return _persistentStoreCoordinator;
        }
    
        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"NAMEOFYOURMODELHERE.sqlite"];
    
        NSError *error = nil;
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
    
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    
        return _persistentStoreCoordinator;
    }
    
     #pragma mark - Application's Documents directory
    
    // Returns the URL to the application's Documents directory.
    - (NSURL *)applicationDocumentsDirectory{
        return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    }
    

    第 4 步:将数据对象获取到您需要数据的 ViewControllers

    选项 1. 使用来自 VC 的 App Delegate 的 ManagedObjectContext(首选且更简单)

    正如@brass-kazoo 所建议的那样——通过以下方式检索对 AppDelegate 及其 managedObjectContext 的引用:

    斯威夫特

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
     appDelegate.managedObjectContext
    

    目标 C

     [[[UIApplication sharedApplication] delegate] managedObjectContext];
    

    选项 2. 在您的 VC 中创建 ManagedObjectContext 并使其与 AppDelegate 中的 AppDelegate 匹配(原始)

    只显示 Objective C 的旧版本,因为更容易使用首选方法

    在 ViewController.h 中

    @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
    

    在 ViewController.m 中

    @synthesize managedObjectContext = _managedObjectContext;
    

    在 AppDelegate 或创建 ViewController 的类中,将 managedObjectContext 设置为与 AppDelegate 相同

    ViewController.managedObjectContext = self.managedObjectContext;
    

    如果您希望使用 Core Data 的视图控制器成为 FetchedResultsController,那么您需要确保这些内容在您的 ViewController.h 中

    @interface ViewController : UIViewController <NSFetchedResultsControllerDelegate> {
      NSFetchedResultsController *fetchedResultsController;
      NSManagedObjectContext *managedObjectContext;
    }
    
     @property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
    

    这是在 ViewController.m 中

    @synthesize fetchedResultsController, managedObjectContext;
    

    在所有这些之后,您现在可以使用这个 managedObjectContext 来运行 CoreData 所需的所有常用 fetchRequest!享受

    【讨论】:

    • 这是一个很好的解决方案,只要你没有太多。如果有成百上千个,则需要考虑其他方式来持久化数据,例如:Core Data、Realm 或 Firebase。
    • 是的,你是对的!.. 然后你必须集成 coredata 或领域数据库
    【解决方案2】:

    如果你想存储在 coredata 中(离线使用),那么只需创建一个实体并将元组插入到实体中。

    只需点击以下链接获取核心数据教程: Core data Tutorial AppCoda

    如果您还可以使用 UserDefaults 来存储特定数据。

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      谢谢各位!但我尝试使用 FMDB 创建数据库(因为它已经集成)并且它正确地创建了新的答案表,但是在将上述字典保存为具有动态键值对时遇到问题。

      【讨论】:

        猜你喜欢
        • 2020-11-06
        • 2020-01-11
        • 2014-01-03
        • 2015-12-17
        • 1970-01-01
        • 2020-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多