I'm able to upload an image (in form of PFFile) on parse with their methods available.
NSData *data = ... ;
PFFile *file = [PFFile fileWithData:data];
[file saveInBackground];
Is there a better way to directly upload an image from a url to parse?
Update: The bad way I found is,
To get an image from NSURL to NSData - don't know about the proper way, but this is working. Something like this,
PFFile *file = [PFFile fileWithData:[NSData dataWithContentsOfURL:urlObj]];
[file saveInBackground];
I think the question is how best to get the data to pass to parse. You're right that dataWithContentsOfUrl is a bad way because it blocks the main thread during the fetch.
Here's a block-based approach to get the data asynchronously:
NSURL *url = [NSURL URLWithString:#"http:// ..."];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
PFFile *file = [PFFile fileWithData:data];
[file saveInBackground];
}
}];
Related
I have a method that returns a string usually locally, but with a backup from the Web. I was retrieving some JSON using dataWithContentsOfUrl but want to switch to using a Session object which is better for the UI and also--if I am not mistaken--allows the server to set a sessionId on the phone, however, I'm struggling with the async issue.
With the old code, I just returned the JSON but I'm struggling with how to do this for the asynchronous result. I can't change the calling method which returns a string. What can I do with the asynchronous Api call to use the data that is retrieved?
async:
-(void)getAsyncAnswerFor:(NSString*) str {
NSString *surl = [NSString stringWithFormat: #"https://~.com//api.php?q=%#",str];
NSURL *url = [NSURL URLWithString:surl];
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//HOW DO I PASS THIS BACK TO THE CALLING METHOD OR IS THAT IMPOSSIBLE
}];
[downloadTask resume];
}
sync
-(NSString*)getAnswerFor:(NSString*) str {
NSError *error;
NSString *surl = [NSString stringWithFormat: #"https://~.com//api.php?q=%#",str];
NSData *data = [NSData dataWithContentsOfURL: [NSURL URLWithString:surl]];
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
//process JSON
if (error) {
return #"";
}
return #"processed JSON";
}
Would appreciate any suggestions.
If what I want to do is totally impossible, is it possible to set a sessionID on the phone without the Session object? I know setting a session ID is is not the greatest approach, but I'm trying to avoid a lot of authentication overhead.
You can pass a block to your asynchronous function and then call it when the url session completion handler is called. This is a trivial example:
- (void)doSomethingWithBlock:(void (^)(double, double))block {
...
block(21.0, 2.0);
}
I lifted this ^^ from the Apple Docs but you might be able to do something like this: (Note: I didn't check this in a compiler!)
-(void)getAsyncAnswerFor:(NSString*) str completion:(void (^)(NSData, NSURLResponse, NSError))block {
NSString *surl = [NSString stringWithFormat: #"https://~.com//api.php?q=%#",str];
NSURL *url = [NSURL URLWithString:surl];
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
block(data, response, error);
}];
[downloadTask resume];
}
You'll need to be careful if you try to reference self anywhere in the blocks.
I have seen this question somewhat answered here but in my case I am using NSURLSession to display images. These images are uploaded by user or scanned into a database using a script.
In this case writing exception URL's (NSExceptionDomains) won't work because the image is hosted by a user on their site or some other site. If I allow NSAllowsArbitraryLoads will I still be able to be approve for App Store since I am not implementing the best practices of ATS?
I am not sure the best way to proceed. Any input would be appreciated!
Here is the code I am using.
NSString *thumbnail_url = [tempObject objectForKey:#"image"];
NSURL *url = [NSURL URLWithString:thumbnail_url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *downloadPhotoTask = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSData *imageData = [[NSData alloc] initWithContentsOfURL:location];
dispatch_async(dispatch_get_main_queue(), ^{
cell.tableImageView.image = [UIImage imageWithData:imageData];
});
}];
[downloadPhotoTask resume];
Yes, you'll pass Review even with this parameter.
We have uploaded many builds since iOS9 SDK with NSAllowsArbitraryLoads set to YES.
P.S.: Your code should better look like this:
cell.thumbnailURL = URL;
__weak typeof(cell) weak
NSURLSessionDownloadTask *downloadPhotoTask = [session downloadTaskWithURL:URL completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSData *imageData = [[NSData alloc] initWithContentsOfURL:location];
UIImage *image = [UIImage imageWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
if (weakCell.thumbnailURL != URL) {
return;
}
weakCell.tableImageView.image = image;
});
}];
[downloadPhotoTask resume];
can i show an instagram photo on my UIImageView?
I was looking for media id and other options, but i can't find the format and the way to show this image for example:
https://www.instagram.com/p/9W-K0wtq3v/
You can get direct link to image using http://api.instagram.com/oembed?url= . After that, downloading the image from that URL & displaying it in UIImageView is fairly simple. I have edited my answer to this one as it works without integrating Instagram API or parsing the web page for URL to file.
Add the following to methods to your View Controller. I have added explanation in comments.
- (void)getDirectURLToLink:(NSString *)urlStr completionBlock:(void (^)(BOOL succeeded, NSString *imageLink))completionBlock
{
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
//Convert data to dictionary as it is JSON. You can view json response for your url at http://paste.ubuntu.com/14437288/
NSError *error1;
NSMutableDictionary * innerJson = [NSJSONSerialization
JSONObjectWithData:data options:kNilOptions error:&error1
];
//Send the direct url to block
completionBlock(YES,[innerJson objectForKey:#"thumbnail_url"]);
} else{
//request failed
completionBlock(NO,nil);
}
}];
}
- (void)downloadImageWithURL:(NSString *)urlStr completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
//cnvert data to uiimage
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(YES,image);
} else{
//download failed
completionBlock(NO,nil);
}
}];
}
(But since sendAsynchronusRequest is deprecated in iOS 9.0, you should use [NSURLSession dataTaskWithURL])
Now you have set up the web request part of the file. To utilize these services, Add following method to your Viewcontroller:
-(void) getImageForPostURL: (NSString *)postURL
{
NSString *baseURL = #"http://api.instagram.com/oembed?url=";
NSString *directLinkRequestURL = [NSString stringWithFormat:#"%#%#",baseURL,postURL];
//Request Direct URL to file from your post url
[self getDirectURLToLink:directLinkRequestURL completionBlock:^(BOOL succeeded, NSString *imgDirectURL) {
if (succeeded) {
//Direct link retrieved
//Get image
[self downloadImageWithURL:imgDirectURL completionBlock:^(BOOL succeeded, UIImage *image) {
if (succeeded) {
// change the image where you want, it has been downloaded
_imgView.image = image;
}
}];
}
else
{
//Error
//Link could not be retrieved
}
}];
}
All this work is not for vain. Now, You are all set to go. All you need is a URL to instagram post and you will be able to download your image just by calling this one line:
[self getImageForPostURL:#"https://www.instagram.com/p/9W-K0wtq3v/"]; //Give your post url as parameter here
I think: it will have two ways to achieve your goal
*First: parse link web Instagram. If you view source your link give: you will find direct link to image:
https://igcdn-photos-b-a.akamaihd.net/hphotos-ak-xfp1/t51.2885-15/e35/10729433_781480525295113_239273684_n.jpg
So you can parse web and find:
<meta property="og:image" content="
for direct link.
Second: You can reference here:
https://instagram.com/developer/endpoints/media/
You enroll developer instagram and learn how to use Instagram API end points.
Hi in my application I have image which change every day as per the date now i want to give download option for the user like they have to download by clicking button and they can see in there device. I'm searching for long time to achieve this task but not able get the proper solution please tell me how to achieve this one.
My ImageView code.
- (void)viewDidLoad
{
[super viewDidLoad];
//this is url which gives the date has a echo
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"url"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
// here I'm connecting the date to my url do display the image
NSString *imgstr=[NSString stringWithFormat:#"url",resSrt];
//assign your image view name
imageview.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",imgstr] ]]];
}
I have used the above to do display the image now to want to user download the image by clicking the download button to localstorage of the device please tell me how to achieve this.
Thanks.
First download the image synchronously and save it in documents folder, then show it over image view.
NSURL *url = [NSURL URLWithString: #"url"];
NSString *imagePath = [DOCUMENTS_PATH stringByAppendingPathComponent:#"some name"];
NSError *error = nil;
NSData *imageData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error: &error];
if (!error) {
[imageData writeToFile:imagePath atomically:YES];
}
Then give this image to the image view
imageview.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/some name", DOCUMENTS_PATH]];
After login to the salesforce in my app I am making service call which returns the list of products with attributes like productName and product image url.
I am trying to download the image from product image url in this way
SFOAuthCredentials *credentials =[SFAccountManager sharedInstance].credentials;
NSString *urlString = [NSString stringWithFormat:#"%#?oauth_token=%#",imageUrl,credentials.accessToken];
NSURL *imgUrl = [[NSURL alloc] initWithString:[URLString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSURLRequest *imgRequest=[[NSURLRequest alloc]initWithURL:imgUrl];
[NSURLConnection sendAsynchronousRequest:imgRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
UIImage *image=[[UIImage alloc] initWithData:data];
NSLog(#"Image Object %#",image);
}];
I am getting the data object of size around 1820 bytes, but while converting NSData to UIImage by using UIImage classsMethod [UIImage iamgeWithData:data] or instance method [UIImage alloc] initWithData:data] I am getting null
Can anyone help me to fix this issue?.