问题
I'm developing an App that use Parse.com Server to Store PFUsers Informations and Classes for each PFUser. I'm able to save everything to the server when i'm online but i would like use the app also when there's no Internet connect which means to save them also when i'm Offline.
My App is simple, I have:
LoginVC
Tableview with all Cars "Cars for Each PFUSER"
ViewController "Add a Car" +
I Search in Parse.com Docs & 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 Get this Error [Error]: Caught "NSInternalInconsistencyException" with reason "Unable to saveEventually a PFObject with a relation to a new, unsaved PFFile." SO IT DOESN'T WORK
So i did another approach, When a user login (it's mandatory to login when you're Online), i pin all the values from the server to localdatastore as follow:
- (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 the Cars and Show 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'm able to Get all Cars that i Create from the 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 the Unique way i found to save the Localdatastore to the Server: is with the Button "LOGOUT" saving and Unpinning all PFObjects in the localDatastore to the server (You can't logout if you don't have internet) as follow:
-(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 QUIT THE APPLICATION when i'm offline Without saving, i lose the PFFile of ImageofCar and i'm not able to to retrive the Image in localdatastore, all that remains is the "Strings" i.e: NameofAircraft ect... ** There is a solution for this problem ???
Thanks
回答1:
When you force quit an app, this method is called in the AppDelegate:
applicationWillTerminate:
You can logout your user there.
However, when an app has been inactive for too long, it goes to the inactive state. You can just handle that case with another method in the app delegate:
applicationWillResignActive:
See UIApplicationDelegate Protocol for more places where you can handle these kind of app related things.
回答2:
Unfortunately, I believe that PFFiles are not persisted in the local datastore. See : related question
来源:https://stackoverflow.com/questions/30213808/how-do-i-save-an-image-pffile-in-localdatastore-while-offline-parse-com