Saturday, October 13, 2012

PieChart in iPhone

I was in need to include a pie chart view in my iPhone project to represent usage graphically. I first came up with a solution. That was to draw a circle of the full size and then drawing the angle that was calculated to the usage size i wanted to represent over the same circle with a different color. I did that into a simple drawRect function. Below are the codes i did.
float endDeg = [currentSize floatValue]/[maxSize floatValue];
NSLog(@"the end degree is : %f",endDeg);
endDeg = endDeg*360.00;
NSLog(@"the end degree is : %f",endDeg);
if(endDeg>360)
{
endDeg=360;
}
int x = 90;
int y = 80;
int r =70;
CGContextRef ctx=UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(ctx, 0, 255,0, 1.0);
CGContextMoveToPoint(ctx,x,y);//center point
CGContextAddArc(ctx,x,y,r,(0)*M_PI/180.0,(360)*M_PI/180.0,0);
CGContextFillPath(ctx);
CGContextSetRGBFillColor(ctx, 0,0,255, 0.9);
CGContextMoveToPoint(ctx,x,y);
CGContextAddArc(ctx,x,y,r,(0)*M_PI/180.0,(endDeg)*M_PI/180.0,0);
CGContextFillPath(ctx);
got the output but not the exact solution i needed. I Wanted some animation to that. Exploration ended in xyPieChart. I just simply integrated the class and customized it to what i needed and came up what i longed for. You can download the xyPieChart from here
There are hell out of frameworks open-sourced for graphical representation of data. 
I just included the xyPieChart classes to my project and the
In ViewDidLoad of the class where i needed to display the chart i included the following
Initiated the slice array which represents the number of slices in the Chart. And added the slice value to the array.
self.slices = [NSMutableArray arrayWithCapacity:2];
[_slices addObject:usedSize];
usedSize = [NSNumber numberWithInt:[maxSize intValue]-[usedSize intValue]];
[_slices addObject:usedSize];
[self.pieChartRight setDelegate:self];
[self.pieChartRight setDataSource:self];
[self.pieChartRight setPieCenter:CGPointMake(95,80)];
[self.pieChartRight setShowPercentage:YES];
self.pieChartRight.backgroundColor =[UIColor blackColor];
self.pieChartRight.layer.cornerRadius =10;
self.pieChartRight.layer.borderWidth = 1;
self.pieChartRight.layer.borderColor = [[UIColor colorWithRed:(188/255.f) green:230 blue:0 alpha:1.0] CGColor];
[self.percentageLabel.layer setCornerRadius:100];
self.sliceColors =[NSArray arrayWithObjects:
[UIColor colorWithRed:(0/255.f) green:0 blue:255 alpha:1.0],
// [UIColor colorWithRed:229/255.0 green:66/255.0 blue:115/255.0 alpha:1],
[UIColor colorWithRed:(0/255.f) green:255 blue:0 alpha:1.0],

and then i  included the follwing delegates.

//delegate for piechart
#pragma mark - XYPieChart Data Source

- (NSUInteger)numberOfSlicesInPieChart:(XYPieChart *)pieChart
{
return self.slices.count;
}

- (CGFloat)pieChart:(XYPieChart *)pieChart valueForSliceAtIndex:(NSUInteger)index
{
return [[self.slices objectAtIndex:index] intValue];
}

- (UIColor *)pieChart:(XYPieChart *)pieChart colorForSliceAtIndex:(NSUInteger)index
{
return [self.sliceColors objectAtIndex:index];
}

#pragma mark - XYPieChart Delegate
- (void)pieChart:(XYPieChart *)pieChart didSelectSliceAtIndex:(NSUInteger)index
{
NSLog(@"did select slice at index %d",index);
self.selectedSliceLabel.text = [NSString stringWithFormat:@"$%@",[self.slices objectAtIndex:index]];
}
Thats it i got the chart displayed well on my page animated.





Accessing Images in iPhone


In iPhone you can use the Assets Library framework to access the pictures and videos managed by the Photo application in the device. Have a look at framework reference by apple here.
I recenlty access all images in my iPhone device's photo application. I would like to share what i actually tried through this blog.

I first accessed all the albums in Photo appllication of my device. Then i enumerated each ato get all the images in each album. Below code takes all the pics and add to an Array.
To load albums use the code below. 

dispatch_async(dispatch_get_main_queue(), ^
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Group enumerator Block
void (^assetGroupEnumerator)( ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if (group == nil){
return;
}
[self.assetGroups addObject:group];
NSLog(@"the total albums are : %d",self.assetGroups.count);
NSLog(@"count in thtread: %d", [group numberOfAssets]);//Displays count of total photos
};
// Group Enumerator Failure Block
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Album Error: %@", [error description]] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
NSLog(@"A problem occured %@", [error description]);
};
// Enumerate Albums
NSLog(@"enumerate assets in thread");
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:assetGroupEnumberatorFailure];
[library release];
[pool release];
})
Where the assetGroups is nothing but ALAssetGroup to which all the albums is added through the above code.
And now loop through each album and pic the assets init.

