No visible #interface for 'NSData' declares the selector 'initWithBase64Encoding: - objective-c

I am trying to build in xcode but I keep getting this issue
No visible #interface for 'NSData' declares the selector 'initWithBase64Encoding:'
and
No visible #interface for 'NSData' declares the selector 'base64Encoding'
I have looked everywhere not but there isn't a clear solution to my problem. These are what's giving me problem:
- (NSString*)stringFromImage:(UIImage*)image
{
if(image)
{
UIImage* convertImage = [GameUtility imageWithImage:image scaledToSize:CGSizeMake(80, 80)];
NSData *dataObj = UIImageJPEGRepresentation(convertImage, 30);
return [dataObj base64Encoding];
}
return #"";
}
- (UIImage*)imageFromString:(NSString*)imageString
{
NSData* imageData =[[NSData alloc] initWithBase64Encoding:imageString];
return [UIImage imageWithData:imageData];
}

If you are targeting OS X 10.9 or iOS 7 you can use the base64EncodedStringWithOptions: method to encode the string, and the initWithBase64EncodedString:options: method to decode the string.
If you are targeting platforms earlier than this, you need to either write these methods yourself or find a library that implements them for you (as category methods of NSData). Different libraries will have different names for these methods, so make sure you check with that library's documentation or check the header.

