objective-c google static map returns nil - objective-c

this is my code:
#define GOOGLE_STATIC_MAP_IMAGE #"https://maps.googleapis.com/maps/api/staticmap?center=%#&zoom=15&size=320x150&maptype=roadmap&markers=color:green|label:H|%#"
-(UIImage*)GetGoogleStaticMap
{
NSString* coordinates = [NSString stringWithFormat:#"%f,%f", latitude, longitude];
NSString *stringURL = [NSString stringWithFormat:GOOGLE_STATIC_MAP_IMAGE, coordinates, coordinates]; //coordinates x2 = for the center & the marker
NSURL *url = [NSURL URLWithString:stringURL];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData];
return image;
}
if I paste stringURL to the browser i get the desired result, but imageData returns nil - ideas?

It may have returned nil because of certain characters in the string.
Try calling stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding on your stringURL before creating the url object.
For example:
newStringURL = [stringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

Related

iOS decodeBase64ToImage returning nil on valid base 64 encoded image

I am trying to turn a base 64 canvas string into a UIImage but I always get nil.
Here is strEncodeData as a gist
https://gist.github.com/blasto333/5f15ab56dee0dbf790d90e9064160ea7#file-base64-receipt-image
Code
- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData
{
NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [UIImage imageWithData:data];
}
data is ALWAYS nil
The base64 string is not a normal base64 encoded string. It's a special data: schemed URL. It begins with data:image/png;base64, which is then followed by the encoded data.
You need:
- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
NSURL *url = [NSURL URLWithString: strEncodeData];
NSData *imageData = [NSData dataWithContentsOfURL: url];
UIImage *image = [UIImage imageWithData: imageData];
return image;
}

memory leaks issue while saving images to directory