for(ALAssetsGroup *group in self.assetGroups)
{
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if(result == nil)
{
return;
}
NSLog(@" the assset are : %@", result);
Asset *asset = [[[Asset alloc] initWithAsset:result] autorelease];
[self.elcAssets addObject:asset];
NSLog(@" the assset are : %@", self.elcAssets);
}];
}
NSLog(@"album count : %d", self.assetGroups.count);
NSLog(@"enumerating photos");
NSMutableArray *selectedAssetsImages = [[[NSMutableArray alloc] init] autorelease];
for(Asset *elcAsset in self.elcAssets)
{
[selectedAssetsImages addObject:[elcAsset asset]];
}
Asset here is an array selectedAssestsImages ia an array to which i add all the looped assets. So finally you get all the assets in this array.
Thats how i programmed to take all the images from the Photos in my device.  For even more brief solution have a look at this
Happy blogging :)

bitlyIntegration

So here is my another sharing from my exploration. Hard to find a constant upate on my blog site. Let me try to hold a girp on that heare after.
This short blog explains how i integrated bitly service to my application.
Its all a request with some query parametes to the bitly service. I wanted the integration class as a seperate module so that i can just use it any where in any application just by including the file to the project.
I so wrote a seperate class which hold the responsibilty of service calls to the service with implemented delegates of it.
When comming to use the bitly its necessary to have an account in it by which u get a user id and the bitly user key. And of cource the long url that to be made tiny. All of these are need to query the request.
Before to use the service get those things ready. The below is the synchronous call code for getting the url shortend.

NSString* urlString = [NSString stringWithFormat: @"http://api.bit.ly/v3/shorten?login=%@&apiKey=%@&uri=%@&format=txt",
[self _formEncodeString: _loginID],
[self _formEncodeString: _userKey],
[self _formEncodeString: [_url absoluteString]]];
NSURLRequest* request = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]
cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 30.0];

NSError *errorResponse = nil;
NSHTTPURLResponse *ShortURLResponse;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&ShortURLResponse error:&errorResponse];
NSString* string = [[[NSString alloc] initWithData: returnData encoding: NSASCIIStringEncoding] autorelease];
string = [string stringByTrimmingCharactersInSet: [NSCharacterSet newlineCharacterSet]];
NSLog(@"this is the final trimmed url that is generated: %@",string);

I have builted the url with query string containg the user id, the userkey, the url to shorten. This is all to get wht u want.
I just wrote this as a seperate objective c class where you have to initialte it with the url to shorten.
The class has async call with the deleagtes implemented to handle the flow.

You can simply download the module here. And of course for the lazy guys like me can get the sample project here.

Happy blogging.





Monday, October 1, 2012

Camera integtration in iPhone application

It has quite time since I have blogged something. Let me write how to access camera from an iPhone application and handle the delegats well to grab the image out of it. Its quite easy to include camera feature into any ios application provided the device has a camera support, and you make use of the imagepickerController of apple :p.
You can have a secondary view controller created for managing the overlap view to the camera.
In this class you define and declare the needed controls to apperar as a overlay to the camera, such as snap button cancel or done, cancel etc: This can be made used to customise the way how the camera screen should apper once camera is selected from your application.
You then have to use the apples imagepickerController to pic the image snaped.