You can convert your image to string like this first. And then you can try convert your UIImage to NSData & then convert that data into string by using encodeBase64WithData
NSString * Image = [self encodeBase64WithData:[imageDict objectForKey:#"Image"]];
and then try your UIImage to string like this
[UIImage imageWithData: [self decodeBase64WithString:[registerDataDict objectForKey:#"Image"]]];
Hope it helps you

use this base64 file for encode and decode
- (NSString*)stringFromImage:(UIImage*)image
{
if(image)
{
UIImage* convertImage = [GameUtility imageWithImage:image scaledToSize:CGSizeMake(80, 80)];
NSData *dataObj = UIImageJPEGRepresentation(convertImage, 30);
return [dataObj base64EncodedString];
}
return #"";
}
- (UIImage *)imageFromString:(NSString*)imageString
{
NSData* imageData =[imageString base64DecodedData];
return [UIImage imageWithData:imageData];
}

Related

How to parse and take only this string value

I wanted to get only array string value app. As example(SLGoogleAuth ,HalfTunes,TheBackgrounder,Calculiator) . But don't know how to do?
It's a code.
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
SEL selector=NSSelectorFromString(#"defaultWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:selector];
SEL selectorALL = NSSelectorFromString(#"allApplications");
NSLog(#"apps: %#", [workspace performSelector:selectorALL]);
}
It's output:
Thanks in advance
You do not want to parse that. NSLog prints out a description of an object. You want to access that value directly.
[LSApplicationWorkspace allApplications];
returns NSArray of LSApplicationProxy. LSApplicationProxy class has a ivar _bundleURL that contains information that you need. You need runtime functions to access it. Working example below:
// #import <objc/runtime.h>
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
SEL selector=NSSelectorFromString(#"defaultWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:selector];
SEL selectorALL = NSSelectorFromString(#"allApplications");
NSArray* appProxies = [workspace performSelector:selectorALL];
Ivar bundleUrlIvar = class_getInstanceVariable([appProxies.firstObject class], "_bundleURL");
NSMutableString* result = [NSMutableString string];
for (id appProxy in appProxies)
{
NSURL* url = object_getIvar(appProxy, bundleUrlIvar);
// at this point you have the information and you can do whatever you want with it
// I will make it a list as you asked
if (url)
{
[result appendFormat:#",%#", [url lastPathComponent]];
}
}
if (result.length > 0)
{
// remove comma from beginning of the list
[result deleteCharactersInRange:NSMakeRange(0, 1)];
}
NSLog(#"apps: %#", result);
Note that this will be rejected by AppStore as you are using private apis. So use at your own discretion.

Problems passing parameters to a dynamic method (object_addMethod)

I'm attempting to use resolveClassMethod: and object_addMethod to add a new method. Things seem to be working fine in general, but the parameter doesn't seem to be coming through.
When I pass in a parameter, such as:
UIFont *font1 = [UIFont academyEngravedLetPlainOfSize:12.0f];
I get 0.0 instead of 12.0 for the font size in my dynamic method. Here's the output from the sample below:
createNamedFontIMP(UIFont, academyEngravedLetPlainOfSize:, 0.000000)
What am I doing wrong here?
#interface UIFont (NTNamedFonts)
+(UIFont *)academyEngravedLetPlainOfSize:(int)size NS_AVAILABLE_IOS(6_0);
#end
#implementation UIFont (NTNamedFonts)
NSString *targetSelectorName = #"academyEngravedLetPlainOfSize:";
NSString *targetFontName = #"AcademyEngravedLetPlain";
+(BOOL)resolveClassMethod:(SEL)sel
{
NSString *selectorName = NSStringFromSelector(sel);
if ( [selectorName isEqualToString:targetSelectorName] )
{
Class metaClass = object_getClass(self);
class_addMethod(metaClass, sel, (IMP)createNamedFontIMP, "##:f");
return YES;
}
else
return [super resolveClassMethod:sel];
}
static id createNamedFontIMP(Class class, SEL _cmd, CGFloat size)
{
NSLog(#"createNamedFontIMP(%#, %#, %f)", NSStringFromClass(class), NSStringFromSelector(_cmd), size);
UIFont *font = [class fontWithName:targetFontName size:size];
return font;
}
#end
You pass an integer to a float. Please show the method declaration.
BTW: What's the reason for your code? A category seems to be the better approach.
BTW 2: If I remember correctly, you have to use double.

CGImageSourceCreateWithURL returns always NULL

I need to read the properties of an image without load or download it. In fact i have implemented a simple method that use the CGImageSourceCreateWithUrl for accomplish this.
My problem is that it is returning always error because seems that the imageSource is null. So what can i do for fix it?
In the NSURL object i pass urls like:
"http://www.example.com/wp-content/uploads/image.jpg" but also ALAssets library Id used to retrieve images inside the phone like "assets-library://asset/asset.JPG?id=E5F41458-962D-47DD-B5EF-E606E2A8AC7A&ext=JPG".
This is my method:
-(NSString *) getPhotoInfo:(NSString *)paths{
NSString *xmlList = #“test”;
NSURL * imageFileURL = [NSURL fileURLWithPath:paths];
NSLog(#"imageFileURL %#", imageFileURL);
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)(imageFileURL), NULL);
if (imageSource == NULL) {
// Error loading image
NSLog(#"Error loading image");
}
CGFloat width = 0.0f, height = 0.0f;
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
NSLog(#"image source %#", imageSource);
return xmlList;
}
I have saw this posts for try to fix it but nothing seems working:
CGImageSourceRef imageSource = CGImageSourceCreateWithURL returns NULL
CGImageSourceCreateWithURL with authentication
accessing UIImage properties without loading in memory the image
In my project ARC is enabled.
Thanks
If you are passing the string "http://www.example.com/wp-content/uploads/image.jpg” to -fileURLWithPath: it’s going to return nil, because that string is sure not a file path, it’s a URL string.
Think of -fileURLWithPath: as just prepending the string you pass in with “file://localhost/“...so you’d end up with a URL that looks like "file://localhost/http://www.example.com/wp-content/uploads/image.jpg”. That’s not good.
You need to call [NSURL URLWithString:paths] if you’re going to be passing in entire URL strings, not just a filesystem path strings.
Working with "assets-library://asset/asset.JPG?id.........., try this code
-(UIImage*)resizeImageToMaxSize:(CGFloat)max anImage:(UIImage*)anImage
{
NSData * imgData = UIImageJPEGRepresentation(anImage, 1);
CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imgData, NULL);
if (!imageSource)
return nil;
CFDictionaryRef options = (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent,
(id)[NSNumber numberWithFloat:max], (id)kCGImageSourceThumbnailMaxPixelSize,
nil];
CGImageRef imgRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options);
UIImage* scaled = [UIImage imageWithCGImage:imgRef];
//these lines might be skipped for ARC enabled
CGImageRelease(imgRef);
CFRelease(imageSource);
return scaled; }

Adding NSImage to IKimagerowserview

I am able to add NSImages to my NSCollectionView without having to first save them on disk. The images are fed into the collection view from an NSMutableArray. This way people can see the images without first having to save them.
Is there something similar that I can achieve with IKImageBrowserView? NSCollectionView is functional when it comes to representing images, but I would like to see if I can do something similar with IKImageBrowserView.
I can easily implement IKImageBrowserView with images saved on disk (Apple docs cover how this works) but can't figure out exactly where to look or how to go about adding images to the browser view directly from NSMutableArray instead of first saving them images to disk.
I'm at a loss here. Apart from the docs, I'm not really sure where else to look for direction. Or what to even call what I'm looking to do.
EDIT: (Here's some of the code)
// The data object -- if it is possible to represent an image object, this is where I am probably going wrong.
#interface ImageObject : NSObject
#property (readwrite, copy) NSImage *image;
#property (readwrite, copy) NSString *imageID;
- (id)initWithImage:(NSImage *)anImage;
- (NSString *)imageUID;
- (NSString *)imageRepresentationType;
- (id)imageRepresentation;
#end
#implementation ImageObject
#synthesize image = _image;
#synthesize imageID = _imageID;
- (id)initWithImage:(NSImage *)anImage
{
if (self = [super init]) {
_image = [anImage copy];
}
return self;
}
- (NSString *)imageUID
{
return _imageID;
}
- (NSString *)imageRepresentationType
{
return IKImageBrowserNSImageRepresentationType;
}
- (id)imageRepresentation
{
return _image;
}
#end
// This is how objects are supposed to be added to the browserView. All of this is straight from Apple.
- (void)updateDatasource
{
[_browserImages addObjectsFromArray:_importedImages];
[_importedImages removeAllObjects];
[imageBrowser reloadData];
}
- (NSUInteger)numberOfItemsInImageBrowser:(IKImageBrowserView *)aBrowser
{
return [_browserImages count];
}
- (id)imageBrowser:(IKImageBrowserView *)aBrowser itemAtIndex:(NSUInteger)index
{
return [_browserImages objectAtIndex:index];
}
This is where I try to add NSImages to the browserView but nothing happens. The array gets populated (which means the images are generated without any errors) but nothing happens on the screen.
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[oPanel URL] options:nil];
NSMutableArray *timesArray = [self generateTimeForSpecifiedNumberOfFramesInVideo:10 UsingAsset:asset];
self.imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
[[self imageGenerator] generateCGImagesAsynchronouslyForTimes:timesArray completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
NSImage *testImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
if (result == AVAssetImageGeneratorSucceeded) {
ImageObject *objects = [[ImageObject alloc] initWithImage:testImage];
[_importedImages addObject:objects];
}
}
As for exploring the rest of the search results...been there done that. If I did miss anything, kindly mark this question as duplicate indicating what post already existed where this issue has been addressed.
EDIT:
I have accepted the answer below. Along with the unique IDs problem. I had overlooked a simple thing which was the requirement to call the updateDatasource method.
The most important point of using IKImageBrowser is create a unique image ID for each element. The following is an example. In fact, it comes from the project that I'm currently working on. I have just implemented IKImageBrowser in it. The code below assumes that you have 36 images (Image01.png, Image02.png..., Image36.png) imported into the project.
// .h
#interface AppDelegate : NSObject {
IBOutlet IKImageBrowserView *browserView;
NSMutableArray *imageArray;
}
// .m
#import "IKBBrowserItem.h"
#import <QuartzCore/QuartzCore.h>
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
imageArray = [[NSMutableArray alloc]init];
}
- (void)populateImage {
for (NSInteger i2 = 1; i2 <= 36 ; i2++) {
NSString *name;
if (i2 < 10) {
name = [NSString stringWithFormat:#"Image0%ld",(long)i2];
} else {
name = [NSString stringWithFormat:#"Image%ld",(long)i2];
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
NSImage *Image0 = [NSImage imageNamed:name];
NSInteger ran = [self genRandom:1000000:9999999];
NSString *imageID = [NSString stringWithFormat:#"%#%li",name,ran];
IKBBrowserItem *item = [[IKBBrowserItem alloc] initWithImage:Image0 imageID:imageID:name];
[imageArray addObject:item];
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
[browserView reloadData];
}
- (NSInteger)genRandom: (NSInteger)min :(NSInteger)max {
int num1;
do {
num1 = arc4random() % max;
} while (num1 < min);
return num1;
}
You don't need to use a random integer generator (genRandom) above, but just make sure that no imageID is the same.
This web site has a sample project, which should get you going. (I have no affiliation.) So make sure you download and run it. Then take a closer look and improve it for your needs.

Large Image Processing (ARC) Major memory leaks

My iPad app that I am creating has to be able to create the tiles for a 4096x2992 image that is generated earlier in my app..
4096x2992 image isn't very complex (what i'm testing with) and when written to file in png format is approximately 600kb...
On the simulator, this code seems to work fine however when I run the app in tighter memory conditions (on my iPad) the process quits because it ran out of memory...
I've been using the same code in the app previously what was working fine (was only creating tiles for 3072x2244 images however)...
Either I must be doing something stupidly wrong or my #autoreleasepool's aren't working as they should (i think i mentioned that im using ARC)... When running in instruments I can just see the memory used climb up until ~500mb where it then crashes!
I've analysed the code and it hasn't found a single memory leak related to this part of my app so I'm really confused on why this is crashing on me...
Just a little history on how my function gets called so you know whats happening... The app uses CoreGraphics to render a UIView (4096x2992) with some UIImageView's inside it then it sends that UIImage reference into my function buildFromImage: (below) where it begins cutting up/resizing the image to create my file...
Here is the buildFromImage: code... the memory issues are built up from within the main loop under NSLog(#"LOG ------------> Begin tile loop ");...
-(void)buildFromImage:(UIImage *)__image {
NSLog(#"LOG ------------> Begin Build ");
//if the __image is over 4096 width of 2992 height then we must resize it! (stop crashes ect)
if (__image.size.width > __image.size.height) {
if (__image.size.width > 4096) {
__image = [self resizeImage:__image toSize:CGSizeMake(4096, (__image.size.height * 4096 / __image.size.width))];
}
} else {
if (__image.size.height > 2992) {
__image = [self resizeImage:__image toSize:CGSizeMake((__image.size.width * 2992 / __image.size.height), 2992)];
}
}
//create preview image (if landscape, no more than 748 high... if portrait, no more than 1004 high) must keep scale
NSString *temp_archive_store = [[NSString alloc] initWithFormat:#"%#/%i-temp_imgdat.zip",NSTemporaryDirectory(),arc4random()];
NSString *temp_tile_store = [[NSString alloc] initWithFormat:#"%#/%i-temp_tilestore/",NSTemporaryDirectory(),arc4random()];
//create the temp dir for the tile store
[[NSFileManager defaultManager] createDirectoryAtPath:temp_tile_store withIntermediateDirectories:YES attributes:nil error:nil];
//create each tile and add it to the compressor once its made
//size of tile
CGSize tile_size = CGSizeMake(256, 256);
//the scales that we will be generating the tiles too
NSMutableArray *scales = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:1000],[NSNumber numberWithInt:500],[NSNumber numberWithInt:250],[NSNumber numberWithInt:125], nil]; //scales to loop round over
NSLog(#"LOG ------------> Begin tile loop ");
#autoreleasepool {
//loop through the scales
for (NSNumber *scale in scales) {
//scale the image
UIImage *imageForScale = [self resizedImage:__image scale:[scale intValue]];
//calculate number of rows...
float rows = ceil(imageForScale.size.height/tile_size.height);
//calulate number of collumns
float cols = ceil(imageForScale.size.width/tile_size.width);
//loop through rows and cols
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
NSLog(#"LOG ------> Creating Tile (%i,%i,%i)",col,row,[scale intValue]);
//build name for tile...
NSString *tile_name = [NSString stringWithFormat:#"%#_%i_%i_%i.png",#"image",[scale intValue],col,row];
#autoreleasepool {
//build tile for this coordinate
UIImage *tile = [self tileForRow:row column:col size:tile_size image:imageForScale];
//convert image to png data
NSData *tile_data = UIImagePNGRepresentation(tile);
[tile_data writeToFile:[NSString stringWithFormat:#"%#%#",temp_tile_store,tile_name] atomically:YES];
}
}
}
}
}
}
Here are my resizing/cropping functions too as these could also be causing the issue..
-(UIImage *)resizeImage:(UIImage *)inImage toSize:(CGSize)scale {
#autoreleasepool {
CGImageRef inImageRef = [inImage CGImage];
CGColorSpaceRef clrRf = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(NULL, ceil(scale.width), ceil(scale.height), CGImageGetBitsPerComponent(inImageRef), CGImageGetBitsPerPixel(inImageRef)*ceil(scale.width), clrRf, kCGImageAlphaPremultipliedFirst );
CGColorSpaceRelease(clrRf);
CGContextDrawImage(ctx, CGRectMake(0, 0, scale.width, scale.height), inImageRef);
CGImageRef img = CGBitmapContextCreateImage(ctx);
UIImage *image = [[UIImage alloc] initWithCGImage:img scale:1 orientation:UIImageOrientationUp];
CGImageRelease(img);
CGContextRelease(ctx);
return image;
}
}
- (UIImage *)tileForRow: (int)row column: (int)col size: (CGSize)tileSize image: (UIImage*)inImage
{
#autoreleasepool {
//get the selected tile
CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height);
CGImageRef inImageRef = [inImage CGImage];
CGImageRef tiledImage = CGImageCreateWithImageInRect(inImageRef, subRect);
UIImage *tileImage = [[UIImage alloc] initWithCGImage:tiledImage scale:1 orientation:UIImageOrientationUp];
CGImageRelease(tiledImage);
return tileImage;
}
}
Now I never use to be that good with memory management, so I did take the time to read up on it and also converted my project to ARC to see if that could address my issues (that was a while ago) but from the results i get after profiling it in instruments I must be doing something STUPIDLY wrong for the memory to leak as bad as it does but I just can't see what i'm doing wrong.
If anybody can point out anything I may be doing wrong it would be great!
Thanks
Liam
(let me know if you need more info)
I use "UIImage+Resize". Inside #autoreleasepool {} it works fine with ARC in a loop.
https://github.com/AliSoftware/UIImage-Resize
-(void)compress:(NSString *)fullPathToFile {
#autoreleasepool {
UIImage *fullImage = [[UIImage alloc] initWithContentsOfFile:fullPathToFile];
UIImage *compressedImage = [fullImage resizedImageByHeight:1024];
NSData *compressedData = UIImageJPEGRepresentation(compressedImage, 75.0);
[compressedData writeToFile:fullPathToFile atomically:NO];
}
}