I'd like to randomly display profile pictures in a UITableViewCell.
My table is set up as a way to filter. I have one table setup on Parse for users which also contains a category column and picture column. I want to query by the category (each cell row is a category as exampled below), and randomly display image(s) in the UITableViewCell.
So the table would be set up such as:
Category A
Category B
Category C
Each cell will have UIImageViews in them, and I'd like to randomly display images in each cell.
Here's what I have tried, but no luck.
// in ViewDidLoad
self.theArray = [[NSArray alloc] initWithObjects:#"A", #"B", #"C", #"D", nil];
// in cellForRowAtIndexPath
cell.label.text = [self.theArray objectAtIndex:indexPath.row];
PFQuery * query = [PFUser query];
[query whereKey:#"category" equalTo:cell.label.text];
[query findObjectsInBackgroundWithBlock:(NSArray *objects, NSError error) {
if (error)
{
NSLog(#"Error: %# %#", error, [error userInfo]);
}
else
{
for (int i = 0; i < objects.count; i++)
{
self.profilePicObject = [objects objectAtIndex:i];
int imgRandom = random() % [objects count];
self.randomProfilePicObject = [objects objectAtIndex:imgRandom];
self.imageFile = [self.randomProfilePicObject objectForKey:#"imageFile"];
NSURL * imageFileURL = [[NSURL alloc] initWithString:self.imageFile.url];
NSData * imageData = [NSData dataWithContentsOfURL:imageFileURL];
UIImage * aImage = [[UIImage alloc] initWithData:imageData];
cell.profilePicOne.image = aImage;
}
}
}];
EDIT:
I have modified the code above, and it is working now. What would be the most efficient way to modify this to fill in more than one UIImageView in a cell?
try this:
for (int i = 0; i < objects.count; i++)
{
//self.profilePicObject = [objects objectAtIndex:i];
int randomImgNumber = arc4random_uniform(5); // You could several many times the same picture !!!
self.profilePicObject = [objects objectAtIndex:randomImgNumber];
self.imageFile = [self.profilePicObject objectForKey:#"imageFile"];
NSURL * imageFileURL = [[NSURL alloc] initWithString:self.imageFile.url];
NSData * imageData = [NSData dataWithContentsOfURL:imageFileURL];
UIImage * aImage = [[UIImage alloc] initWithData:imageData];
// aImage = [objects objectAtIndex:randomImgNumber];
cell.profilePicOne.image = aImage;
}
Related
I want to add dynamic values of UIImage in array which initialised in the for loop, So I created a NSMutableArray to set object first in for loop and later tried to retrieve values from that.
Please can you look where I am going wrong and what should be best approch while adding the dynamic values.
NSMutableDictionary * dic= [[NSMutableDictionary alloc]init];
NSMutableArray *cImages = [[NSMutableArray alloc]init];
for(int i=0; i<5; i++) {
NSString * imageKey= [NSString stringWithFormat:#"image%i",i+1];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: [[results objectAtIndex:i]valueForKey:imageKey]]];
UIImage *imageOne = [UIImage imageWithData:imageData];
[dic setObject:imageOne forKey:imageKey];
}
for (NSString *key in dic) {
NSString *sprite = [dic objectForKey:key];
//adding below to the array
[cImages addObject:sprite];
}
What's wrong with just adding UIImage's to the mutable array?
NSMutableArray *cImages = [[NSMutableArray alloc]init];
for(int i = 0; i < 5; i++)
{
NSString *imageKey= [NSString stringWithFormat:#"image%i", i+1];
UIImage *imageToAdd = [UIImage imageNamed:imageKey];
[cImages addObject:imageToAdd];
}
// Using the images
for (UIImage *image in cImages)
{
// Do whatever u want with each image.
}
If you really need to use a dictionary to access the UIImage's by the names "image1, image2" etc you can do this:
NSDictionary *dict = [[NSDictionary alloc] init];
for (int i = 0; i < 5; i++)
{
NSString *imageKey = [NSString stringWithFormat:#"image%i", i+1];
UIImage *image = [UIImage imageNamed:#"nameOfImageFile.png"];
[dict setObject:image forKey:imageKey];
}
// Now you can access the UIImage values by their names (image1,image2,image3,image4,image5)
UIImage *imageToUse = [dict valueForKey:#"image1"];
(haven't test these, but it's fairly standard).
I have the following code and it is working to an extent :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/service.php"];
NSURL *url = [NSURL URLWithString:strURL];
NSData * data = [NSData dataWithContentsOfURL:url];
NSError * error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
AdObject *someAdObject = [[AdObject alloc] init];
//NSLog(#"%#", json);
self.detailLabel.text = self.tempString;
}
Now when the commented out NSLog actually prints the JSON dictionary, I get :
{
brand = "";
category = Games;
country = "Japan";
"discount_rate" = 50;
duration = 5;
id = 1;
"issue_date" = "2014-04-07";
location = "Heishi Mall";
title = "Gamestory videogames sales!";
user = "";
}
)
I created an Ad object which has properties such as title, location, country, etc (as reflected above). I would like to access the JSON above and store value in object variables.
You can access that values :-
for(NSDictionary *item in json) {
NSLog(#"%#",[item valueForKey:#"key"]);
someAdObject.key = [item valueForKey:#"key"];
}
Try this and review your json also
AdObject *someAdObject = nil;
for(NSDictionary *item in json) {
someAdObject = [[AdObject alloc] init];
someAdObject.category = [item valueForKey#"category"];
someAdObject.country = [item valueForKey#"country"];
someAdObject.discount_rate = [item valueForKey#"discount_rate"];
someAdObject.duration = [item valueForKey#"duration"];
//and same all of your required object properties
}
I load data from json and then add it to nsmutablearray like this:
- (void)loadData
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// Create array to hold dictionaries
myObject = [[NSMutableArray alloc] init];
NSData *jsonData = [NSData dataWithContentsOfURL:
[NSURL URLWithString:#"http://www.domain.com/json.php"]];
if(jsonData != nil)
{
NSError *error = nil;
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if (error == nil){
dispatch_sync(dispatch_get_main_queue(), ^{
// values in foreach loop
for (NSMutableArray *tempArray in jsonObjects) {
[myObject addObject:tempArray];
NSSortDescriptor * sortDesc = [[NSSortDescriptor alloc] initWithKey:#"id.doubleValue" ascending:NO];
[myObject sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
[self performSelectorOnMainThread:#selector(endAnimating) withObject:nil waitUntilDone:YES];
}
});
}
}
});
}
if I check with NSLog "tempArray" it's looks ok, but if I check "myObject", data added to it multiple times. How to add data just one time in to my "myObject" array?
EDIT:
My JSON result:
[{"id":"7","title":"monkey","thumb":"http:\/\/icon.s.photosight.ru\/img\/8\/e09\/5045427_thumb.jpg","url":"http:\/\/icon.s.photosight.ru\/img\/8\/e09\/5045427_large.jpg","day":"perjantai","date":"0","likes":"2","device_id":"1111","active":"1"},
{"id":"11","title":"Bukashka","thumb":"http:\/\/icon.s.photosight.ru\/img\/f\/b3b\/5078973_thumb.jpg","url":"http:\/\/icon.s.photosight.ru\/img\/f\/b3b\/5078973_large.jpg","day":"perjantai","date":"0","likes":"1","device_id":"1111","active":"1"},
{"id":"12","title":"blya","thumb":"http:\/\/icon.s.photosight.ru\/img\/f\/c1d\/5076251_thumb.jpg","url":"http:\/\/icon.s.photosight.ru\/img\/f\/c1d\/5076251_large.jpg","day":"perjantai","date":"0","likes":"1","device_id":"1111","active":"1"}]
My NSLog(#"%#", myObject);
2013-06-12 18:45:52.228 testApp[960:60b] (
{
active = 1;
date = 0;
day = perjantai;
"device_id" = 1111;
id = 7;
likes = 2;
thumb = "http://icon.s.photosight.ru/img/8/e09/5045427_thumb.jpg";
title = monkey;
url = "http://icon.s.photosight.ru/img/8/e09/5045427_large.jpg";
}
)
2013-06-12 18:45:52.230 testApp[960:60b] (
{
active = 1;
date = 0;
day = perjantai;
"device_id" = 1111;
id = 11;
likes = 1;
thumb = "http://icon.s.photosight.ru/img/f/b3b/5078973_thumb.jpg";
title = Bukashka;
url = "http://icon.s.photosight.ru/img/f/b3b/5078973_large.jpg";
},
{
active = 1;
date = 0;
day = perjantai;
"device_id" = 1111;
id = 7;
likes = 2;
thumb = "http://icon.s.photosight.ru/img/8/e09/5045427_thumb.jpg";
title = monkey;
url = "http://icon.s.photosight.ru/img/8/e09/5045427_large.jpg";
}
)
2013-06-12 18:45:52.237 testApp[960:60b] (
{
active = 1;
date = 0;
day = perjantai;
"device_id" = 1111;
id = 12;
likes = 1;
thumb = "http://icon.s.photosight.ru/img/f/c1d/5076251_thumb.jpg";
title = blya;
url = "http://icon.s.photosight.ru/img/f/c1d/5076251_large.jpg";
},
{
active = 1;
date = 0;
day = perjantai;
"device_id" = 1111;
id = 11;
likes = 1;
thumb = "http://icon.s.photosight.ru/img/f/b3b/5078973_thumb.jpg";
title = Bukashka;
url = "http://icon.s.photosight.ru/img/f/b3b/5078973_large.jpg";
},
{
active = 1;
date = 0;
day = perjantai;
"device_id" = 1111;
id = 7;
likes = 2;
thumb = "http://icon.s.photosight.ru/img/8/e09/5045427_thumb.jpg";
title = monkey;
url = "http://icon.s.photosight.ru/img/8/e09/5045427_large.jpg";
}
)
WORKING SOLUTION BY: danypata
in viewDidLoad put myObject = [[NSMutableArray alloc] init];
then
- (void)loadData
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSData *jsonData = [NSData dataWithContentsOfURL:
[NSURL URLWithString:#"http://www.domain.com/json.php"]];
if(jsonData != nil)
{
NSError *error = nil;
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if (error == nil){
[myObject removeAllObjects];
for (NSMutableDictionary *tempDict in jsonObjects) {
[myObject addObject:tempDict];
}
NSSortDescriptor * sortDesc = [[NSSortDescriptor alloc] initWithKey:#"id.doubleValue" ascending:NO];
[myObject sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
dispatch_sync(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[self.tableView.pullToRefreshView stopAnimating];
});
}
}
});
}
One possible cause of your problem is that the tempArray arrays contains same objects, but to reply to your question `how to add just one time in to my "myObject" array" there are two easy solutions
One, use containsObject: method like this:
if([myObject containsObject:tempArray] == NO) {
[myObject addObject:tempArray]
}
Second, which I think is more elegant use NSMutableSet (`NSMutableSet adds objects only if the object is not already added). You can use it like this:
NSMutableSet *set = [[NSMutableSet alloc] init];
[set addObject:tempArray];
//after you added all objects just do the following after you init your myObject
[myObject addObjectsFromArray:[set allObjects]]
EDIT
Your problem is caused by the for loop. You are nto extracting properly the data, in your JSON you have an array of dictionaries not an array of arrays so you should change the for loop like this:
for (NSDictionary *tempDict in jsonObjects) {
[myObject addObject:tempDict];
//other operations here
}
I've almost finished my app and everything seems to work but the main view.
It's an UIViewController with an embedded UITableView.
I'm using Parse as the backend, and I get an array of the objects I need in my viewDidLoad method.
Each cell contains some data that I'm fetching in the tableView:cellForRowAtIndexPath and I'm afraid that this is the reason why my table view is so laggy, but I don't know how to fetch the data I need for each object in my array without having the indexPath.row number.
I've already made each cell element "opaque" as suggested in other answers.
This is my code, any help would be greatly appreciated:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellHT";
CellHT *cell = (CellHT *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CellHT alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// self.hH is an NSArray containing all the objects
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
cell.lblTitle.text = [self.hH[indexPath.row] objectForKey:#"title"];
cell.lblVenueName.text = [self.hH[indexPath.row] objectForKey:#"venueName"];
cell.lblDistance.text = NSLocalizedString(#"Distance from you", nil);
self.geo = [self.hH[indexPath.row] objectForKey:#"coordinates"];
// the formatters are initialized in the viewDidLoad: method
self.formatData = [NSDateFormatter dateFormatFromTemplate:#"dd/MM" options:0 locale:[NSLocale currentLocale]];
[self.formatterData setDateFormat:self.formatData];
self.formatOra = [NSDateFormatter dateFormatFromTemplate:#"j:mm" options:0 locale:[NSLocale currentLocale]];
[self.formatterOra setDateFormat:self.formatOra];
self.dal = NSLocalizedString(#"from", nil);
self.ore = NSLocalizedString(#"at", nil);
CLLocation *vLoc = [[CLLocation alloc] initWithLatitude:self.geo.latitude longitude:self.geo.longitude];
CLLocation *user = [[CLLocation alloc] initWithLatitude:self.userGeo.latitude longitude:self.userGeo.longitude];
CLLocationDistance distance = [user distanceFromLocation:venueLoc];
if ([[prefs objectForKey:#"unit"] isEqualToString:#"km"]) {
cell.lblDist.text = [NSString stringWithFormat:#"%.1f Km", distance /1000];
} else {
cell.lblDist.text = [NSString stringWithFormat:#"%.1f Miles", distance /1609];
}
// compare the object's starting date with the current date to set some images in the cell
NSComparisonResult startCompare = [[self.hH[indexPath.row] objectForKey:#"startDate"] compare: [NSDate date]];
if (startCompare == NSOrderedDescending) {
cell.quad.image = [UIImage imageNamed:#"no_HT"];
cell.lblStartTime.textColor = [UIColor redColor];
} else {
cell.quad.image = [UIImage imageNamed:#"yes_HT"];
cell.lblStartTime.textColor = [UIColor colorWithRed:104.0/255.0 green:166.0/255.0 blue:66.0/255.0 alpha:1.0];
}
NSString *dataInizio = [NSString stringWithFormat:#"%# %# %# %#", self.dal, [self.formatterData stringFromDate:[self.hH[indexPath.row] objectForKey:#"startDate"]], self.ore, [self.formatterOra stringFromDate:[self.hH[indexPath.row] objectForKey:#"endDate"]]];
cell.lblStartTime.text = dataInizio;
PFObject *cat = [self.hH[indexPath.row] objectForKey:#"catParent"];
NSString *languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([languageCode isEqualToString:#"it"]) {
cell.lblCategory.text = [cat objectForKey:#"nome_it"];
} else if ([languageCode isEqualToString:#"es"]) {
cell.lblCategory.text = [cat objectForKey:#"nome_es"];
} else {
cell.lblCategory.text = [cat objectForKey:#"nome_en"];
}
//getting the image data from the Parse PFFile
PFFile *theImage = [self.hH[indexPath.row] objectForKey:#"photo"];
[theImage getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
cell.cellImageView.image = [UIImage imageWithData:data];
}
}];
//getting the cell object's owner and his profile
PFUser *usr = [self.hH[indexPath.row] objectForKey:#"parent"];
PFQuery *prof = [PFQuery queryWithClassName:#"Profile"];
prof.cachePolicy = kPFCachePolicyCacheThenNetwork;
[prof whereKey:#"parent" equalTo:usr];
[prof getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
//getting the object's rating and the number of votes
PFQuery *rateQuery = [PFQuery queryWithClassName:#"Rating"];
[rateQuery whereKey:#"parent" equalTo:object];
[rateQuery getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
float vote = [[object objectForKey:#"rate"] floatValue];
float temp = ((vote * 2) + 0.5);
int tempvote = (int)temp;
float roundedVote = (float)tempvote / 2;
// drawing the stars number, depending on the rating obtained
UIImage *starsImage = [UIImage imageNamed:#"stars"];
UIGraphicsBeginImageContextWithOptions(cell.imgVoto.frame.size, NO, 0);
CGPoint starPoint = (CGPoint) {
.y = (cell.imgVoto.frame.size.height * (2 * roundedVote + 1)) - (starsImage.size.height)
};
[starsImage drawAtPoint:starPoint];
cell.imgVoto.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.lblVoto.text = [NSString stringWithFormat:#"(%d)", [[object objectForKey:#"voters"] intValue]];
}
}];
}
}];
return cell;
}
EDIT: this is the cell code:
+ (void)initialize {
if (self != [HH class]) {
return;
}
}
-(id)initWithCoder:(NSCoder *)aDecoder {
if ( !(self = [super initWithCoder:aDecoder]) ) return nil;
self.cellImageView.image = [UIImage imageNamed:#"icona_foto"];
self.cellImageView.contentMode = UIViewContentModeScaleToFill;
self.formatterData = [[NSDateFormatter alloc] init];
self.formatData = [[NSString alloc] init];
self.formatterOra = [[NSDateFormatter alloc] init];
self.formatOra = [[NSString alloc] init];
self.formatData = [NSDateFormatter dateFormatFromTemplate:#"dd/MM" options:0 locale:[NSLocale currentLocale]];
[self.formatterData setDateFormat:self.formatData];
self.formatOra = [NSDateFormatter dateFormatFromTemplate:#"j:mm" options:0 locale:[NSLocale currentLocale]];
[self.formatterOra setDateFormat:self.formatOra];
self.lblVoto.text = #"(0)";
return self;
}
SECOND EDIT: this is the code in the viewDidLoad method:
PFQuery *hours = [PFQuery queryWithClassName:#"HH"];
hours.cachePolicy = kPFCachePolicyCacheThenNetwork;
// here I'm making lots of query constraints that I'll not include
[hours findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objectsNumber = objects.count;
self.hH = [[NSArray alloc] initWithArray:objects];
}
}];
[self.tableView reloadData];
}
I would move as much of the logic out of cellForRowAtIndexPath: as you can, it needs to be very light-weight to get good scrolling performance. You're doing a lot of work on the main thread, and I would do a lot more of this work when you get your model objects back from Parse (if you could post viewDidLoad I can give you more specific help) and update the table view when these calls are done:
[UIImage imageWithData:data]
anything to do with NSDateFormatter
CLLocation's initWithLatitude:longitude:
creating the rating stars image
None of these depend on the state of the table view, so they can be effectively precomputed and cached in a model object. If you simply scroll up and down the table, you're doing allo f the same work over and over, killing your performance.
Updated for the questioner's newest code:
I won't include all of your functionality here but this should give you an idea:
// create a single shared formatter instead of one per object
NSDateFormatter *dateFormatter = [NSDateFormatter dateFormatFromTemplate:#"dd/MM" options:0 locale:[NSLocale currentLocale]];
NSDateFormatter *timeFormatter = [NSDateFormatter dateFormatFromTemplate:#"j:mm" options:0 locale:[NSLocale currentLocale]];
[hours findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objectsNumber = objects.count;
for (SomeObject *modelObj in objects) {
// if you can add properties to your model object directly, do that
// otherwise write a category on the Parse object to add the ones you need
modelObj.dateString = [NSString stringWithFormat:#"%# %# %# %#", modelObj.dal, [self.dateFormatter stringFromDate:[modelObj objectForKey:#"startDate"]], modelObj.ore, [self.timeFormatter stringFromDate:[modelObj objectForKey:#"endDate"]]];
// create your locations, images, etc in here too
}
self.hH = [[NSArray alloc] initWithArray:objects];
}
}];]
Then in cellForRowAtIndexPath:, take the precomputed properties and simply assign them to the appropriate labels, image views, etc.
It would be even better to do most of this processing off the main thread via GCD, but that is most likely out of scope for this question. See Using GCD and Blocks Effectively for more information. Just remember do only interact with UIKit from the main thread!
have a try by removing
CLLocation *vLoc = [[CLLocation alloc] initWithLatitude:self.geo.latitude longitude:self.geo.longitude];
CLLocation *user = [[CLLocation alloc] initWithLatitude:self.userGeo.latitude long itude:self.userGeo.longitude];
CLLocationDistance distance = [user distanceFromLocation:venueLoc];
This was at first sight , then I see your all your code and I realize a lot of image are used
Because UITableView takes some time to layout cells.
Solution:
step1. Set section number and row number to 0.
step2. Reload tableView in viewDidAppear.
Then your view controller cloud response quickly and then show cells.
I am trying to pull an LDAP "jpegPhoto" attribute from an openLDAP server using a iOS openLDAP framework. The framework pulls the data as a dictionary of NSStrings.
I need to convert the NSString of "jpegPhoto" (which also appears to be base64 encoded) to UIImage, with the end result being that I display the jpegPhoto as the user's image when they login.
More Info:
-(NSDictionary *)doQuery:(NSString *)query:(NSArray *)attrsToReturn {
...
while(attribute){
if ((vals = ldap_get_values_len(ld, entry, attribute))){
for(int i = 0; vals[i]; i++){
//Uncomment if you want to see all the values.
//NSLog(#"%s: %s", attribute, vals[i]->bv_val);
if ([resultSet objectForKey:[NSString stringWithFormat:#"%s",attribute]] == nil){
[resultSet setObject:[NSArray arrayWithObject:[NSString stringWithFormat:#"%s",vals[i]->bv_val]] forKey:[NSString stringWithFormat:#"%s",attribute]];
}else{
NSMutableArray *array = [[resultSet objectForKey:[NSString stringWithFormat:#"%s",attribute]] mutableCopy];
[array addObject:[NSString stringWithFormat:#"%s",vals[i]->bv_val]];
[resultSet setObject:array forKey:[NSString stringWithFormat:#"%s",attribute]];
}
}
ldap_value_free_len(vals);
};
ldap_memfree(attribute);
attribute = ldap_next_attribute(ld, entry, ber);
};
...
}
-(UIIMage *)getPhoto{
NSString *query = [NSString stringWithFormat:#"(uid=%#)",self.bindUsername];
NSArray *attrsToReturn = [NSArray arrayWithObjects:#"cn",#"jpegPhoto", nil];
NSDictionary *rs = [self doQuery:query:attrsToReturn];
NSString *photoString = [[rs objectForKey:#"jpegPhoto"] objectAtIndex:0];
NSLog(#"The photoString is: %i %#",[photoString length],#"characters long"); //returns 4
NSData *photoData = [NSData dataWithBase64EncodedString:photoString];
UIImage *userPhoto = [UIImage imageWithData:photoData];
return userPhoto;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.studentNameLabel.text = [NSString stringWithFormat:#"Hi %#!",[self.ldap getFullName]];
self.studentPhotoImage.image = [self.ldap getPhoto];
[self checkForProctor];
}
Try this code
NSData *dataObj = [NSData dataWithBase64EncodedString:beforeStringImage];
UIImage *beforeImage = [UIImage imageWithData:dataObj];
There are many similar questions in Stackoverflow.. Please refer the following links
UIImage to base64 String Encoding
UIImage from bytes held in NSString
(Since there has been no working code posted for getting the image data from LDAP, I wanted to add this answer for the benefit of future visitors.)
The missing piece was reading the binary data into an NSData object rather than an NSString when you have binary data that might contain NULL (zero) values within it, such as images or GUIDs.
value = [NSData dataWithBytes:vals[0]->bv_val length:vals[0]->bv_len];
+ (NSArray *)searchWithBaseDN:(const char *)baseDN andFilter:(const char *)filter andScope:(int)scope {
...
while(entry)
{
// create a dictionary to hold attributes
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
attribute = ldap_first_attribute(ld, entry, &ber);
while(attribute)
{
if ((vals = ldap_get_values_len(ld, entry, attribute)))
{
if (ldap_count_values_len(vals) > 1) {
NSMutableArray *values = [[NSMutableArray alloc] init];
for(int i = 0; vals[i]; i++) {
[values addObject:[NSString stringWithUTF8String:vals[i]->bv_val]];
}
[dictionary setObject:values forKey:[NSString stringWithUTF8String:attribute]];
} else {
NSObject *value = nil;
if (strcmp(attribute, "thumbnailPhoto") == 0 || strcmp(attribute, "objectGUID") == 0) {
value = [NSData dataWithBytes:vals[0]->bv_val length:vals[0]->bv_len];
} else {
value = [NSString stringWithFormat:#"%s", vals[0]->bv_val];
}
[dictionary setObject:value forKey:[NSString stringWithUTF8String:attribute]];
}
ldap_value_free_len(vals);
};
ldap_memfree(attribute);
attribute = ldap_next_attribute(ld, entry, ber);
};
...
}