离线 Parse.com 时如何在 localdatastore 中保存图像 PFFile?

Posted

技术标签:

【中文标题】离线 Parse.com 时如何在 localdatastore 中保存图像 PFFile?【英文标题】:How do I Save an Image PFFile in localdatastore while Offline Parse.com? 【发布时间】:2015-07-24 16:20:29 【问题描述】:

我正在开发一个使用 Parse.com 服务器来存储每个 PFUser 的 PFUser 信息和类的应用程序。当我在线时,我可以将所有内容保存到服务器,但我也想在没有互联网连接时使用该应用程序,这意味着当我离线时也可以保存它们。

我的应用很简单,我有:

    登录VC

    包含所有汽车的表格视图“每个 PFUSER 的汽车”

    ViewController“添加汽车”+

我在 Parse.com Docs 中搜索,发现离线时 SaveEventually。

- (IBAction)save:(id)sender 


    PFUser*user = [PFUser currentUser];

    PFObject *CarsObject = [PFObject objectWithClassName:@"Cars"];
    CarsObject[@"makeandmodel"] = self.MakeModelTextfield.text;
    CarsObject[@"registrationnumber"] = self.CarImmatriculation.text;
    CarsObject[@"typeofCar"] = TypeACString;
    CarsObject[@"categoryofCar"] = CategoryString;
    CarsObject[@"User"] = user;

    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.mode = MBProgressHUDModeDeterminate;
    hud.animationType = MBProgressHUDAnimationZoom;
    hud.labelText = @"Uploading";
    [hud show:YES];


    NSData *imageData = UIImageJPEGRepresentation(CarsImageView.image, 0.5);
    NSString *filename = [NSString stringWithFormat:@"%@.jpg",self.CarsImmatriculation.text];
    PFFile *imageFile = [PFFile fileWithName:filename data:imageData];
    [CarsObject setObject:imageFile forKey:@"CarImage"];



    [CarObject SaveEventually:^(BOOL success, NSError*error)
        [hud hide:YES];

        if (!error) 
            [self dismissViewControllerAnimated:YES completion:nil];
        else 

            NSLog(@"ERROR SAVE");
        

    ];



使用上面的代码,我收到此错误 [错误]:捕获“NSInternalInconsistencyException”,原因是“无法最终保存一个与新的未保存 PFFile 相关的 PFObject。”所以它不起作用

所以我做了另一种方法,当用户登录时(当您在线时必须登录),我将服务器中的所有值固定到 localdatastore,如下所示:

- (void)FetchFromServerAtLogin

    PFQuery*query = [PFQuery queryWithClassName:@"Cars"];
    [query whereKey:@"User" equalTo:[PFUser currentUser]];
    [query findObjectsInBackgroundWithBlock:^(NSArray*object, NSError*error)

        if (!error) 

            [PFObject pinAllInBackground:object block:nil];

        else

            NSLog(@"ERROR in Fetch From Server At login");
        

    ];


我有一个表格视图,它显示所有汽车并从 Localdatastore 显示它们,因此它可以使用以下代码:

- (void)FetchFromDatabase

    [self ShowAircraftCategory];

    PFQuery*query = [PFQuery queryWithClassName:@"Cars"];
    [query fromLocalDatastore];
    [query whereKey:@"User" equalTo:[PFUser currentUser]];
    [query whereKey:@"categoryofCars" equalTo:self.CategoryACString];
    [query findObjectsInBackgroundWithBlock:^(NSArray*object, NSError*error)

        if (!error) 
            NSArray*temp = [NSArray arrayWithArray:object];
            self.CarsArray = [temp mutableCopy];
            [self.tableView reloadData];

        else

            NSLog(@"ERROR in FetchFromDatabse");
        

    ];


而且它有效所以此时我可以使用此代码获取我从 VC 中创建的所有汽车:

