How to Generate Random Numbers?

If you are creating an app with dynamical content, plot, random number is something definitely you need to know. Random number of enemies, random score for each smaller achievement, random number… forget about the reasons you need to know it!

There are few functions in iPhone SDK that gives you random number. The best is arc4random(). Why best? Because, each time you call this function you get the random number, without performing any other randomize procedures.

```int myRandomNumber;
myRandomNumber = arc4random();
int myRandomNumber2;
myRandomNumber2 = arc4random();```

In above example myRandomNumber and myRandomNumber2 are two different integers, it will be amazing coincident if they are the same.

There is one thing you need to know about it. arc4random() doesn’t ask you about the range of given number, in fact in most cases it returns you the random 8-9 digits numbers (positive or negative). But, using (un)known modulo operation (returns the remainder of division) you can get:

• arc4random() % 10 : random number from range <0, 9>
• arc4random() % 11 : random number from range <0, 10>
• arc4random() % 2 : random number from range <0, 1>
• arc4random() % 1000 : random number from range <0, 999>
• arc4random() % 1001 : random number from range <0, 1000>

Now, using the know addition you can generate any range you wish:

• 5 + arc4random() % 10 : <5,14>
• 100 + arc4random() % 15 : <100,114>

I hope I won’t disappoint You if I don’t include any sample project this time. For one simple function returning an integer 7 examples should be enough.

How to take screenshots within your Application.

iPhone / iPod touch allows you to make screenshots (saves the contents as an image) by pressing both home and power button, although many users don’t know this functionality. If you go to your camera roll or sync photos with your computer, every screenshot you make is an image 320 x 480 px.

Today I will show you how to make a screenshot of arbitrary size using Quartz. What does arbitrary size mean? Well you can not only save the smaller part of your screen, but, if you for example have bigger view than 320×480 px you can save it all, not only the visible part.

Before you start, you have to add the QuartzCore framework to the project.

`#import <QuartzCore/QuartzCore.h>`

You can add this line in either header (.h) or implementation file (.m).

Now it’s time to add the method which will make a screenshot and explain how it works:

```-(void)saveToCameraRoll {
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, self, nil, nil);

/*
flashView.alpha = 1;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
flashView.alpha = 0;
[UIView commitAnimations];
*/
}```

I’ve implemented the saveToCameraRoll method were first five lines do everything you need. It’s quite difficult to discuss it, as long as I never mentioned about Quartz drawingcontextslayers… But, first line creates the context of our view (UIViewController’s self.view) size. Using that context’sframe (it’s not frame properly speaking) it contents is rendered (2nd line) and saved to anviewImage. 4th line is closing the context as we do not need it anymore, and the 5th line putsviewImage to the Camera Roll.

How about the part in the comment ( /* and */ )? Well it’s my idea how to copy the animation iPhone uses while making the screenshot using home and power buttons. I created the flashView – simple white view of the same size of my self.view most time 100% transparent. When the userdecides to create a screenshot using a button I provided in the application, flashView become visible and during half a second it’s transparent again. And the alert to inform what has just happen.

Please remember that above method saves the whole self.view and all it’s subviews. So whatever is a subview of self.view will be saved as well. You can change the alpha property of anything you don’t want to save and reveal what’s behind it, and after screenshot was made bring alpha to normal. While making a screenshot as long as it will be one procedure – one task user won’t see any changes in interface. Example:

```-(void)saveToCameraRoll {	topView.alpha = 0;

UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, self, nil, nil);
topView.alpha = 1;```

}

As always (don’t thank me) I provided an sample project. It alows you to make screenshot of whole iPhone screen (320 x 480 px), only central part (320 x 240 px) and again the whole iPhone screen without button on the bottom.

Thanks goes to http://chris-software.com/

You can get the source code from here

iOS5 – how to turn off ARC on individual files ?

iOS5 SDK comes with new feature of ARC.

ARC = Automatic Reference Counting which is used for enabling memory management at compiler level.

fig.1

