How to host content externally on Parse? - ios

I want to pack a lot of products into one for Black Friday.
The upload limit # Parse is 10 MB and I need to upload 145 MB. How can I re-route a download to an external hosted content without releasing a new version of my app?
I Hope you can Answer this soon.
It's really important for us to put this Black Friday offer in place.
EDIT:
OK, now I Know I'll Need to Update my App to Download the Content externally. Does Anyone have the Code on how to Download the Content From an External Host Instead of Parse once the Purchase is Approved? THANKS
What I'm Doing now is:
// FOR THE PURCHASE:
[PFPurchase buyProduct:<ProductID> block:^(NSError *error) {
if (!error) {
// run UI logic that informs user the product has been purchased, such as displaying an alert view.
[SVProgressHUD showWithStatus:#"Downloading..."];
}else
{
NSLog(#"ERROR: %#", error);
[SVProgressHUD showErrorWithStatus:#"Error"];
}
}];
// AND EARLIER....
// adding the Purchase Observer
[PFPurchase addObserverForProduct:<ProductID> block:^(SKPaymentTransaction *transaction) {
[PFPurchase downloadAssetForTransaction:transaction completion:^(NSString *filePath, NSError *error) {
if (!error) {
// Unzipping
//...... AND SAVING THE FILES, ETC.....
}
}];
// Thanks Stack-Overflowers

If your App is actually getting the images out of Parse, then you are stuck with the 10 MB limit unfortunately. In order to get around that you would need to store the URL to the image in Parse and host the image somewhere else. Unfortunately you would need to modify your App in the code to handle the URL which will require another release.
It seems like the only thing you can do at this point is to reduce the quality or dimensions of your images to shrink the file size to < 10 MB.

Related

Parse unpinFromBackground doesn't work

I'm currently using Parse to save details about users in an app. When the ViewController is loaded for the first time, the user data is retrieved from the server. When the user leaves the ViewController, I use the code [user pinInBackground] to save user variables to the local datastore. When the ViewController is reloaded later, the user variables are set using the data from the local datastore. This works correctly in my app.
However, when the user leaves to a specific view controller, on returning to the original ViewController, I wish for the app to access the data from the server instead of the local datastore. To do this, I use the code:
[user fetchFromLocalDatastoreInBackgroundWithBlock:^(PFObject *object, NSError *error) {
[user unpinInBackgroundWithName:#"MAINPIN" block:^(BOOL succeeded, NSError *error) {
[user fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
NSLog([NSString stringWithFormat:#"personalHeaderString is equal to %#", user[pfPersonalHeader]]);
}];
}];
}];
The NSLog shows that the code is definitely run as intended. However, the NSLog also shows that the data is not unpinned, and instead the app continues to use data from the local datastore, rather than fetching the data from the Parse server as fetch is supposed to do. How can I fix this?
All help appreciated.
Is there a reason that you are fetching from the local datastore before you unpin? I'm guessing that when you pin the result initially you give it the name "MAINPIN" so why not use:
PFObject.unpinInBackgroundWithName:("MAINPIN")
and then run a your "live" query after after this?
More info here: https://parse.com/docs/ios/api/Classes/PFObject.html#//api/name/unpinInBackgroundWithName:
Andrew

UIImage save to document directory with Low memory usage

In My app I'm saving images to document directory.
My Question is if when device memory is full i.e ex if my device is 16GB and my free space is 2mb then how to handle this while saving image to document directory using WriteToFile API .
[imageData writeToFile:captureImagename atomically:YES];
Any Idea to handle this condition
Thanks in Advance
Use writeToFile:options:error: instead of writeToFile:atomically: so you can get an NSError object in case the operation fails.
Then you can check if the operation returned an error
NSError *error;
if (![plistData writeToFile:file options: NSDataWritingAtomic error:&error]) {
NSLog(#"Error writing file: %#", error);
}
Trying to improve Lefteris' solution is too check if there is space available in the first place.
That way, you can ask the user what he wants to do "Cancel" or "Save (anyway)", and he knows he's saving a 3mb picture in a 2mb storage it's probably gonna fail.
Then he can free space if necessary ; always give the user choice & information, he knows better than you what's happening anyway.
According to this answer : https://stackoverflow.com/a/8036586/3603502
you can get the available disk space. Translate it in megabytes if necessary, compare with picture size, and if the difference is less than, say, 100x, show error message saying "are you sure". Then he can do it or not, and if it fails you can show error like Lefteris suggested. And I'll insist on what he said because he was right :
You should always manipulate files with error statements so you can come back with information if it fails for any reason. (and display to user if necessary).

Overwriting images in iPhoto app

I have a feature in my iOS application. The user has the option to save photo or video to the iPhoto app. When the user presses the 'Save' button, it saves the photo or video again. Is there a way to overwrite the existing file instead of saving it again.
[self writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL* assetURL, NSError* error) {
//error handling
if (error!=nil) {
completionBlock(error);
return;
}
//add the asset to the custom photo album
[self addAssetURL: assetURL
withCompletionBlock:completionBlock];
}];
Any suggestion on this? Using checksum?
Looks like you can't, either you disable your Save button after click once or save to document directory and do checksum algorithm. Please check this answer check image exist

Progressbar on file-upload to Amazon S3 for iOS?

I was using the services from Parse a while back, and they had implemented an amazing feature for uploading data, with a method something like this:
PFFile *objectToSave...; //An image or whatever, wrapped in a Parse-file
[objectToSave saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
//Do stuff after upload is complete
} progressBlock:^(int percentDone) {
[someLabel setText:[NSString stringWithFormat:#"%i%#", percentDone, #"%"]];
}];
Which let me keep track of the file-upload. Since Parse only let me upload max 10mb files, I chose to move to the cloud-area to explore a bit. I've been testing with Amazon's S3-service now, but the only way I can find how to upload data is by calling [s3 putObject:request];. This will occupy the main thread until it's done, unless I run it on another thread. Either way, I have no idea of letting my users know how far the upload has come. Is there seriously no way of doing this? I read that some browser-API-version of S3's service had to use Flash, or set all uploads to go through another server, and keep track on that server, but I won't do either of those. Anyone? Thanks.
My users are supposed to be uploading video with sizes up to 15mb, do I have to let them stare at a spinning wheel for an unknown amount of time? With a bad connection, they might have to wait for 15 minutes, but they would stare at the screen in hope the entire time.
Seems like I didn't quite do my homework before posting this question in the first place. I found this great tutorial doing exactly what I was asking for. I would delete my question, but I'll let it stay just in case it might help other helpless people like myself.
Basically, it had a delegate-method for this. Do something like this:
S3PutObjectRequest *por = /* your request/file */;
S3TransferManager *tm = /* your transfer manager */;
por.delegate = self;
tm.delegate = self;
[tm upload: por];
Then use this appropriately named delegate-method:
-(void)request:(AmazonServiceRequest *)request
didSendData:(long long)bytesWritten
totalBytesWritten:(long long)totalBytesWritten
totalBytesExpectedToWrite:(long long)totalBytesExpectedToWrite
{
CGFloat progress = ((CGFloat)totalBytesWritten/(CGFloat)totalBytesExpectedToWrite);
}
It will be called for every packet it uploads or something. Just be sure to set the delegates.
(Not sure if you need both delegates to be set though)

NSFileCoordinator error when using UIManagedDocument in iOS 5.0 simulator

I am using a UIManagedDocument in iOS 5.0, running the app on the simulator, using XCode 4.2 under OSX 10.6. The code in question looks as follows:
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.photoDatabase.fileURL path]]) {
// does not exist on disk, so create it
[self.photoDatabase saveToURL:self.photoDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
[self fetchFlickrDataIntoDocument:self.photoDatabase];
}];
} else if (self.photoDatabase.documentState == UIDocumentStateClosed) {
// exists on disk, but we need to open it
// *** the following line generates the message ***
[self.photoDatabase openWithCompletionHandler:^(BOOL success) {
//[self setupFetchedResultsController];
}];
} else if (self.photoDatabase.documentState == UIDocumentStateNormal) {
// already open and ready to use
[self setupFetchedResultsController];
}
Running the marked line creates the following message on the log:
2012-01-10 22:33:17.109 Photomania[5149:4803] NSFileCoordinator: A surprising server error was signaled. Details: Connection invalid
After the message is sent, the UIManagedDocument may or may not work—I have not found the circumstances that determine this, yet.
I am pretty sure that the code is correct, as it's actually one of the code examples in the CS193p course from Stanford. The whole example can be downloaded at their website under
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/
Direct link to the code:
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/sample_code/Photomania_0.zip
Additionally, the code runs fine on the device itself, without generating the "surprising" message, and running all the code that comes afterwards just fine.
I have not found anything on Google, neither on the Apple Developer pages. Restarting the simulator, or XCode, or reinstalling both of them does not change the behaviour.
Any ideas?
I can only say that I've had this happen to me several times. For me, I'm lazy after I update my dataModel and so far, each time I've gotten this error it was because I had changed my data model. Usually, all I need to do is delete my app from the simulator and re-run it and it has always turned out fine. Hope this helps someone out there.
I think I have found the answer. It looks like the automatic saving for UIManagedDocument kicks in only after a few seconds on the simulator.
So I minimized the app on the simulator, by pressing the home button, and then clicked on the icon to maximize it again. And then I terminated the app in simulator.
When I re-launched the app, the database was loaded. The error still shows up - it comes because the document is in "closed" state (that's normal - that's why CS193P asked to call openWithCompletionHandler), but my data across launches is preserved. Unfortunately I have to do the minimize/maximize routine before terminating the app, or the changes are discarded at next launch.
Can you verify that this is the behavior you are able to recreate? At least for testing purposes this should be a good enough trick to use.
Try upgrading to the latest iOS 5.1. I don't think UIManagedDocument with iCloud works reliably in 5.0. This has been my experience.
I love the Stanford iTunes class. However, I think the sample code for using UIManagedDocument is wrong. In fact, he notes in the demo that he is only doing it that way because he wants to just fetch the information right then. In the code comments, he says not to use the auto-save features because the data will not be saved if the app quits. however, UIManagedDocument will save anything that's necessary before quitting. It has all pertinent handlers for quitting/multitasking/etc to make sure the data is saved.
So, if you are using that code as your example, here's a version that should work, and does not use saveToURL (I don't have a flickr account, so I didn't actually run it - but this is how the class is designed to work). Please let me know if it does not work.
- (void)fetchFlickrDataIntoDocument:(UIManagedDocument *)document
{
NSManagedObjectContext *ctx = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
ctx.parentContext = document.managedObjectContext;
[ctx performBlock:^{
NSArray *photos = [FlickrFetcher recentGeoreferencedPhotos];
for (NSDictionary *flickrInfo in photos) {
[Photo photoWithFlickrInfo:flickrInfo inManagedObjectContext:ctx];
// Push changes to document MOC
[ctx save:0]; // propagates changes to parent MOC
// and tell the document it is dirty and needs to be saved
// It will be saved when the document decides its time to save
// but it *will* be saved.
[document updateChangeCount:UIDocumentChangeDone]
}
}];
}
Still had errors when the last path component for document file url was #"Database". Adding an extension #"Database.db" seems to have fixed it, everything running fine now. Have also upgraded to Lion though.
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:#"Database.db"];

Resources