- (IBAction)save:(id)sender 



    PFUser*user = [PFUser currentUser];

    PFObject *CarsObject = [PFObject objectWithClassName:@"Cars"];
    CarsObject[@"makeandmodel"] = self.MakeModelTextfield.text;
    CarsObject[@"registrationnumber"] = self.CarImmatriculation.text;
    CarsObject[@"typeofcar"] = TypeACString;
    AircraftObject[@"categoryofcar"] = CategoryString;
    AircraftObject[@"User"] = user;

    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.mode = MBProgressHUDModeDeterminate;
    hud.animationType = MBProgressHUDAnimationZoom;
    hud.labelText = @"Uploading";
    [hud show:YES];


    NSData *imageData = UIImageJPEGRepresentation(CarImageView.image, 0.5);
    NSString *filename = [NSString stringWithFormat:@"%@.jpg",self.CarImmatriculation.text];
    PFFile *imageFile = [PFFile fileWithName:filename data:imageData];
    [CarsObject setObject:imageFile forKey:@"AircraftImage"];



    [CarsObject pinInBackgroundWithBlock:^(BOOL success, NSError*error)
        [hud hide:YES];

        if (!error) 
            [self dismissViewControllerAnimated:YES completion:nil];
        else 

            NSLog(@"ERROR SAVE");
        

    ];



我发现将 Localdatastore 保存到服务器的最后一部分和唯一方式: 使用按钮“LOGOUT”将localDatastore中的所有PFObjects保存并取消固定到服务器(如果没有互联网,则无法注销)如下:

-(IBAction)Logout:(id)sender


    PFQuery*query = [PFQuery queryWithClassName:@"Cars"];
    [query fromLocalDatastore];
    [query whereKey:@"User" equalTo:[PFUser currentUser]];
    [query findObjectsInBackgroundWithBlock:^(NSArray*arrayOb, NSError*error)

    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.mode = MBProgressHUDModeDeterminateHorizontalBar;
    hud.animationType = MBProgressHUDAnimationFade;
    hud.labelText = @"Uploading";
    [hud show:YES];


        if (error == nil) 
            NSArray*Cars = [NSArray arrayWithArray:arrayOb];
            [PFObject saveAllInBackground:Cars block:^(BOOL succeeded, NSError *error)
                [hud hide:YES];
                if (error == nil) 

                    [PFObject unpinAllObjectsInBackgroundWithBlock:nil];
                    [PFUser logOut];
                    [self performSegueWithIdentifier:@"Logout" sender:self];

                

                else

                    UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"LOGOUT ERROR ???? !" message:@"\n Please Connect to The Internet to SYNC with the Server all What you saved Locally ???? ! " delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                    [alert show];
                

            ];



        else

            UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"LOGOUT ERROR ???? !" message:@"\n Please Connect to The Internet to SYNC with the Server all What you saved Locally ???? ! " delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];
        

    ];





**我的问题是“如果我在离线时退出应用程序而不保存,我会丢失 ImageofCar 的 PFFile 并且我无法检索本地数据存储中的图像,剩下的就是“字符串”即:NameofAircraft 等... **这个问题有解决方案???

谢谢

【问题讨论】:

看这里:parse.com/questions/using-parse-offline(我猜运气不好) @ThomasKilian 谢谢!我找到了获得离线平台的方法!但不幸的是,唯一的问题是当我强制退出应用程序时 -> 我丢失了所有固定的 PFFiles !如果我不强制退出应用程序并正常注销(使用 InternetON)一切都同步了! 【参考方案1】:

当你强制退出一个应用时,这个方法在 AppDelegate 中被调用:

applicationWillTerminate:

您可以在那里注销您的用户。

但是,当应用程序处于非活动状态的时间过长时,它会进入非活动状态。您可以在应用程序委托中使用另一种方法来处理这种情况:

applicationWillResignActive:

请参阅UIApplicationDelegate Protocol,了解更多可以处理此类应用相关事务的地方。

【讨论】:

【参考方案2】:

不幸的是,我认为 PFFile 不会持久保存在本地数据存储中。见:related question

【讨论】:

以上是关于离线 Parse.com 时如何在 localdatastore 中保存图像 PFFile?的主要内容,如果未能解决你的问题,请参考以下文章

android,在离线模式下保存文件(parse.com)

parse.com / iOS - 有没有办法以 json 格式下载整个类对象?

在线/离线数据管理

如何检查我是不是已经订阅了 parse.com 推送通知

如何批量更新用户类(Parse.com、Android)中的所有对象?

如何在 parse.com 仪表板中添加数组?