How do I save a PFFile image to localdatastore while Offline Parse.com?

I am developing an application using Parse.com Server to store information and PFUsers classes for each PFUser. I can save everything on the server when I'm online, but I would like to use the app also when there is no internet connection, which means saving them also when I'm offline.

My application is simple, I have:

  • LoginVC

  • Tableview with all cars "Cars for every PFUSER"

  • ViewController "Add car" +

I Search the Parse.com Docs and I found SaveEventually when we are offline.

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

    }];


}

      

With the code above I am getting this error [Error]: Caught "NSInternalInconsistencyException" with reason "Unable to save Eventually PFObject with relation to new unsaved PFFile". SO IT DOESN'T WORK

So I took a different approach. When the user enters a login (required to log in when you're online), I write all the values ​​from the server to localdatastore like this:

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

    }];

}

      

And I have a Tableview that shows all Cars and Shows them from Localdatastore, so it works with this code:

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

    }];

}

      

And it works So at this point I can get all the cars I build from VC with this code:

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

    }];


}

      

The last part and unique way I found Localdatastore for the server: with the "LOGOUT" button, save and discard all PFObjects in the local store on the server (you cannot log out if you have no internet) like this:

-(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];
        }

    }];




}

      

** MY PROBLEM IS "IF I EXIT THE APPLICATION WHEN I AM OFFLINE. Without saving, I lose the PFFile ImageofCar and I cannot retrieve the image in localdatastore, all that remains is" Strings "ie: NameofAircraft ect ... ** Is there a solution to this problem ???

thank

+2


source to share


2 answers


When you force terminate the application, this method is called in the AppDelegate:

applicationWillTerminate:

You can log out of your user.



However, if an application is inactive for too long, it goes into an inactive state. You can simply handle this case with another method in your application delegate:

applicationWillResignActive:

See UIApplicationDelegate Protocol for more places where you can handle this kind of application related stuff.

+1


source


Unfortunately, I believe that PFFiles are not stored in local data storage. See: related question



+1


source







All Articles