But due to this feature, you might not able to compile facebook API, HJCache library or any other libraries developed for iPhone/iPad development.

Here is the one of the example of that error.

Automatic Reference Counting forbids explicit message send of ‘dealloc’

I have shared a trick to enable older library compilation in new iOS5 SDK.

1. Click on the Project.
2. Click on the target.
3. Select build phases tab.
4. Select the multiple files in which you want to turn off ARC.
5. Press ENTER / Hit Enter key
6. Type “-fno-objc-arc” ( without quotes, as shown in image )
I hope this might be helpful to you.
Thanks & Regards,
Ankit Vyas

This sample iPad application contains a search bar and a large UIMapView. Search results are visualized on the map with a placemark and by clicking the placemark the map will zoom to the viewport returned from the geocoding service. When I started working with the geocoding service it was still in version two, this last week Google launched version three. Version two will be depricated of course but I had already written the parser for version two so I’ve included it as well in my sample. Of course the API works for iPhone as well. Because the API contains quite a lot of code you will find the code inside the sample project at the bottom of this page.

```- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {

NSLog(@"Searching for: %@", searchBar.text);
if(forwardGeocoder == nil)
{
forwardGeocoder = [[BSForwardGeocoder alloc] initWithDelegate:self];
}

// Forward geocode!
[forwardGeocoder findLocation:searchBar.text];

}
-(void)forwardGeocoderFoundLocation
{
if(forwardGeocoder.status == G_GEO_SUCCESS)
{
int searchResults = [forwardGeocoder.results count];

// Add placemarks for each result
for(int i = 0; i < searchResults; i++)
{
BSKmlResult *place = [forwardGeocoder.results objectAtIndex:i];

// Add a placemark on the map
CustomPlacemark *placemark = [[CustomPlacemark alloc] initWithRegion:place.coordinateRegion];

if([countryName count] > 0)
{
}

[countryName release];
}

if([forwardGeocoder.results count] == 1)
{
BSKmlResult *place = [forwardGeocoder.results objectAtIndex:0];

// Zoom into the location
[mapView setRegion:place.coordinateRegion animated:TRUE];
}

// Dismiss the keyboard
[searchBar resignFirstResponder];
}
}```
When search has executed the geocoder contains the result and a status code. The status code is from Google and to support both version 2 and 3 of the API there’s an enum containing response codes. If everything goes well the status should be “G_GEO_SUCCESS” and the “results” property will contain an array of BSKmlResult objects which contain the location information returned for the query. Here’s an example query for my home town Stockholm (Google geocoding service version 3) :http://maps.google.com/maps/api/geocode/xml?address=stockholm&sensor=false.
The details for the service can be found here:http://code.google.com/apis/maps/documentation/geocoding/.
There are multiple arguments you can pass to the search url, you should read the geocoding documentation and check the search url in the application before you implement this in your own app.

BSForwardGeocoder

```#import <Foundation/Foundation.h>

// Enum for geocoding status responses
enum {
G_GEO_SUCCESS = 200,
G_GEO_SERVER_ERROR = 500,
G_GEO_MISSING_QUERY = 601,
G_GEO_UNKNOWN_DIRECTIONS = 604,
G_GEO_TOO_MANY_QUERIES = 620
};

@protocol BSForwardGeocoderDelegate <NSObject>
@required
-(void)forwardGeocoderFoundLocation;
@optional
-(void)forwardGeocoderError:(NSString *)errorMessage;
@end

@interface BSForwardGeocoder : NSObject {
NSString *searchQuery;
int status;
NSArray *results;
id<BSForwardGeocoderDelegate> delegate;
}
-(id) initWithDelegate:(id<BSForwardGeocoderDelegate>)del;
-(void) findLocation:(NSString *)searchString;

@property (assign) id<BSForwardGeocoderDelegate> delegate;
@property (nonatomic, retain) NSString *searchQuery;
@property (nonatomic, retain) NSArray *results;

@end```