Please try to understand my question.
i am picking images from phone library and saving into Documents Directory. But When I pick large number of images the utilised memory increases gradually and reach above of 400 mb then my app crash. Please if anybody can solve my problem what should I do? I'm new comer to Objective C. Any response will be appreciated.
here is my code
when Picker finish picking
- (void)agImagePickerController:(AGImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info {
[self ShowLoadingView:#"Files Are Loading...."];
[self performSelectorInBackground:#selector(saveAllSelectedImages:) withObject:info];}
and then I save images to Directory
-(void) saveAllSelectedImages:(NSArray*)imagesArray{
for (int i=0; i<imagesArray.count; i++) {
ALAsset *asset = [imagesArray objectAtIndex:i];
ALAssetRepresentation *alassetRep = [asset defaultRepresentation];
NSDate *currentDate = [NSDate date];
NSString* DucPath = [[AppDelegate GetDocumentDirectoryPath] stringByAppendingPathComponent:#"Media"];
if (![[NSFileManager defaultManager] fileExistsAtPath:DucPath])
[[NSFileManager defaultManager] createDirectoryAtPath:DucPath withIntermediateDirectories:NO attributes:nil error:nil];
if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo])
{
long long DataSize = [alassetRep size];
Byte *buffer = (Byte*)malloc(DataSize);
NSUInteger buffered = (NSUInteger)[alassetRep getBytes:buffer fromOffset:0.0 length:alassetRep.size error:nil];
NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
NSString* newVideoName = [NSString stringWithFormat:#"video_%d_%d.mov",(int)currentDate,i];
NSString* newVideoPath = [DucPath stringByAppendingPathComponent:newVideoName];
[videoData writeToFile:newVideoPath atomically:YES];
[pImageMediaArray addObject:newVideoName];
}
else
{
UIImage *image = [UIImage imageWithCGImage:[alassetRep fullResolutionImage]];
/************************************Full Resolution Images ******************************************/
NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
image = nil;
NSString *originalPath = [NSString stringWithFormat:#"IMAGE_%d_%d.jpg",(int)currentDate,i];
NSString* pImagePath = [DucPath stringByAppendingPathComponent:originalPath];
[imageData writeToFile:pImagePath atomically:YES];
[pImageMediaArray addObject:originalPath];
}
/************************************Low Resolution Images ******************************************/
UIImage *image = [UIImage imageWithCGImage:[alassetRep fullResolutionImage]];
UIImage *thumbImage = [self imageWithImage:image scaledToSize:CGSizeMake(50, 50)];
NSData *thumbImageData = UIImageJPEGRepresentation(thumbImage, 0.8);
NSString *thumbOriginalPath = [NSString stringWithFormat:#"SMALL_IMAGE_%d_%d.jpg",(int)currentDate,i];
NSString* thumbImagePath = [DucPath stringByAppendingPathComponent:thumbOriginalPath];
NSLog(#"Image path At Save Time:%#",thumbImagePath);
[thumbImageData writeToFile:thumbImagePath atomically:YES];
[pMediaArray addObject:thumbOriginalPath];
}
[appDelegate setPMediaArray:pImageMediaArray];
[pGridView reloadData];
imagesArray = nil;
[imagesArray release];
[pImageMediaArray release];
[self performSelectorOnMainThread:#selector(closeLoadindView) withObject:nil waitUntilDone:YES];}
Byte *buffer = (Byte*)malloc(DataSize);
is not being freed?
I had the same exact same issue. What worked for me was to use an autorelease pool block when you save the image. This will free up the retain count and the garbage collection will release the memory appropriately instead of retaining those objects in memory until the containing loop is finished running.
Example: In the method that you are using to save the images add code that looks like this:
#autoreleasepool {
NSString *filePath = [[NSArray arrayWithObjects:self.imagePath, #"/", GUID, #".png", nil] componentsJoinedByString:#""];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
BOOL res = [imageData writeToFile:filePath atomically:YES];
imageData = nil;
}
You need to add the autoreleasepool for task that perform in the background. In the above code content of the saveAllSelectedImages should be written inside autoreleasepool, Otherwise memory won't be released.

UIImage error with dynamic string

I'm trying to load an image into the cell,
The following code is working correctly :
NSString *imageURL = #"http://localhost/images/image2.jpg";
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageURL]];
UIImage *rowImage = [[UIImage alloc] initWithData:imageData];
cell.image=rowImage;
but when i change imageURL to be dynamic , the image isn't displayed :
NSString *imageURL = [[stories objectAtIndex:indexPath.row] objectForKey:#"image"];
You might be saying the problem is in :
[[stories objectAtIndex:indexPath.row] objectForKey:#"image"];
But it's not , i've tried to log it and the output is as expected :
NSSLog(#"%#",[[stories objectAtIndex:indexPath.row] objectForKey:#"image"]);
//Outputs http://localhost/images/image2.jpg
What could be wrong ?
I am guessing there is space before or after the string. So do this,
NSString *imageURL = [[stories objectAtIndex:indexPath.row] objectForKey:#"image"];
imageURL = [imageURL stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageURL]];
UIImage *rowImage = [[UIImage alloc] initWithData:imageData];
While this should mostly fix your issue, I suggest you trim the strings before adding to the dictionary during the XML parsing.
You should also ensure you release both imageData and rowImage. You might be doing it already but its not in the code above so I just wanted to indicate that it could be leaking.
try this one
NSString *imageURL =[NSString stringWithFormat:#"%#",[[stories objectAtIndex:indexPath.row] objectForKey:#"image"]];

How to load image from NSMutableArray

I want to load the image URL from my NSMutableArray.
Here is my Code:
id path = (NSString *)[[stories objectAtIndex: storyIndex] objectForKey: #"icon"];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data cache:NO];
If I use: id path = #"http://www.xzy.de/icon.png"; it´s all right, but not if I want to extract the imageURL from my Array
Anyone who can help me?
Thanks!
I don't get why you declare path as anonymous id type. Define it as NSString. Shouldn't be any problems.
Okay, here's the solution to the problem:
path = [path stringByReplacingOccurrencesOfString:#" " withString:#""];
path = [path stringByReplacingOccurrencesOfString:#"\n" withString:#""];
// that's a tab in the next line's string
path = [path stringByReplacingOccurrencesOfString:#" " withString:#""];

Getting Image from URL Objective C

I'm trying to get an image from an URL and it doesn't seem to be working for me. Can someone point me in the right direction?
Here is my code:
NSURL *url = [NSURL URLWithString:#"http://myurl/mypic.jpg"];
NSString *newIMAGE = [[NSString alloc] initWithContentsOfURL:url
encoding:NSUTF8StringEncoding error:nil];
cell.image = [UIImage imageNamed:newIMAGE];
When I debug the newIMAGE string is nil so something isn't working there.
What you want is to get the image data, then initialize a UIImage using that data:
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: #"http://myurl/mypic.jpg"]];
cell.image = [UIImage imageWithData: imageData];
[imageData release];
As requested, here's an asynchronous version:
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: #"http://myurl/mypic.jpg"]];
if ( data == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
// WARNING: is the cell still using the same data by this point??
cell.image = [UIImage imageWithData: data];
});
[data release];
});
Ok there's a couple of things wrong here:
The conversion from URL (url) to NSString (newImage) is incorrect, what the code actually does there is try to load the contents of "http://myurl/mypic.jpg" into the NSString.
The -imageNamed method takes a string that is a path of a local file, not a URL as an argument.
You need to use an NSData object as an intermediary, like in this example:
http://blogs.oreilly.com/digitalmedia/2008/02/creating-an-uiimage-from-a-url.html
the accepted answer asynchronous version worked very slow in my code. an approach using NSOperation worked light years faster. the code provided by Joe Masilotti --> objective - C : Loading image from URL? (and pasted below):
-(void) someMethod {
// set placeholder image
UIImage* memberPhoto = [UIImage imageNamed:#"place_holder_image.png"];
// retrieve image for cell in using NSOperation
NSURL *url = [NSURL URLWithString:group.photo_link[indexPath.row]];
[self loadImage:url];
}
- (void)loadImage:(NSURL *)imageURL
{
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(requestRemoteImage:)
object:imageURL];
[queue addOperation:operation];
}
- (void)requestRemoteImage:(NSURL *)imageURL
{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[self performSelectorOnMainThread:#selector(placeImageInUI:) withObject:image waitUntilDone:YES];
}
- (void)placeImageInUI:(UIImage *)image
{
[self.memberPhotoImage setImage:image];
}
In Swift 3 and 4
let theURL = URL(string:"https://exampleURL.com")
let imagedData = NSData(contentsOf: theURL!)!
let theImage = UIImage(data: imagedData as Data)
cell.theImageView.image = theImage
This will be done in the main thread.
And to perform the same in asynchronous/background thread
DispatchQueue.main.async(){
let theURL = URL(string:"https://exampleURL.com")
let imagedData = NSData(contentsOf: theURL!)!
let theImage = UIImage(data: imagedData as Data)
}
cell.theImageView.image = theImage
Updating upon Jim dovey answer,[data release] is no longer required because in the updated apple guidelines. Memory management is done automatically by ARC (Automatic counting reference) ,
Here is the updated asynchronous call,
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: #"your_URL"]];
if ( data == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
self.your_UIimage.image = [UIImage imageWithData: data];
});
});