【问题标题】:store result from wcf service in core data将 wcf 服务的结果存储在核心数据中
【发布时间】:2012-08-27 02:47:41
【问题描述】:

我在我的应用程序中使用 WCF 服务。当应用程序第一次在 iPad 上运行时,我希望它调用 WCF 服务并在 UITableView 中显示结果。同时在 UITableView 中显示数据,我想要将数据存储在 Core Data 中,因此当用户“离线”(未连接到 wifi)时,数据将从 Core Data 显示。AppDelegate.m 如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
    if (![defaults objectForKey:@"firstRun"])
    {
        self.firstRun = TRUE;
        [defaults setObject:[NSDate date] forKey:@"firstRun"];
    }
    else
    {
       self.firstRun = FALSE;//flag does exist so this ISNT the first run
    }
   [[NSUserDefaults standardUserDefaults] synchronize];
}

UITableView 中的代码如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [my_table setDataSource:self];
    [my_table setDelegate:self];

    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate.firstRun){
        NSLog(@"IS FIRST RUN");
        EDViPadDocSyncService *service = [[EDViPadDocSyncService alloc]init];
        [service getAllCategories:self action:@selector(handleGetAllCategories:)];
    }
    else 
    {
        NSLog(@"NOT FIRST RUN");
        NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription
                                       entityForName:@"Categories" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];
        NSError *errormsg;
        self.allCats = [managedObjectContext executeFetchRequest:fetchRequest error:&errormsg];
        NSLog(@"allCATS=%@",self.allCats);
        self.title = @"Categories";
    }
}

-(void)handleGetAllCategories:(id)value
{
    if([value isKindOfClass:[NSError class]])
    {
        NSLog(@"This is an error %@",value);
        return;
    }

    if([value isKindOfClass:[SoapFault class]])
    {
        NSLog(@"this is a soap fault %@",value);
        return;
    }
    NSMutableArray *result = (NSMutableArray*)value;

    NSMutableArray *categoryList = [[NSMutableArray alloc] init];
    NSMutableArray *docCount = [[NSMutableArray alloc]init];
    NSMutableArray *catIdList = [[NSMutableArray alloc]init];

    self.myData = [[NSMutableArray array] init];
    self.myDocCount = [[NSMutableArray array]init];
    self.catId = [[NSMutableArray array]init];

    for (int i = 0; i < [result count]; i++)
    {
        EDVCategory *catObj = [[EDVCategory alloc]init];
        catObj = [result objectAtIndex:i];
        [categoryList addObject:[catObj categoryName]];
        [docCount addObject:[NSNumber numberWithInt:[catObj docCount]]];
        [catIdList addObject:[NSNumber numberWithInt:[catObj categoryId]]];
    }

    self.myData = categoryList;
    self.myDocCount = docCount;
    self.catId = catIdList;
    [my_table reloadData];

    /*store data in Core Data - START*/
    NSManagedObjectContext *context = [self managedObjectContext];
    NSManagedObject *newCategory;
    for(int j=0;j<[result count];j++)
    {
        newCategory = [NSEntityDescription insertNewObjectForEntityForName:@"Categories" inManagedObjectContext:context];
        /*HOW TO STORE DATA FOR THE "CATEGORIES" OBJECT IN CORE DATA*/
    }
    /*store data in Core Data - END*/
}

我无法弄清楚如何将从 wcf 服务接收到的数据直接存储到核心数据对象。我知道如何将它从屏幕上的文本框存储到核心数据对象。例如:-

coreDataAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *newContact;
newCat = [NSEntityDescription insertNewObjectForEntityForName:@"Categories" inManagedObjectContext:context];
[newCat setValue:name.text forKey:@"name"];
name.text = @"";
[context save:&error];

但这对我的情况没有帮助。感谢任何帮助。

【问题讨论】:

    标签: objective-c wcf core-data uitableview


    【解决方案1】:

    您正在混合网络和 UI 代码。这是无法维护代码的秘诀。

    您的 UI 应该查看 Core Data,并且查看 Core Data 来显示其数据。

    您应该分别异步地从 WCF 请求数据并将其推送到 Core Data。

    您的 UI 不需要关心首次运行与后续运行。它只是通过NSFetchedResultsController 查看 Core Data。

    您的网络代码是唯一关心新与更新的部分。

    更新 1

    我怎样才能做到这一点?当应用程序运行并连接到 WiFi 时,它必须从 WCF 服务获取最新数据。

    NSURLConnection 可以内置异步请求。我通常建议将您的网络代码编写为NSOperation 子类,然后将它们放入队列中。

    WCF 似乎可以返回 XML 并接受标准 HTTP 请求。因此,您可以编写 NSOperation 子类来构建您的请求,将其发送到服务器并等待回复。当回复到来时,您解析 XML 并将其插入到 Core Data 中。当您保存 Core Data NSManagedObjectContext 时,您的 NSFetchedResultsController 实例将自动触发并允许您更新 UI。

    我有几个代码示例可以执行这些功能,尽管它们是针对 JSON 响应而不是 XML 响应编写的。采用这些示例并根据您的需要进行更改并不难。

    您可以从this stackoverflow question 及其响应开始。

    【讨论】:

    • “您应该分别异步地从 WCF 请求数据并将其推送到核心数据中。” - 我该如何实现呢?当应用程序运行并连接到 WiFi 时,它必须从 WCF 服务获取最新数据。
    • 完美!这正是我想要的!
    【解决方案2】:

    要将数据存储到NSManagedObject 的属性中,只需使用 KVC 设置值:

    EDVCategory *catObject = [result objectAtIndex:j];
    [newCategory setValue:[catObject categoryName] forKey@"categoryName"];
    [newCategory setValue:[catObject docCount] forKey@"docCount"];    
    [newCategory setValue:[catObject categoryID] forKey@"categoryID"];
    
    // after the loop
    [context save:&nil];
    

    【讨论】:

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