BSKmlResult
The result class is the same for both version 2 and 3 of the service. A big difference in the returned information between the versions is the way address components are returned, in version three more information is returned and therefore I’ve created another class to store the address component information. The properties: countryNameCode, countryName, subAdministrativeAreaName and localityName are for version two only. For version three all address information is stored in the “addressComponents” array (contains BSAddressComponent objects). Because there is really no reason to use version 2 anymore you probably want to remove this code for your own application.

```#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface BSKmlResult : NSObject {
NSString *countryNameCode;
NSString *countryName;
NSString *localityName;
float viewportSouthWestLat;
float viewportSouthWestLon;
float viewportNorthEastLat;
float viewportNorthEastLon;
float boundsSouthWestLat;
float boundsSouthWestLon;
float boundsNorthEastLat;
float boundsNorthEastLon;
float latitude;
float longitude;
float height;
NSInteger accuracy;
}

@property (nonatomic, assign) NSInteger accuracy;
@property (nonatomic, retain) NSString *countryNameCode;
@property (nonatomic, retain) NSString *countryName;
@property (nonatomic, retain) NSString *localityName;
@property (nonatomic, assign) float latitude;
@property (nonatomic, assign) float longitude;
@property (nonatomic, assign) float viewportSouthWestLat;
@property (nonatomic, assign) float viewportSouthWestLon;
@property (nonatomic, assign) float viewportNorthEastLat;
@property (nonatomic, assign) float viewportNorthEastLon;
@property (nonatomic, assign) float boundsSouthWestLat;
@property (nonatomic, assign) float boundsSouthWestLon;
@property (nonatomic, assign) float boundsNorthEastLat;
@property (nonatomic, assign) float boundsNorthEastLon;

@end```

To make it somewhat simple to find address components I’ve added a method that will search for components for you. Using version 3 of the geocoding service you will get the country name using this code:

```NSArray *countryName = [BSKmlResultPlace findAddressComponent:@"country"];
if([countryName count] > 0)
{
}
[countryName release];```

There are also properties to make the result simple to use with a MKMapView. The “coordinate” property returns a CLLocationCoordinate2D object, “coordinateSpan” calculates and returns a MKCoordinateSpan object for setting the map viewport. The “coordinateRegion” combines both coordinate and coordinateSpan returning a MKCoordinateRegion object that can be used to directly move your MKMapView to the right place.

```#import <Foundation/Foundation.h>

NSString *longName;
NSString *shortName;
NSArray *types;
}

@property (nonatomic, retain) NSString *longName;
@property (nonatomic, retain) NSString *shortName;
@property (nonatomic, retain) NSArray *types;```

This class maps against what’s returned in version 3 of the geocoding service. It’s just a container class.

You can grab the sample code from Here

How to change iPhone/iPad Navigation Bar Title text color and other Property?

Hi,

In iPhone/iPad several times we need to develop some custom controls or we need to change existing attribute.same way here i am going to explain how to change UINavigationbar’s title property like  font,color,size etc.

You need to use a `UILabel` as the `titleView` of the `navigationItem`.

The label should:

• Have a clear background color (`label.backgroundColor = [UIColor clearColor]`).
• Use bold 20pt system font (`label.font = [UIFont boldSystemFontOfSize: 20.0f]`).
• Have a shadow of black with 50% alpha (`label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5]`).
• You’ll want to set the text alignment to centered as well (`label.textAlignment = UITextAlignmentCenter`).

Set the label text color to be whatever custom color you’d like. You do want a color that doesn’t cause the text to blend into shadow, which would be difficult to read.

I worked this out through trial and error, but the values I came up with are ultimately too simple for them not to be what Apple picked. 🙂

If you want to verify this, drop this code into `initWithNibName:bundle:` in`PageThreeViewController.m` of Apple’s NavBar sample. This will replace the text with a yellow label. This should be indistinguishable from the original produced by Apple’s code, except for the color.

````- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {   `
`  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];    `
` if (self)     {         // this will appear as the title in the navigation bar    `
`     UILabel *label = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];      `
`   label.backgroundColor = [UIColor clearColor];         `
` label.font = [UIFont boldSystemFontOfSize:20.0];       `
`   label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];       `
`   label.textAlignment = UITextAlignmentCenter;      `
`   label.textColor = [UIColor yellowColor]; // change this color      `
`   self.navigationItem.titleView = label;          `
` label.text = NSLocalizedString(@"PageThreeTitle", @"");       `
`   [label sizeToFit];    `
` }    `
` return self;`
` } ````

Today most of the applications we build have a common feature: Socialize! One common way to achieve this my integrating Facebook within the app.For iPhone applications FacebookConnect is the only way to integrate facebook social features. Facebook team has developed a sdk for iPhone. A sample code showing the use and integration of Facebook Connect in your application. This is quite simple and also tons of tutorials, forums, e-books and videos are out here on the web.

Objective: Create a simple view based application and publish a feed using FacebookAgent.

It also includes facebook connect sdk. So you don’t need to add this sdk elsewhere or even update any project settings for this purpose.

2. Create a new project, name it FacebookAgentTest. Righ click on the project in the XCode and select Add existing files. Add the FacebookAgent Folder to your classes. Check copy the source files.

```@interface FacebookAgentTestViewController : UIViewController {
...```

4. Declare a member variable of type FacebookAgent.

`FacebookAgent* fbAgent;`

```fbAgent = [[FacebookAgent alloc] initWithApiKey:@"PLACE YOUR FACEBOOK APPLICATION API KEY"
ApiProxy:nil];
fbAgent.delegate = self;```

6. Declare an IBAction method in the FacebookAgentTest.h file.

`-(IBAction)updateStatus:(id)sender;`

7. Define the above method in FacebookAgentTest.m file.

```-(IBAction)updateStatus:(id)sender{
}```

8. Open FacebookAgentTestViewController.xib and add a button in the view and connect the above method on its touchesUpInside signal.

9. Now just add the following lines in the updateStatus method to publish a feed!

```-(IBAction)updateStatus:(id)sender{
[fbAgent publishFeedWithName:@"Hellow world"
captionText:@"how are you?"
userMessagePrompt:@"What do you think:"];
}```

This code will first check if the user is logged in. If logged in it will show the feed dialog.
If the user is not logged in already, first the login dialog will be shown, after logging in, the feed dialog will be shown automatically!

But one minute, there is one require method in the FacebookAgentDelegate protocol. So, you need to define this:

```- (void) facebookAgent:(FacebookAgent*)agent loginStatus:(BOOL) loggedIn{
}```

Above method is called when the user logs in or logs out of the facebook. If you use any login button which is very likely, you may change the button title here.

10. Try updating your status. For this use this line:

`[fbAgent setStatus:@"status from iPhone 1"];`

This will first check if the user is logged in. if not logged in, then it will show the login prompt first.
After log in it will check if extended permission is enabled for this app. if not it will show the permission dialog.
Having given the permission, it will change the user status.

BUT.

11. You need to two more FacebookAgentDelegate method if you want to change status:

```- (void) facebookAgent:(FacebookAgent*)agent requestFaild:(NSString*) message{
}
}```

12. Thats all  Run the app!

You can look into the FacebookAgent.h for more detail. It is well documented. If you still have some question shoot here or drop me mail.
Feel free to use this classes without any restriction but I will appreciate if you let me know in which app you are using it

What can be done now using FacebookAgent:
1. Fetch user name:

`fbAgent.shouldFetchUsernameAfterLogin = YES`

and also define the corresponding delegate method:

```- (void) facebookAgent:(FacebookAgent*)agent didLoadName:(NSString*) name{
//use the name
}```

2. Make your own attachment and publish a feed.

```// this method has some over loaded versions too
- (void) publishFeed:(NSString*)attachement;```

3. Publish feed by passing, name, caption, image and link url.

```// this method has some over loaded versions too
/**
* Let the agent make attachement for you. You just pass the information
*
*/
- (void) publishFeedWithName:(NSString*)name
captionText:(NSString*)caption
imageurl:(NSString*)url
userMessagePrompt:(NSString*)prompt;```

`- (void) uploadPhoto:(NSString*)imageurl;`

`- (void) askPermission;`

```- (void) login;
- (void) logout;```

The delegates also offers some handy callback options like:

```/**
* Must define this method if setStatus is called
*
* This method is called when user status is changed either successfully or not
*/

/**
*
* This method is called after the agent fetched facebook profile name
*/

/**
* Must define this method if uploadPhoto is called
*
* This method is called after photo is uploaded
*/

/**
* Must impement this method if any of the above method is defined
*
* This method is called if the agent fails to perform any of the above three actions
*/

@required

/**
* This method is called if after login or logout
*/

Here is the demo project. DONT FORGET TO ADD YOUR key and secret!!

Cocoa: Convert number to comma-separated NSString

At some point in your Mac, iPhone, or iPad development you may find the need to express a long number (1000000000) as a comma-separated string (1,000,000,000) to make life easier on your users. The NSNumberFormatter class is a rich tool for converting numbers to strings supporting different types of currencies and localizations. It’s also the perfect class to leverage for our comma-ing task.

First of all, the NSNumberFormatter class works on NSNumber objects, so we need to convert our number to a NSNumber if it’s not there already.
`NSNumber *number = [NSNumber numberWithInt:1000000000];`

NSNumber also supports floating point values (numberWithFloat) and the regular gang of other number formats.

With our NSNumber in hand, we can get on with the good stuff. NSNumberFormatter supports grouping of numeric digits into arbitrary length groups (we want groups of three) and separating the groups with arbitrary strings (we want to use a comma (@”,”) but we could use any string). Here’s the code that makes our string:

```NSNumberFormatter *frmtr = [[NSNumberFormatter alloc] init]; [frmtr setGroupingSize:3]; [frmtr setGroupingSeparator:@","]; [frmtr setUsesGroupingSeparator:YES]; NSString *commaString = [frmtr stringFromNumber:number]; ```

Hi,

I have found one very simple way how to generate QR Code using Google Api.Just take 1 UIWebView in my code I have taken IBOutlet UIWebView *webView; and I want add this Much of Information in My QR Code.

2.First Name and  Last Name

4.Website

I have also taken 1 Button Event named here is QRcodeTapped.I am receiving all the Value from NSDictionary.Please check the bellowed methods.

– (IBAction)QRcodeTapped:(id)sender {

NSLog(@”d==%@”,[d valueForKey:@”QR First Name”]);

NSLog(@”d==%@”,[d valueForKey:@”QR Last Name”]);

NSLog(@”d==%@”,[d valueForKey:@”QR  Last Name”]);

NSLog(@”d==%@”,[d valueForKey:@”QR Physical City”]);

NSLog(@”d==%@”,[d valueForKey:@”QR Physical State”]);

NSLog(@”d==%@”,[d valueForKey:@”QR Physical Zip”]);

NSLog(@”d==%@”,[d valueForKey:@”QR Physical Zip Plus 4″]);

NSLog(@”d==%@”,[d valueForKey:@”QR Website”]);

//this url has several parameters which is passed here. After that don’t Forget NSUTF8StringEncoding.

NSString *url=[NSString stringWithFormat:@”http://chart.apis.google.com/chart?cht=qr&chs=200×200&chl=MECARD:ORG%@CN%@%@CTEL%@CADR%@%@%@%@%@CEMAIL%@&#8221;,[d valueForKey:@”QR Business Name”],[d valueForKey:@”QR First Name”],[d valueForKey:@”QR Last Name”],[d valueForKey:@”QR Phone”],[d valueForKey:@”QR Physical Address”],[d valueForKey:@”QR Physical City”],[d valueForKey:@”QR Physical State”],[d valueForKey:@”QR Physical Zip”],[d valueForKey:@”QR Physical Zip Plus 4″],[d valueForKey:@”QR Website”]];

//Create a URL object.

NSURL *Curl=[NSURL URLWithString:url];

//URL Requst Object

NSURLRequest *request = [NSURLRequest requestWithURL:Curl];

//Load the request in the UIWebView.

}

Grab the Sample Code from Here

Hi,

See new sample code “MessageComposer” which includes both Mail and Messages features.

This application shows how to target older OS versions while building with newly released APIs. It also illustrates how to use the MessageUI framework to edit and send email messages from within your application.

Tap the “Compose Mail” button to display an email composition interface if your device is running iPhone OS 3.0 or launch the Mail application, otherwise.

Step 1:

#import <MessageUI/MessageUI.h>

#import <MessageUI/MFMailComposeViewController.h>

@interface MailComposerViewController : UIViewController <MFMailComposeViewControllerDelegate>

{

IBOutlet UILabel *message;

}

@property (nonatomic, retain) IBOutlet UILabel *message;

-(IBAction)showPicker:(id)sender;

-(void)displayComposerSheet;

-(void)launchMailAppOnDevice;

Step 2:Now write the code for mail.

-(IBAction)showPicker:(id)sender

{

// This sample can run on devices running iPhone OS 2.0 or later

// The MFMailComposeViewController class is only available in iPhone OS 3.0 or later.

// So, we must verify the existence of the above class and provide a workaround for devices running

// earlier versions of the iPhone OS.

// We display an email composition interface if MFMailComposeViewController exists and the device can send emails.

// We launch the Mail application on the device, otherwise.

Class mailClass = (NSClassFromString(@”MFMailComposeViewController”));

if (mailClass != nil)

{

// We must always check whether the current device is configured for sending emails

if ([mailClass canSendMail])

{

[self displayComposerSheet];

}

else

{

[self launchMailAppOnDevice];

}

}

else

{

[self launchMailAppOnDevice];

}

}

#pragma mark –

#pragma mark Compose Mail

// Displays an email composition interface inside the application. Populates all the Mail fields.

-(void)displayComposerSheet

{

MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];

picker.mailComposeDelegate = self;

[picker setSubject:@”Hello from Ankit Vyas!”];

// Set up recipients

NSArray *toRecipients = [NSArray arrayWithObject:@”first@example.com”];

NSArray *ccRecipients = [NSArray arrayWithObjects:@”second@example.com”, @”third@example.com”, nil];

NSArray *bccRecipients = [NSArray arrayWithObject:@”fourth@example.com”];

[picker setToRecipients:toRecipients];

[picker setCcRecipients:ccRecipients];

[picker setBccRecipients:bccRecipients];

// Attach an image to the email

NSString *path = [[NSBundle mainBundle] pathForResource:@”rainy” ofType:@”png”];

NSData *myData = [NSData dataWithContentsOfFile:path];

// Fill out the email body text

NSString *emailBody = @”It is raining in sunny California!”;

[picker setMessageBody:emailBody isHTML:NO];

[self presentModalViewController:picker animated:YES];

[picker release];

}

// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.

– (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error

{

message.hidden = NO;

// Notifies users about errors associated with the interface

switch (result)

{

case MFMailComposeResultCancelled:

message.text = @”Result: canceled”;

break;

case MFMailComposeResultSaved:

message.text = @”Result: saved”;

break;

case MFMailComposeResultSent:

message.text = @”Result: sent”;

break;

case MFMailComposeResultFailed:

message.text = @”Result: failed”;

break;

default:

message.text = @”Result: not sent”;

break;

}

[self dismissModalViewControllerAnimated:YES];

}

#pragma mark –

#pragma mark Workaround

// Launches the Mail application on the device.

-(void)launchMailAppOnDevice

{

NSString *recipients = @”mailto:first@example.com?cc=second@example.com,third@example.com&subject=Hello from California!”;

NSString *body = @”&body=It is raining in sunny California!”;

NSString *email = [NSString stringWithFormat:@”%@%@”, recipients, body];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];

}

#pragma mark –

{

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

self.message = nil;

}

#pragma mark –

#pragma mark Memory management

– (void)dealloc

{

[message release];

[super dealloc];

}

for more detail Grab the Code From Here