Creating a overlayViewController includes the following.
  1. Declare the needed controlls in .h file
  2. Implement those in .m
  3. Include the UIImagePickerControllerDelegate
  4. Create needed delegates for your overlayViewController
A Sample overlay having buttons takepicture button and done button with actions takePhoto, close respectively for those. Also the delegate methods didTakePicture, the method where you get the snaped picture and didFinshWithCamera that can be used to perform any action once you are done with camera. 

The .h file of overlayViewController:

@protocol OverlayViewControllerDelegate;
@interface OverlayViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
id <OverlayViewControllerDelegate> delegate;
UIImagePickerController *imagePickerController;
@private
UIBarButtonItem *takePictureButton;
UIBarButtonItem *cancelButton;
}

@property (nonatomic, assign) id <OverlayViewControllerDelegate> delegate;
@property (nonatomic, retain) UIImagePickerController *imagePickerController;

@property (nonatomic, retain) IBOutlet UIBarButtonItem *takePictureButton;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *cancelButton;

- (void)setupImagePicker:(UIImagePickerControllerSourceType)sourceType;
// camera page (overlay view)
- (IBAction)done:(id)sender;
- (IBAction)takePhoto:(id)sender;
@end

@protocol OverlayViewControllerDelegate
- (void)didTakePicture:(UIImage *)picture;
- (void)didFinishWithCamera;
@end

Now in you .m file. Initiate the imagePickerController and map its delegate

self.imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
self.imagePickerController.delegate = self;

- (void)setupImagePicker:(UIImagePickerControllerSourceType)sourceType
{
NSLog(@"enters setupImagePicker");
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera)
{
// user wants to use the camera interface
//
self.imagePickerController.showsCameraControls = NO;
if ([[self.imagePickerController.cameraOverlayView subviews] count] == 0)
{
// setup your custom overlay view for the camera
//
// ensure that your custom view's frame fits within the parent frame
CGRect overlayViewFrame = self.imagePickerController.cameraOverlayView.frame;
CGRect newFrame = CGRectMake(0.0,
CGRectGetHeight(overlayViewFrame) -
self.view.frame.size.height - 10.0,
CGRectGetWidth(overlayViewFrame),
self.view.frame.size.height + 10.0);
self.view.frame = newFrame;
[self.imagePickerController.cameraOverlayView addSubview:self.view];
}
}
}

This calls the didFinishWithCamera delegats.
- (IBAction)done:(id)sender
{
[self.delegate didFinishWithCamera];
}

Action that maps takesPhoto. This just calls the takePicture of imgaePickerController which is responsible for initiating still image capture.

- (IBAction)takePhoto:(id)sender
{
[self.imagePickerController takePicture];
}

Also include the follwoing delegates of imgePicker which gets called when an image is taken by the camera.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
if (self.delegate)
[self.delegate didTakePicture:image];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self.delegate didFinishWithCamera]; // tell your delegate we are finished with the picker
}

Thats all you do with your overlayController.

Now How to use this in your class. You have to now include the overlayController delegate and imgaPickerController in header of the class where you wish to inclue a button for a camera capture.
Now call the below function in the button action you need.

- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType
{
NSLog(@"entered showImagePicker camera");
if ([UIImagePickerController isSourceTypeAvailable:sourceType])
{
[self.overlayViewController setupImagePicker:sourceType];
[self presentModalViewController:self.overlayViewController.imagePickerController animated:YES];
}
}

This checks for the sourcetype you give that should be a camera source type the syntax is as below

[self showImagePicker:UIImagePickerControllerSourceTypeCamera];

Thants it now include the delegates of ovrelay class that was created

- (void)didTakePicture:(UIImage *)picture
{
//do some thing with the picture.
}
- (void)didFinishWithCamera
{
[self dismissModalViewControllerAnimated:YES];
}

The didTakePicture tells that a picture was take, you get the picture you snaped in this delegate. And didFinishWithCamera tells to finish with the camera.
Thats it you get your camera to snap from your application and the image you snaped.