Maximum number of Background threads
performSelectorInBackgroundhttp://stackoverflow.com/questions/1447416/maximum-thread-limit
This page on the Mac Dev Center gives you thread allocation costs, which you can make an estimated guess from:
1kb kernel cost
1mb stack space on iPhone
Creation time 90 microseconds
The guide suggests you will be asking the OS to allocate your app 50mb of 128mb of ram if you spawn 50 threads:
The space for this memory is set aside in your process space at thread creation time, but the actual pages associated with that memory are not created until they are needed
That seems like a large amount - and this blog post goes in some detail in saying that if you're trying to use over 46mb of ram your app will freeze, and then be killed 5-10 seconds later by the OS.
So really 15-20 threads is a safe amount to stick to, but of course that depends on how much memory each thread is consuming in the operations it performs, and also how fast the thread completes. The memory is deallocated once the thread finishes.
According to what you find on the net the iPhone has a total memory size of 128 MB and your application should not use more than 46MB of it. But what happens exactly when you try to obtain more?
This page on the Mac Dev Center gives you thread allocation costs, which you can make an estimated guess from:
1kb kernel cost
1mb stack space on iPhone
Creation time 90 microseconds
The guide suggests you will be asking the OS to allocate your app 50mb of 128mb of ram if you spawn 50 threads:
The space for this memory is set aside in your process space at thread creation time, but the actual pages associated with that memory are not created until they are needed
That seems like a large amount - and this blog post goes in some detail in saying that if you're trying to use over 46mb of ram your app will freeze, and then be killed 5-10 seconds later by the OS.
So really 15-20 threads is a safe amount to stick to, but of course that depends on how much memory each thread is consuming in the operations it performs, and also how fast the thread completes. The memory is deallocated once the thread finishes.
According to what you find on the net the iPhone has a total memory size of 128 MB and your application should not use more than 46MB of it. But what happens exactly when you try to obtain more?
You tube APIs
Parameter q would determine the results serach string
http://gdata.youtube.com/feeds/api/videos?q=i%20will%20sing%20don%20moen&orderby=relevance&v=2&start-index=1&max-results=50
Core animation Fun
Exploring CA 360
Shape_05 Example - https://github.com/joericioppo/Shape_05
Creating a CALayer with shape - Pentagon
pentagonPath = CGPathCreateMutable();
CGPoint center = self.view.center;
CGPathMoveToPoint(pentagonPath, nil, center.x, center.y - 75.0);
for(int i = 1; i < 5; ++i)
{
CGFloat x = - 75.0 * sinf(i * 2.0 * M_PI / 5.0);
CGFloat y = - 75.0 * cosf(i * 2.0 * M_PI / 5.0);
CGPathAddLineToPoint(pentagonPath, nil,center.x + x, center.y + y);
}
CGPathCloseSubpath(pentagonPath); //This screws everything up.
Creating a Layer
shapeLayer = [CAShapeLayerlayer];
shapeLayer.path = pentagonPath;
UIColor *fillColor = [UIColor colorWithWhite:0.9 alpha:1.0];
shapeLayer.fillColor = fillColor.CGColor;
//shapeLayer.contents = [UIImage imageNamed:@"test.png"];
shapeLayer.fillRule = kCAFillRuleNonZero;
[rootLayeraddSublayer:shapeLayer];
Shape_05 Example - https://github.com/joericioppo/Shape_05
Creating a CALayer with shape - Pentagon
pentagonPath = CGPathCreateMutable();
CGPoint center = self.view.center;
CGPathMoveToPoint(pentagonPath, nil, center.x, center.y - 75.0);
for(int i = 1; i < 5; ++i)
{
CGFloat x = - 75.0 * sinf(i * 2.0 * M_PI / 5.0);
CGFloat y = - 75.0 * cosf(i * 2.0 * M_PI / 5.0);
CGPathAddLineToPoint(pentagonPath, nil,center.x + x, center.y + y);
}
CGPathCloseSubpath(pentagonPath); //This screws everything up.
Creating a Layer
shapeLayer = [CAShapeLayerlayer];
shapeLayer.path = pentagonPath;
UIColor *fillColor = [UIColor colorWithWhite:0.9 alpha:1.0];
shapeLayer.fillColor = fillColor.CGColor;
//shapeLayer.contents = [UIImage imageNamed:@"test.png"];
shapeLayer.fillRule = kCAFillRuleNonZero;
[rootLayeraddSublayer:shapeLayer];
Adding aUITableView to scroll faster
http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/
Use Custom cells for tables
Use Custom cells for tables
Adding button with Image
Button and Image could be tricky
Needs to be setBackground image and for title use
setTitle:kShazamButtonTextSetUpCompleteforState
UIImage *image = [UIImage imageNamed:@"buy.png"] ;
UIButton *sharedConnectButton = [[UIButton alloc] initWithFrame:CGRectMake(cell.contentView.frame.size.width - image.size.width - PADDING_SPACE_RIGHT,
kSharedRowHeightFBNotConnected - image.size.height - PADDING_BUTTON_HEIGHT,
image.size.width, image.size.height)];
[sharedConnectButton setBackgroundImage:image forState:UIControlStateNormal];
[sharedConnectButton setTitle:kButtonTextSetUpCompleteforState:UIControlStateNormal];
sharedConnectButton.titleLabel.font = [UIFont systemFontOfSize:12];
sharedConnectButton.tag = SHARED_LOGINBUTTON_TAG;
sharedConnectButton.titleLabel.textColor = [UIColor whiteColor];
[sharedConnectButton addTarget:selfaction:@selector(gotoFriendsTab:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:sharedConnectButton];
[sharedConnectButton release];
Trimming string
NSString*string=@" spaces in front and at the end ";NSString*trimmedString =[string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
Array saving t0 plist and retrieving plist
Retrieving from Temp Directory
NSString *plistPath = [NSTemporaryDirectory()stringByAppendingPathComponent:@"friendsList.plist"];
NSMutableArray *data = [[NSMutableArrayalloc] initWithContentsOfFile:plistPath];
Saving to file
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"friendsList.plist"];
[friendsList writeToFile:path atomically:YES];
Reading from a text file into a NSArray
NSArray*wordListArray =[[NSArray alloc] initWithArray:[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@”myStringsFile” ofType:@”txt”]
encoding:NSMacOSRomanStringEncoding error:NULL] componentsSeparatedByString:@”\n”]];
encoding:NSMacOSRomanStringEncoding error:NULL] componentsSeparatedByString:@”\n”]];
UIScrollView Madness
Excellent resource for scrolling - Paging - Pinch and Zoom,https://github.com/andreyvit/ScrollingMadness/
Graph API FaceBook connect
Reference
https://github.com/facebook/facebook-ios-sdk ---- SDK
https://github.com/facebook/facebook-ios-sdk/wiki --- upgrading info
http://developers.facebook.com/docs/api
Get my Info
https://graph.facebook.com/me?access_token=247904832531|092a01a4e57e8b5
Get my friends list
https://graph.facebook.com/me/friends?access_token=247904832531|092a01a4e57e8b5983fb2
{ "data": [ { "name": "Vikram ", "id": "42683" }, { "name": "Dell Joseph", "id": "502440" }, { "name": "Ad Jeriel", "id": "5107414" },
}
Get my friends Picture
https://graph.facebook.com/ID/picture?access_token=247904832531|
Get collective Info - From Id
https://graph.facebook.com/502788440?fields=id,name,picture
e.g{ "id": "502788440", "name": "Dell Joseph", "picture": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/41417_502788440_q.jpg" }
Get the friends list with their picture
https://graph.facebook.com/me/friends?fields=id,name,picture&access_token=asdf
{ "data": [ { "id": "426383", "name": "Vikram", "picture": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs455.snc4/49911_426383_64.jpg" }, { "id": "502788440", "name": "Dell Joseph", "picture": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs323.snc4/41417_50278844_q.jpg" }, }
Delegates - For retrieving the data from FB. eg. name , email. etc
Using delegates extensively - could result in crash - Specially login- logout sequences are repeated
make sure you set their delegates to nil before you deallocate the delegate.
Using multiple level of permissions could be useful in app
Single sign-on issue for facebook - From application - we can use the single sign on - Fb app launches. eg. Path app.
Post to wall Stream.publish
-(void)postMessageToWallWithTitle:(NSString*)msg withBody:(NSString*)body andLinks:(NSArray*)links {
SBJSON *jsonWriter = [[SBJSON alloc] init];
NSString *link = [NSString stringWithString:@"http://www.shazam.com"];
NSString *pictureLink = [NSString stringWithString:@"http://www.shazam.com/music/images/icons/facebook_badge.png"];
NSArray* media = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:
@"image",@"type",pictureLink,
@"src",SHLocalizedString(@"SocialLinkiPhone",""),@"href",nil],nil];
NSArray* actionsDict = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:
@"Get shazam",@"text",
pictureLink,@"href",nil],nil];
//NSString *description = [NSString stringWithString:@"Test this I just setup Shazam Friends making it easy to share Tags. Download the latest version of Shazam to instantly share tagged music."];
NSDictionary *attachmentDict = [NSDictionary dictionaryWithObjectsAndKeys:
msg,@"name",link,@"caption",link,@"href",
media,@"media",body,@"description",nil];
DLog(@"Attachment %@",attachmentDict);
NSString *attachmentStr = [jsonWriter stringWithObject:attachmentDict];
NSString *actionsStr = [jsonWriter stringWithObject:actionsDict];
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
attachmentStr,@"attachment",
actionsStr,@"action_links", nil];
[_facebook requestWithMethodName:@"stream.publish"
andParams:params
andHttpMethod:@"POST"
andDelegate:self];
[jsonWriter release];
Fixing Concurrency issues
Multiple set of operations happening at the same time is know as concurrency.
Objective to keep the interface responsive when processing some task
Eg - Parsing and updating the interface
listening on multiple ports
asychronously retrieving data from different sources.
Solution - More Iphone 3
Using Batch Timers
Using NSOperation Queues
Timers
1) Trigger the Batch processing- Break down your work in smaller chunks
#define kTimerInterval 1.0/10.0 - Ten times a second
[NSTimer scheduledTimerWithTimeInterval:kTimerInterval
target:self
selector:@selector(processChunk:)
userInfo:batch
repeats:YES];
2) Cycle through chunk
Instance of Timer called - hence the timer argument
- (void)processChunk:(NSTimer *)timer {
if (!processRunning) { // Cancelled
[timer invalidate];
progressLabel.text = @"Calculations Cancelled";
return;
}
SquareRootBatch *batch = (SquareRootBatch *)[timer userInfo];
NSTimeInterval endTime = [NSDate timeIntervalSinceReferenceDate] + (kTimerInterval / 2.0);
BOOL isDone = NO;
while ([NSDate timeIntervalSinceReferenceDate] < endTime && (!isDone)) {
for (int i = 0; i < kBatchSize; i++) {
if (![batch hasNext]) {
isDone = YES;
i = kBatchSize;
}
else {
NSInteger current = batch.current;
double nextSquareRoot = [batch next];
NSLog(@"Calculated square root of %d as %0.3f", current, nextSquareRoot);
}
}
}
progressLabel.text = [batch percentCompletedText];
progressBar.progress = [batch percentCompleted];
if (isDone) {
[timer invalidate];
processRunning = NO;
progressLabel.text = @"Calculations Finished";
[goStopButtonsetTitle:@"Go"forState:UIControlStateNormal];
}
}
NSOperationQueues
Using POSIX threads - pthreads NSThreads are generally used. NSOperationQueues make life easier
All applications has 1 thread- main thread
Problems - Race condition - multiple threads changing the contents of the object to give different results.
using mutex- mutual exclusion semaphore - solution to Race Condition.
@synchronised(self){
My safe code
}
a) Handle exceptions
b) Each thread should have its own autorelease pools
c) Dependencies could be added to NSoperations
Objective to keep the interface responsive when processing some task
Eg - Parsing and updating the interface
listening on multiple ports
asychronously retrieving data from different sources.
Solution - More Iphone 3
Using Batch Timers
Using NSOperation Queues
Timers
1) Trigger the Batch processing- Break down your work in smaller chunks
#define kTimerInterval 1.0/10.0 - Ten times a second
[NSTimer scheduledTimerWithTimeInterval:kTimerInterval
target:self
selector:@selector(processChunk:)
userInfo:batch
repeats:YES];
2) Cycle through chunk
Instance of Timer called - hence the timer argument
- (void)processChunk:(NSTimer *)timer {
if (!processRunning) { // Cancelled
[timer invalidate];
progressLabel.text = @"Calculations Cancelled";
return;
}
SquareRootBatch *batch = (SquareRootBatch *)[timer userInfo];
NSTimeInterval endTime = [NSDate timeIntervalSinceReferenceDate] + (kTimerInterval / 2.0);
BOOL isDone = NO;
while ([NSDate timeIntervalSinceReferenceDate] < endTime && (!isDone)) {
for (int i = 0; i < kBatchSize; i++) {
if (![batch hasNext]) {
isDone = YES;
i = kBatchSize;
}
else {
NSInteger current = batch.current;
double nextSquareRoot = [batch next];
NSLog(@"Calculated square root of %d as %0.3f", current, nextSquareRoot);
}
}
}
progressLabel.text = [batch percentCompletedText];
progressBar.progress = [batch percentCompleted];
if (isDone) {
[timer invalidate];
processRunning = NO;
progressLabel.text = @"Calculations Finished";
[goStopButtonsetTitle:@"Go"forState:UIControlStateNormal];
}
}
NSOperationQueues
Using POSIX threads - pthreads NSThreads are generally used. NSOperationQueues make life easier
All applications has 1 thread- main thread
Problems - Race condition - multiple threads changing the contents of the object to give different results.
using mutex- mutual exclusion semaphore - solution to Race Condition.
@synchronised(self){
My safe code
}
a) Handle exceptions
b) Each thread should have its own autorelease pools
c) Dependencies could be added to NSoperations
Force Lanscape only rendering of MPMovieplayerViewController
Certain videos whould like to forced into landscape only mode
Inherit Movie player into a custom Movieplayer Controller and
http://efreedom.com/Question/1-3310909/MPMoviePlayerViewController-Issue-Movie-Finishes
Registering NSUserDefaults - Settings.bundle
Happen to implement the settings bundle - After settings fields is setup in the bundle the values - needs to be registered so that you are able to read them into the app
A good reference is
http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the-s
on how to register the fields in the app once loaded
A good reference is
http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the-s
on how to register the fields in the app once loaded
Apple Submission headache (BC)
Lost my distribution key
Rescue - Recreate the profiles
http://stackoverflow.com/questions/1410156/lost-private-key-for-iphone-distribution-certificate-what-could-be-solutions
Application Loader errors - Code sign Error
-> Only Team agents can sign and submit the build
->Distribution Certificate needs to be requested.
-> Common Name should match with the Distribution profile name.
-> Distribution Private key needs match with the certificate name.
Understanding Core data
Wrapper for Sqllite
XcdataModel files allows you to create entities and attributes and relationships needed in for storage of files
Good tutorial with code to start with.
http://blog.sallarp.com/iphone-core-data-uitableview-drill-down/
This is a sample core data example with County -Province -City entities and 1-M relationships
Few 1- M
http://pragprog.com/titles/mzcd/source_code
IphoneCoreDataRecipies
/// Good Example of Tabbar +Core data
// Also contains good references to TableviewCell Custom types.
http://developer.apple.com/iphone/library/samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html
Benefits of using Core Data
biggest benefits you can gain by using Core Data is the lazy loading of data and the faulting to save on memory. So you need to also think about things like this when you are considering performance as the amount of free memory you have will also impact performance.
XcdataModel files allows you to create entities and attributes and relationships needed in for storage of files
Good tutorial with code to start with.
http://blog.sallarp.com/iphone-core-data-uitableview-drill-down/
This is a sample core data example with County -Province -City entities and 1-M relationships
Few 1- M
http://pragprog.com/titles/mzcd/source_code
IphoneCoreDataRecipies
/// Good Example of Tabbar +Core data
// Also contains good references to TableviewCell Custom types.
http://developer.apple.com/iphone/library/samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html
Benefits of using Core Data
biggest benefits you can gain by using Core Data is the lazy loading of data and the faulting to save on memory. So you need to also think about things like this when you are considering performance as the amount of free memory you have will also impact performance.
Core Data Concepts
Managed Objects and the Managed Object Context
A managed object is an instance of NSManagedObject or of a subclass of NSManagedObject. Conceptually, it’s an object representation of a record in a table in a database, so it’s a model (in the sense of the model-view-controller design pattern) object that is managed by Core Data. Managed objects represent the data you operate on in your application—for example departments and employees in a human resources application; shapes, text areas, and groups in a drawing application; albums, artists, and tracks in a music management application. A managed object is always associated with a managed object context.
The managed object context is an instance of NSManagedObjectContext. A context represents a single object space, or scratch pad, in an application. Its primary responsibility is to manage a collection of managed objects. These objects form a group of related model objects that represent an internally consistent view of one or more persistent stores. The context is a powerful object with a central role in your application, with responsibilities from life-cycle management to validation, relationship maintenance, and undo/redo.
When you create a new managed object, you insert it into a context. You fetch existing records in the database into the context as managed objects. (Fetching is discussed in greater detail in “Fetching Events.”) Any changes you make (whether insertion or deletion of complete objects, or manipulation of property values) are kept in memory until you actually commit them to the store by saving the context.
The Managed Object ModelA managed object model is an instance of NSManagedObjectModel. It’s an object representation of a schema that describes your database, and so the managed objects you use in your application. A model is a collection of entity description objects (instances ofNSEntityDescription). An entity description describes an entity (a table in a database) in terms of its name, the name of the class used to represent the entity in your application, and what properties (attributes and relationships) it has.
You typically create the managed object model graphically using Xcode's Data Model Design tool.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/CoreData/Articles/cdBasics.html
Test the data changes you have made to the persistent store by checking the contents of the sqlite
Use commads
1) sqlite3 filename.sqlite
2) .dump
A managed object is an instance of NSManagedObject or of a subclass of NSManagedObject. Conceptually, it’s an object representation of a record in a table in a database, so it’s a model (in the sense of the model-view-controller design pattern) object that is managed by Core Data. Managed objects represent the data you operate on in your application—for example departments and employees in a human resources application; shapes, text areas, and groups in a drawing application; albums, artists, and tracks in a music management application. A managed object is always associated with a managed object context.
The managed object context is an instance of NSManagedObjectContext. A context represents a single object space, or scratch pad, in an application. Its primary responsibility is to manage a collection of managed objects. These objects form a group of related model objects that represent an internally consistent view of one or more persistent stores. The context is a powerful object with a central role in your application, with responsibilities from life-cycle management to validation, relationship maintenance, and undo/redo.
When you create a new managed object, you insert it into a context. You fetch existing records in the database into the context as managed objects. (Fetching is discussed in greater detail in “Fetching Events.”) Any changes you make (whether insertion or deletion of complete objects, or manipulation of property values) are kept in memory until you actually commit them to the store by saving the context.
The Managed Object ModelA managed object model is an instance of NSManagedObjectModel. It’s an object representation of a schema that describes your database, and so the managed objects you use in your application. A model is a collection of entity description objects (instances ofNSEntityDescription). An entity description describes an entity (a table in a database) in terms of its name, the name of the class used to represent the entity in your application, and what properties (attributes and relationships) it has.
You typically create the managed object model graphically using Xcode's Data Model Design tool.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/CoreData/Articles/cdBasics.html
Test the data changes you have made to the persistent store by checking the contents of the sqlite
Use commads
1) sqlite3 filename.sqlite
2) .dump
Search Bar Delegate
Search a string in the search string
NSComparisonResult result = [[dict objectForKey:@"subject"]
compare:searchText options:(NSCaseInsensitiveSearch)
range:[[dict objectForKey:@"subject"] rangeOfString:searchText
options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)]];
if (result == NSOrderedSame)
{
[self.filteredListContentaddObject:dict];
}
NSComparisonResult result = [[dict objectForKey:@"subject"]
compare:searchText options:(NSCaseInsensitiveSearch)
range:[[dict objectForKey:@"subject"] rangeOfString:searchText
options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)]];
if (result == NSOrderedSame)
{
[self.filteredListContentaddObject:dict];
}
Alert View with Prompt
Discussion
The arguments to the block are two objects to compare. The block returns an NSComparisonResult
value to denote the ordering of the two objects.
You use NSComparator
blocks in comparison operations such as NSArray
’s sortedArrayUsingComparator:
, for example:
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) { |
if ([obj1 integerValue] > [obj2 integerValue]) { |
return (NSComparisonResult)NSOrderedDescending; |
} |
if ([obj1 integerValue] < [obj2 integerValue]) { |
return (NSComparisonResult)NSOrderedAscending; |
} |
return (NSComparisonResult)NSOrderedSame; |
}]; |
Availability
- Available in iPhone OS 4.0 and later.
Declared In
NSObjCRuntime.h
Relative Date Year. months Ago
+(NSString*) relativeDifference:(NSDate*)relativeDate
{
NSDate *now = [NSDate date];
double ti = [relativeDate timeIntervalSinceDate:now];
NSString *relativeString = nil;
//$delta = time() - $time;
ti = ti * -1;
if (ti < 1 * MINUTE)
{
relativeString = [NSString stringWithFormat:@"%d seconds ago",ti];
return relativeString;//ti == 1 ? "one second ago" : " seconds ago";
}
if (ti < 2 * MINUTE)
{
relativeString = [NSString stringWithFormat:@"a minute ago"];
return relativeString;
}
if (ti < 45 * MINUTE)
{
relativeString = [NSString stringWithFormat:@"%d a minute ago",floor(ti / MINUTE)];
return relativeString;
}
if (ti < 90 * MINUTE)
{
relativeString = [NSString stringWithFormat:@"an hour ago"];
return relativeString;
}
if (ti < 24 * HOUR)
{
relativeString = [NSString stringWithFormat:@"%d hours ago",floor(ti / HOUR)];
return relativeString;
}
if (ti < 48 * HOUR)
{
relativeString = [NSString stringWithFormat:@"yesterday"];
return relativeString;
}
if (ti < 30 * DAY)
{
relativeString = [NSString stringWithFormat:@" %d days ago",floor(ti / DAY)];
return relativeString;
}
if (ti < 12 * MONTH)
{
int months = floor(ti / (DAY *30));
if(months <= 1)
relativeString = [NSString stringWithFormat:@" one month ago"];
else
relativeString = [NSString stringWithFormat:@"%d months ago",months];
return relativeString;
}
else
{
int years = floor(ti / (DAY * 365));
//return years <= 1 ? "one year ago" : years . " years ago";
if(years <= 1)
relativeString = [NSString stringWithFormat:@" one year ago"];
else
relativeString = [NSString stringWithFormat:@" years ago",years];
return relativeString;
}
return relativeString;
}
Playing with AVAudioRecorder
AVAudioRecorder is a simple solution to do the recording of sound in iphone. easy to implement.
There are other options like the SpeakHere example which is more crude form with AQPlayer user.
The data recorded file is saved in NSUrl whcih which could be further coverted to NSData - initWithContents of File
I needed the NSData - raw bytes which could be base64 encoded and posted as attribute of the a Webserver - JSON for example.
http://stackoverflow.com/questions/2149280/proper-avaudiorecorder-settings-for-recording-voice
recorderSettingsDict=[[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatAppleIMA4],AVFormatIDKey,
[NSNumber numberWithInt:44100.0],AVSampleRateKey,
[NSNumber numberWithInt:2],AVNumberOfChannelsKey,
[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
nil];
You'll want to read the iPhone Application Programming Guide section titled Using Sound in iPhone OS, and the Audio Queue Services Programming Guide.
Most sounds in human voices are in the middle range of human hearing. Recorded speech is easily understood even when digitized with very low data rates. You can stomp all over a voice recording, yet still have a useful file. Therefore, your ultimate use for these recordings will guide your decisions on these settings.
First you need to choose the audio format. Your choice will be determined by what you want to do with the audio after you record it. Your current choice is IMA4. Maybe you'll want a different format, but IMA4 is a good choice for the iPhone. It's a fast encoding scheme, so it won't be too taxing for the limited iPhone processor, and it supplies 4:1 compression, so it won't take up too much storage space. Depending upon the format you choose, you'll want to make further settings.
Your current sample rate, 44.1 kHz, is the same as the standard for CD audio. Unless you're after a high fidelity recording, you don't need this high of a rate, but you don't want to use arbitrary rates. Most audio software can only understand rates at specific steps like 32 kHz, 24 kHz, 16 kHz, or 12 kHz.
Your number of channels is set to 2, for stereo. Unless your using additional hardware, the iPhone only has one microphone, and 1 mono channel should be sufficient. This cuts your data needs in half.
The three Linear PCM settings you are using seem to be just for Linear PCM format recordings. I think they have no effect in your code, since you are using the IMA4 format. I don't know the IMA4 format well enough to tell you which settings you'll need to make, so you'll have to do some additional research if you decide to continue using that setting.
There are other options like the SpeakHere example which is more crude form with AQPlayer user.
The data recorded file is saved in NSUrl whcih which could be further coverted to NSData - initWithContents of File
I needed the NSData - raw bytes which could be base64 encoded and posted as attribute of the a Webserver - JSON for example.
http://stackoverflow.com/questions/2149280/proper-avaudiorecorder-settings-for-recording-voice
recorderSettingsDict=[[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatAppleIMA4],AVFormatIDKey,
[NSNumber numberWithInt:44100.0],AVSampleRateKey,
[NSNumber numberWithInt:2],AVNumberOfChannelsKey,
[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
nil];
You'll want to read the iPhone Application Programming Guide section titled Using Sound in iPhone OS, and the Audio Queue Services Programming Guide.
Most sounds in human voices are in the middle range of human hearing. Recorded speech is easily understood even when digitized with very low data rates. You can stomp all over a voice recording, yet still have a useful file. Therefore, your ultimate use for these recordings will guide your decisions on these settings.
First you need to choose the audio format. Your choice will be determined by what you want to do with the audio after you record it. Your current choice is IMA4. Maybe you'll want a different format, but IMA4 is a good choice for the iPhone. It's a fast encoding scheme, so it won't be too taxing for the limited iPhone processor, and it supplies 4:1 compression, so it won't take up too much storage space. Depending upon the format you choose, you'll want to make further settings.
Your current sample rate, 44.1 kHz, is the same as the standard for CD audio. Unless you're after a high fidelity recording, you don't need this high of a rate, but you don't want to use arbitrary rates. Most audio software can only understand rates at specific steps like 32 kHz, 24 kHz, 16 kHz, or 12 kHz.
Your number of channels is set to 2, for stereo. Unless your using additional hardware, the iPhone only has one microphone, and 1 mono channel should be sufficient. This cuts your data needs in half.
The three Linear PCM settings you are using seem to be just for Linear PCM format recordings. I think they have no effect in your code, since you are using the IMA4 format. I don't know the IMA4 format well enough to tell you which settings you'll need to make, so you'll have to do some additional research if you decide to continue using that setting.
Setting a Badge Number
Setting a badge on the Tab bar view
UITabBar *tb = self.tabBarController.tabBar;
UITabBarItem *tbi = [tb.items objectAtIndex:0];
/// Set the badge for the unread messages count
if(needsDisplay)
{
[[UIApplicationsharedApplication] setApplicationIconBadgeNumber:5];
//set the badge
tbi.badgeValue = [NSString stringWithFormat:@"%@",[resultDict objectForKey:kUnreadCount]];
}
else {
[[UIApplicationsharedApplication] setApplicationIconBadgeNumber:0];
tbi.badgeValue = nil;
}
Setting a a badge on the Application is quite easy - with a one line code you can do it.
[[UIApplicationsharedApplication] setApplicationIconBadgeNumber:5];
Setting it to 0 will cause no badge to be displayed
UITabBar *tb = self.tabBarController.tabBar;
UITabBarItem *tbi = [tb.items objectAtIndex:0];
/// Set the badge for the unread messages count
if(needsDisplay)
{
[[UIApplicationsharedApplication] setApplicationIconBadgeNumber:5];
//set the badge
tbi.badgeValue = [NSString stringWithFormat:@"%@",[resultDict objectForKey:kUnreadCount]];
}
else {
[[UIApplicationsharedApplication] setApplicationIconBadgeNumber:0];
tbi.badgeValue = nil;
}
Setting a a badge on the Application is quite easy - with a one line code you can do it.
[[UIApplicationsharedApplication] setApplicationIconBadgeNumber:5];
Setting it to 0 will cause no badge to be displayed
Reloading the parent View each time you load
There might be cased when you want page to reload each time you visit this page.
Eg in the navigation Controller - Reload the parent page each time you come back from the child view controller page.
Implement this function-(void) viewWillAppear:(BOOL)animated {
NSLog(@"VIEW WIll APPEAR Called");
/// Load the content you want each time you load the page
}
Clickable UILabels
http://furbo.org/2008/10/07/fancy-uilabels/
Retrieving button pressed
-(IBAction) editButtonPressed:(id)sender
{
UITableViewCell *cellAux=(UITableViewCell*)[[sender superview] superview];
UITableView *table=(UITableView*)[cellAux superview];
NSIndexPath *path=[table indexPathForCell:cellAux];
NSLog(@"been pressed %d si %d",path.section, path.row);
}
{
UITableViewCell *cellAux=(UITableViewCell*)[[sender superview] superview];
UITableView *table=(UITableView*)[cellAux superview];
NSIndexPath *path=[table indexPathForCell:cellAux];
NSLog(@"been pressed %d si %d",path.section, path.row);
}
Basic HTTP Authentication with RESTful Rails app
Forcing HTTP Basic Authentication on the iPhone
http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/248
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *authString = [Base64 encode:[[NSString stringWithFormat:@"%@:%@",[url user], [url password]] dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:[NSString stringWithFormat:@"Basic %@", authString] forHTTPHeaderField:@"Authorization"];
return [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
This method needs to be implemented to receive the authentication challenge and do Basic authentication webservices
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { NSLog(@"got auth challange"); if ([challenge previousFailureCount] == 0) { [[challenge sender] useCredential:[NSURLCredential credentialWithUser:[usernameTextField text] password:[passwordTextField text] persistence:NSURLCredentialPersistenceForSession] forAuthenticationChallenge:challenge]; } else { [[challenge sender] cancelAuthenticationChallenge:challenge]; } }
http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/248
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *authString = [Base64 encode:[[NSString stringWithFormat:@"%@:%@",[url user], [url password]] dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:[NSString stringWithFormat:@"Basic %@", authString] forHTTPHeaderField:@"Authorization"];
return [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
This method needs to be implemented to receive the authentication challenge and do Basic authentication webservices
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { NSLog(@"got auth challange"); if ([challenge previousFailureCount] == 0) { [[challenge sender] useCredential:[NSURLCredential credentialWithUser:[usernameTextField text] password:[passwordTextField text] persistence:NSURLCredentialPersistenceForSession] forAuthenticationChallenge:challenge]; } else { [[challenge sender] cancelAuthenticationChallenge:challenge]; } }
RESTFUL webservices.
http://developer.apple.com/safari/articles/creatingrestfulclients.html
The Emergence of REST
At the same time as SOAP was becoming established as the standard protocol for traditional web services, another movement was gaining acceptance, based on the published dissertation of Roy Fielding, one of the principal authors of the HTTP specification. Fielding’s dissertation, published in 2000, introduced the term “REST”, which is a quasi-acronym that stands for REpresentational State Transfer.
The RESTful CommandsRESTful web services provide data using exactly the same protocol as the World Wide Web. In fact, most of the web sites that you visit on a daily basis are RESTful web services and Safari can accurately be called a RESTful web service client.
There are four basic commands that RESTful web services can implement, which, not by coincidence, are all part of the HTTP 1.1 specification. The commands are GET, POST, PUT, and DELETE.
The Emergence of REST
At the same time as SOAP was becoming established as the standard protocol for traditional web services, another movement was gaining acceptance, based on the published dissertation of Roy Fielding, one of the principal authors of the HTTP specification. Fielding’s dissertation, published in 2000, introduced the term “REST”, which is a quasi-acronym that stands for REpresentational State Transfer.
There are four basic commands that RESTful web services can implement, which, not by coincidence, are all part of the HTTP 1.1 specification. The commands are GET, POST, PUT, and DELETE.
Parsing string to date - rails format
NSDateFormatter* dateFormatter =[[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
date =[dateFormatter dateFromString:dateStr];
Read More
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
date =[dateFormatter dateFromString:dateStr];
Read More
Scrolling for TableView - with TextFields
UseFul Link
http://stackoverflow.com/questions/594181/uitableview-and-keyboard-scrolling-problem
Shifting of the table works beautifully here
-(void) textFieldDidBeginEditing:(UITextField*)textField {
UITableViewCell*cell =(UITableViewCell*)[[textField superview] superview];
[tView scrollToRowAtIndexPath:[tView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];}
Reading Txt file into an NSArray
Sample File lines
London #(GMT +0:0) London Time Zone
Paris #(GMT +1:0) Paris Time Zone
/// Separating the components First by line(/n) and then by the ' #' string
NSArray *listArray = [[NSArray alloc] initWithArray:
[[NSStringstringWithContentsOfFile:[[NSBundlemainBundle] pathForResource:@"TimeZoneFullList"ofType:@"txt"]
encoding:NSMacOSRomanStringEncoding error:NULL] componentsSeparatedByString:@"\n"]];
timeZoneValuePart = [[NSMutableArray alloc] init];
timeZoneDisplayPart = [[NSMutableArray alloc] init];
for(NSString *timeZone in listArray)
{
NSArray *rowElements = [timeZone componentsSeparatedByString:@" #"];
if ([rowElements count] != 2) continue;
[self.timeZoneValuePart addObject:[rowElements objectAtIndex:0]];
[self.timeZoneDisplayPart addObject:[rowElements objectAtIndex:1]];
}
[listArray release];
}
JSON Post Message
Sending a Request to a un- secure Call
NSString *requestURL = @"http://staging.com/api/v1/users.json";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestURL]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json"forHTTPHeaderField:@"Content-Type"];
requestDictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *subDict = [[NSMutableDictionaryalloc] init];
// {"user":{"full_name":"Name", "time_zone":"Someplace", "password":"secret", "email":"[email protected]"}}
[subDict setObject:[NSString stringWithString:@"Jidh Test"] forKey:@"full_name"];
[subDict setObject:[NSStringstringWithString:@"London"] forKey:@"time_zone"];
[subDict setObject:password forKey:@"password"];
[subDict setObject:emailAddress forKey:@"email"];
[requestDictionary setObject:subDict forKey:@"user"];
NSString *theBodyString = requestDictionary.JSONRepresentation;
NSLog(@"%@",theBodyString);
NSData *theBodyData = [theBodyString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:theBodyData];
[[NSURLConnectionalloc] initWithRequest:request delegate:self];
/// Get the response
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSStringalloc] initWithData:responseDataencoding:NSUTF8StringEncoding];
NSLog(@" String %@",responseString);
[responseDatarelease];
NSError *error;
SBJSON *json = [[SBJSON new] autorelease];
NSDictionary *dictionary = [json objectWithString:responseString error:&error];
[responseString release];
}
Sending a Request to a Secure Call - https
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
// if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
// if ([trustedHosts containsObject:challenge.protectionSpace.host])
[challenge.sender useCredential:[NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space {
if([[space authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if(1) {
returnYES; // Self-signed cert will be accepted
} else {
returnNO; // Self-signed cert will be rejected
}
// Note: it doesn't seem to matter what you return for a proper SSL cert
// only self-signed certs
}
// Otherwise maybe YES for NSURLAuthenticationMethodDefault and etc.
returnNO;
}
OR
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
Loading Custom UITableCell from nib
static NSString *CellIdentifier = @"ProductCell";
static NSString *CellNib = @"cellProduct";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// cell = (UITableViewCell *)[[NSBundle mainBundle] loadNibNamed: CellIdentifier owner: self options: nil];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
//cell = gigCell;
//self.gigCell = nil;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
static NSString *CellNib = @"cellProduct";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// cell = (UITableViewCell *)[[NSBundle mainBundle] loadNibNamed: CellIdentifier owner: self options: nil];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
//cell = gigCell;
//self.gigCell = nil;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
Including the Touch XML Framework
The settings that we are interested in are “Header Search Paths” and “Other Linker Flags”, you can easily find these by typing the beginning of the name into the “Quick Find” at the top right of the window.
You need to add “/usr/include/libxml2″ to the “Header Search Paths” and you need to add “-lxml2″ to the“Other Linker Flags”.
Once you have done this you can close the settings window and you will be back at your project window.
Now that the libxml2 libraries have been included you will need to import the TouchXML files to your project, to do this simply right click on the “Classes” folder in the left hand pane and click Add > Existing Files…
You will be presented with a finder window and you will need to navigate to the location that you checked the TouchXML files out to (in my case it was /Developer/ExtraLibraries/) and then keep going to the following path “touchcode-read-only/TouchXML/Common/Source/” and select all the files and click “Add”. You will be presented with the following screen:
Transparant Table cell
static NSString *CellIdentifier = @"DummyCell";
cell = [self.loginTableViewdequeueReusableCellWithIdentifier: CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
UIView *transparentBackground = [[UIView alloc] initWithFrame:CGRectZero];
transparentBackground.backgroundColor = [UIColor clearColor];
cell.backgroundView = transparentBackground;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell = [self.loginTableViewdequeueReusableCellWithIdentifier: CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
UIView *transparentBackground = [[UIView alloc] initWithFrame:CGRectZero];
transparentBackground.backgroundColor = [UIColor clearColor];
cell.backgroundView = transparentBackground;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
Tab Bar controller and Edit tableView
Generally the first view controller is Tab bar controller - But when you want the first to be navigation controller with the following view controller as the tab bar view controller.
http://www.wiredbob.com/blog/tag/iphone - Good link for the project
Books Eg a very good example for adding a object type Book with editable table control for edit and delete options.. Also Good example for Reordering of the table elements and MV.
http://www.wiredbob.com/blog/tag/iphone - Good link for the project
Books Eg a very good example for adding a object type Book with editable table control for edit and delete options.. Also Good example for Reordering of the table elements and MV.
Transparent Background in UiWebview
Transweb Apple Sample - Nice example to set the background to clear and also applying zoom to the UIWebView.
// to make html content transparent to its parent view -
// 1) set the webview's backgroundColor property to [UIColor clearColor]
// 2) use the content in the html: <body style="background-color: transparent">
// 3) opaque property set to NO
Retrieving TimeZones
// Retrieve the array of known time zone names, then sort the array and pass it to the root view controller.
NSArray *timeZones = [NSTimeZone knownTimeZoneNames];
rootViewController.timeZoneNames = [timeZones sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
Contacts List editing
/// obtain the Array with the contacts from the Address Book
/// Populate the array /// C09 - PeoplePlacesThings
NSMutableArray peopleArray = (NSMutableArray*) ABAddressBookCopyArrayOfAllPeople(ABAddressBookCreate());
//Search through the personArray for the match to the string supplied
NSString *upString = [matchString uppercaseString];
if (searchArray) [searchArrayrelease];
searchArray = [[NSMutableArrayalloc] init];
for (NSString *person in peopleArray)
{
// Add everyone when there's nothing to match to
if ([matchString length] == 0)
{
[searchArray addObject:person];
continue;
}
// Add the person if the string matches
NSRange range = [[[self getName:person] uppercaseString] rangeOfString:upString];
if (range.location != NSNotFound) [searchArray addObject:person];
}
/// From the ABPerson list person obtain the name of the person and other details
//# In getName string is passed and search is done for ABRecordRef.
- (NSString *) getName: (ABRecordRef) person
{
NSString *firstName = [(NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty) autorelease];
NSString *lastName = [(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty) autorelease];
NSString *biz = [(NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty) autorelease];
if ((!firstName) && !(lastName))
{
if (biz) return biz;
return@"[No name supplied]";
}
if (!lastName) lastName = @"";
if (!firstName) firstName = @"";
return [NSString stringWithFormat:@
Network Resrictions applied could cause some features to not work
In one the cases my app was having some problem connecting to the server. Soon realised the problem was withthe problem was that the network was not allowing proper communication between the server and iphoneIn this case Vodafone connection is causing problem to connect to the server.http://www.fir3net.com/iPhone/iPhone/vodafone-iphone-youtubeerror-cannot-play-back-not-supported.html
Orientations
Initially looks simple
should autorotate function takes care of th does the work for you. But it could be quite tricky with the
navigation bars and landscape orientations
One good example of user switching to the landscape
http://strange.bplaced.net/S.T.R.A.N.G.E./WELCOME.html
Portrait on click to landscape view
Using Navbar and setting YES in shouldRotate is better
should autorotate function takes care of th does the work for you. But it could be quite tricky with the
navigation bars and landscape orientations
One good example of user switching to the landscape
http://strange.bplaced.net/S.T.R.A.N.G.E./WELCOME.html
Portrait on click to landscape view
Using Navbar and setting YES in shouldRotate is better
Jumping between the View controller level Stack
There might be cases where the design requires the app to restore the View controller say Level 3 of the navigation stack eg. Map view level 3 directly
Restore the navigation stack to a previous state.
When your application launches, you can use the setViewControllers:animated: method to restore the navigation controller to a previous state. For example, you would use this method to return the user to the same screen they were viewing when they last quit the application.
In order to restore your application to a previous state, you must first save enough state information to recreate the needed view controllers. When the user quits your application, you would need to save some markers or other information indicating the user’s position in your data hierarchy. At the next launch time, you would then read this state information and use it to recreate the needed view controllers before calling the setViewControllers:animated: method.
Say you want to Jump to the root view controller directly from level 4.
There might be cases where the design requires the app to restore the View controller say Level 3 of the navigation stack eg. Map view level 3 directly
Return the user to the root view controller.
To return to the top of your navigation interface, use the popToRootViewControllerAnimated: method. This method removes all but the root view controller from the navigation stack.
Restore the navigation stack to a previous state.
When your application launches, you can use the setViewControllers:animated: method to restore the navigation controller to a previous state. For example, you would use this method to return the user to the same screen they were viewing when they last quit the application.
In order to restore your application to a previous state, you must first save enough state information to recreate the needed view controllers. When the user quits your application, you would need to save some markers or other information indicating the user’s position in your data hierarchy. At the next launch time, you would then read this state information and use it to recreate the needed view controllers before calling the setViewControllers:animated: method.
Say you want to Jump to the root view controller directly from level 4.
There might be cases where the design requires the app to restore the View controller say Level 3 of the navigation stack eg. Map view level 3 directly
Return the user to the root view controller.
To return to the top of your navigation interface, use the popToRootViewControllerAnimated: method. This method removes all but the root view controller from the navigation stack.
Populate the contents of NSArray with text file data
NSArray *crayons = [[NSStringstringWithContentsOfFile:[[NSBundlemainBundle] pathForResource:@"crayons"ofType:@"txt"]] componentsSeparatedByString:@"\n"];
Ref:Coverflow/CookBook
Holding Connections to the server
CFMutableDictionaryRefconnections;
Initalise
connections = CFDictionaryCreateMutable(kCFAllocatorDefault,0,&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
Delegation vs Notification Ways to send messages
Delegation is mainly 1-1 (Bidirectional connection)
Notification is 1- many connection - Broadcasting
Delegation is a way to customise the behaviour of the object without subclassing a class.
Delegating is a good programming practice for many situations.Both delegating and notifications help decouple the view controllers from each other, which is a good thing. Notifications might be a little easier to code and offer the advantage that multiple objects can observe one notification. With delegates, such a thing cannot be one without modifying the delegating object (and is unusual).
Some advantages of delegating:
Implementing a delegate pattern is simple:
Notification is 1- many connection - Broadcasting
Delegation is a way to customise the behaviour of the object without subclassing a class.
Delegating is a good programming practice for many situations.Both delegating and notifications help decouple the view controllers from each other, which is a good thing. Notifications might be a little easier to code and offer the advantage that multiple objects can observe one notification. With delegates, such a thing cannot be one without modifying the delegating object (and is unusual).
Some advantages of delegating:
- The connection between delegating object and delegate is made clearer, especially if implementing the delegate is mandatory.
- If more than one type of message has to be passed from delegatee to delegate, delegating can make this clearer by specifying one delegate method per message. For notifications, you can use multiple notification names but all notifications end up in the same method on the side of the observer (possibly requiring a nasty switch statement).
Implementing a delegate pattern is simple:
- In your ChildViewController.h, declare the delegate protocol that the delegate must implement later:
@protocolChildViewControllerDelegate<NSObject> - @optional-(void)viewControllerDidChange:(ChildViewController*)controller;
- @end
- At the top of the file, create an instance variable to hold the pointer to the delegate in your ChildViewController:
@protocolChildViewControllerDelegate; - @interfaceChildViewController:UIViewController{
id <ChildViewControllerDelegate>delegate;
...} - @property(assign) id <ChildViewControllerDelegate>delegate;...
- @end
- In RootViewController.h, make your class conform to the delegate protocol:
@interfaceRootViewController:UIViewController<ChildViewControllerDelegate>{... - In the RootViewController implementation, implement the delegate method. Also, when you create the ChildViewController instance, you have to assign the delegate.
@implementRootViewController...// in some method: - ChildViewController*controller = [[ChildViewController alloc] initWithNibName:...
controller.delegate=self;... - -(void)viewControllerDidChange:(ChildViewController*)controller {
NSLog(@"Delegate method was called.");}... - In the ChildViewController implementation, call the delegate method at the appropriate time:
@implementationChildViewController...// in some method:if([self.delegate respondsToSelector:@selector(viewControllerDidChange:)]){
[self.delegate viewControllerDidChange:self];}...
When property to be used in case of NSString
For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your @property declaration. Specifying retain is something you almost never want in such a situation.
Here's why you want to do that:
NSMutableString*someName =[NSMutableString stringWithString:@"Chris"];Person*p =[[[Person alloc] init] autorelease];
p.name = someName;[someName setString:@"Debajit"];
The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be @"Debajit" if the property is marked retain, but@"Chris" if the property is marked copy.
Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using@synthesize you should remember to actually use copy instead of retain in it.)
Here's why you want to do that:
NSMutableString*someName =[NSMutableString stringWithString:@"Chris"];Person*p =[[[Person alloc] init] autorelease];
p.name = someName;[someName setString:@"Debajit"];
The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be @"Debajit" if the property is marked retain, but@"Chris" if the property is marked copy.
Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using@synthesize you should remember to actually use copy instead of retain in it.)
UiTextView and UiTextField
There are some important functions that are needed to for better formatting the text
Eg Fot TextField
- (void)textFieldDidBeginEditing:(UITextField *)textField;
- (void)textFieldDidEndEditing:(UITextField *)textField;
- (BOOL)textFieldShouldReturn:(UITextField *)textField
- (BOOL)textField:(UITextField *) textField shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text /// Updating the text and checking the text at runtime
Same set of functions could be used for changing and manipulating the text of UItextView.
For Using a text field attacted to the keyboard
->Create a view with the textField and add the view as subview to the view to be added
Eg Fot TextField
- (void)textFieldDidBeginEditing:(UITextField *)textField;
- (void)textFieldDidEndEditing:(UITextField *)textField;
- (BOOL)textFieldShouldReturn:(UITextField *)textField
- (BOOL)textField:(UITextField *) textField shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text /// Updating the text and checking the text at runtime
Same set of functions could be used for changing and manipulating the text of UItextView.
For Using a text field attacted to the keyboard
->Create a view with the textField and add the view as subview to the view to be added
Resign Keyboard in UITextView
There might be cases which require the keyboard t be dismissed on pressing the return button
Implement the UITextViewDelegate and- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { // Any new character added is passed in as the "text" parameter
if([text isEqualToString:@"\n"]) {
// Be sure to test for equality using the "isEqualToString" message
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return FALSE;
} // For any other character return TRUE so that the text gets added to the view
return TRUE;
}
Encoding of url for handling the spaces and crazy characters
Final string that is obtained needs to be encoded to handle the characters like spaces , dots and other wierd characters before sending it to the server.
In NSString the function called stringByAddingPercentEscapesUsingEncoding takes care of it
eg.
NSString* escapedUrl = [requestString
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL * requestUrl = [NSURL URLWithString: escapedUrl];
Must for creating a request for connection using NSURLConnection with the requestUrl
Data Entry and scrolling issue
Data entry text field and scrolling issues with tableview controller.
Using a hard code method to shift the view by certain pixels
It does not use the notification methods like the keyboard hide and show
http://stackoverflow.com/questions/594181/uitableview-and-keyboard-scrolling-problem
MoviePlayer Controller - Video looping and Blending
What we want to achieve:
Looping Video and blending the video when the video ends. By default the background of the movieplayer is black. Using UIClearColor helps in blending.
Might want to control the start of the video from somewhere in the middle of the video.
moviePlayer.initialPlaybackTime = 20.0f;
Lopping achieved by using
- (void) moviePlayBackDidFinish:(NSNotification*)notification
player.initialPlaybackTime = 20.0f;
[player play];
Using the first frame of the video as the background image of the video.
Sample with explanation at http://labs.lastminute.com/blog/how-we-built-topsee-–-the-technical-details-an-intro-movie/
Aspect Fit vs Aspect Fill
Aspect Fit makes sure your whole image is visible proportionally.
Aspect Fill will make sure there is no space left in the imageview while sizing your image proportionally.
Aspect Fill will make sure there is no space left in the imageview while sizing your image proportionally.
Memory Handling
One of the very important areas. I haven't seen lot of links that help understand the retaining and release.
As the project gets complex. and more subviews, more the issues.
Some things to know
In did recieveWarnings method
// We can set some instance variables as nil, rather than call the release method on them, if we have defined setters that retain nil and release their old values (such as through use of @synthesize)
eg
for string B and D synthesis defined and property defined., String A and C only declarat
self.myStringB = nil;
As the project gets complex. and more subviews, more the issues.
Some things to know
In did recieveWarnings method
// We can set some instance variables as nil, rather than call the release method on them, if we have defined setters that retain nil and release their old values (such as through use of @synthesize)
eg
for string B and D synthesis defined and property defined., String A and C only declarat
self.myStringB = nil;
self.myStringD = nil;
[myStringA release];// No setter defined - must release it this way
[myStringC release];// No setter defined - must release it this way
Good Example of using the didRecieve MemoryWarnings etc and setView
http://www.mail-archive.com/[email protected]/msg23288.html
http://www.cocoabuilder.com/archive/cocoa/224024-uiviewcontroller-memory-warnings-didreceivememorywarning-setview-releasing-outlets-releasing-properties.html
Good Example of using the didRecieve MemoryWarnings etc and setView
http://www.mail-archive.com/[email protected]/msg23288.html
http://www.cocoabuilder.com/archive/cocoa/224024-uiviewcontroller-memory-warnings-didreceivememorywarning-setview-releasing-outlets-releasing-properties.html
Loading Image in Html - Base 64 string
Loading Html page in UIWebview is done NSUrl request to the the html page
Eg
Online Html page
NSURL *url = [NSURL URLWithString:@"http://google.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
This is the straightforward way of getting the page displayed.
You might want to get the page rendered in offline mode.
Offline Html Page
NSString *htmlFile = [[NSBundlemainBundle] pathForResource:@"sample"ofType:@"html"];
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFile];
[webViewloadData:htmlData MIMEType:@"text/html"textEncodingName:@"UTF-8"baseURL:[NSURLURLWithString:@""]];
There might be cases when you want to a html page in Iphone with and image
with image loaded from some site
<img src="http://www.google.com/some.gif"/><br/>
Loading a base 64 string format for the in the Html page
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAALwAA/
+4ADkFkb2JlAGTAAAAAAf/bAIQACQYGBgcGCQcHCQ0JBwkNDwsJCQsPEg4ODw4OEhEODw4ODw4RERQVFxUUERs
sf1O9EVq6EHqWVfvwFtNyiKVi1ND6a49qIiwV/R/9k="alt="some.jpg" /><br/>
Function callback Implementation
Class A
[t statuses_update:twitterMessageText.textdelegate:selfrequestSelector:@selector(status_updateCallback:)];
/// Call back recieved with data
- (void) status_updateCallback: (NSData *) content {
}
Class B
if([delegaterespondsToSelector:self.callback])
{
[delegateperformSelector:self.callbackwithObject:receivedData];
}
[t statuses_update:twitterMessageText.textdelegate:selfrequestSelector:@selector(status_updateCallback:)];
/// Call back recieved with data
- (void) status_updateCallback: (NSData *) content {
}
Class B
if([delegaterespondsToSelector:self.callback])
{
[delegateperformSelector:self.callbackwithObject:receivedData];
}
Float to string and formating
You might require to have a number like 2.00834.
You can round off with 2 digits - use %.2f.
In case you want number with removing all the 00 from 3.5 use %g
NSString *numberstring = [dict objectForKey:@"distance"];
float numberf = [numberstring floatValue];
float distance = round(2.0f * numberf) / 2.0f;
NSString *info3 = [NSString stringWithFormat:@"Distance %g",distance];
You can round off with 2 digits - use %.2f.
In case you want number with removing all the 00 from 3.5 use %g
NSString *numberstring = [dict objectForKey:@"distance"];
float numberf = [numberstring floatValue];
float distance = round(2.0f * numberf) / 2.0f;
NSString *info3 = [NSString stringWithFormat:@"Distance %g",distance];
Retrieving data from a webservice
This is how a Post request would look like- notice it includes the body[theRequestsetHTTPMethod:@"POST"];
[theRequestsetValue:@"application/x-www-form-urlencoded"forHTTPHeaderField:@"Content-Type"];
[theRequestsetHTTPBody:[requestBodydataUsingEncoding:NSASCIIStringEncodingallowLossyConversion:YES]];
[theRequestsetValue:[NSStringstringWithFormat:@"%d",[requestBodylength] ] forHTTPHeaderField:@"Content-Length"];
Also a good example for the callback function implementation.
E.g TwitterRequest
Cake post
Used to always wonder the difference between a Get and Post Request - The way I put it - Post request has a Body and get will not. Imagine a letter sent to cake maker with the Info of how the cake should be_ customised or in other words you POST the info of how the cake should be.
While in case of Get Request- you just say you want the cake - and cake is returned as per the availability.
Using Dynamic number of buttons on UIActionSheet
There might be cases where you want to add title to the action sheet but you dont the info of number of buttons to add.
Trying to add the array to otherbuttontitles in the action sheet would result in a crash the with compiler warnings.
This is a good way to solve the problem - set the buttons as nil and then start adding the buttons to it.
UIActionSheet *actionSheet= [[UIActionSheet alloc] initWithTitle:@"Sometitle"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (int i=0; i<[buttons count];i++)
{
NSString *string = [NSStringstringWithFormat:@"%@",[[buttonsobjectAtIndex:i] objectForKey:@"description"] ];
tmp addObject: string];
[actionSheet addButtonWithTitle:string];
}
[actionSheet addButtonWithTitle:@"Cancel"];
[actionSheet setCancelButtonIndex:[buttonscount]];
Trying to add the array to otherbuttontitles in the action sheet would result in a crash the with compiler warnings.
This is a good way to solve the problem - set the buttons as nil and then start adding the buttons to it.
UIActionSheet *actionSheet= [[UIActionSheet alloc] initWithTitle:@"Sometitle"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (int i=0; i<[buttons count];i++)
{
NSString *string = [NSStringstringWithFormat:@"%@",[[buttonsobjectAtIndex:i] objectForKey:@"description"] ];
tmp addObject: string];
[actionSheet addButtonWithTitle:string];
}
[actionSheet addButtonWithTitle:@"Cancel"];
[actionSheet setCancelButtonIndex:[buttonscount]];
Striping the Html content in UIWebview
Quite useful - When you want to get only the pure text content from the webpage returned by the UIWebview
- (void)webViewDidFinishLoad:(UIWebView *)_webView
{
NSString *myText = [_webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];
}
In case you want the entire content with the HTML contents then
- (void)webViewDidFinishLoad:(UIWebView *)_webView
{
NSString *content = [_webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML;"];
}
Random Snowfall
UIImageView* snow = [[UIImageView alloc] initWithImage: snow];
// use the random() function to randomize up our flake attributes
int startX = round(random() % 320);
int endX = round(random() % 320);
double scale = 1 / round(random() % 100) + 1.0;
double speed = 1 / round(random() % 100) + 1.0;
// set the flake start position
snow.frame = CGRectMake(startX, -100.0, 25.0 * scale, 25.0 * scale);
snow.alpha = 0.25;
// put the flake in our main view
[self.view addSubview: snow];
[UIViewbeginAnimations:nilcontext: snow];
// set up how fast the flake will fall
[UIViewsetAnimationDuration:5 * speed];
// set the postion where flake will move to
snow.frame = CGRectMake(endX, 500.0, 5.0 * scale, 5.0 * scale);
// set a stop callback so we can cleanup the flake when it reaches the
// end of its animation
[UIViewsetAnimationDidStopSelector:@selector(onAnimationComplete:finished:context:)];
[UIViewsetAnimationDelegate:self];
[UIViewcommitAnimations];.
Add a scroll view. Eg right move.
In this tutorial I will create a 2 UiScrollviews in a UIView with horizontal and vertical scrolling respectively.I will be using mainly IB to set up the images in the scrollview. This is ideal in case you know exactly number of images you need in the scroller. If you are unsure of the number of images, you should the loading of images and setting the properties from the code itself. Also if the number is very large you should consider using a dynamic loading and unloading of images to provide smooth user experience while scrolling.
1)Create a scroll view in your IB
You can layout the elements you want to use in the scrollview like the image view the labels etc as per you choice. Also use the frame offset in the view to view the elements that are laid out in the bottom of the screen of next page of the screen.
Drag the images to the resources directory to add it to the project.
Say you want to have 3 images in the scrollview
Create a scrollview with the width of the scrollview( SizePosition in Image view size) to the total_Images * width of the each image. Add individual images to each of the image_view added in the scrollview.To make the image fit to the scale - (ImageView Attributes->View->Mode - Scale To Fill )
Enable the interaction for the swiping the images across
Set the enabled ( ImageView Attributes->View->Mode - User Interaction Enabled )
In this case we will have 1 scrollview scrolling in horizontal and other in vertical direction.
Ensure that the vertical scrollview is enabled in the IB for the first and horizontal only in second
scrollview
Implement - UIScrollViewDelegate in you .h file.
Add the IBOutlet to your code .h file
IBOutlet UIScrollView * scrollView1;
IBOutlet UIScrollView * scrollView2;
Add the property for the scrollview
@property (nonatomic,retain) UIScrollView * scrollView1;
@property (nonatomic,retain) UIScrollView * scrollView2;
Synthesis the scrollview in the .m file
@synthesize scrollView1,scrollView2;
Connect the scrollviews in the code in your IB.
Add few lines of code to set up the the scroller content size in the .m file
/// use this for the vertical scroller
scrollView1.contentSize = CGSizeMake(320.0, 400.0);
scrollView1.contentOffset = CGPointMake(0, 0);
// This is for horizontal scrolling
scrollView2.contentSize = CGSizeMake(640.0, 200.0);
scrollView2.contentOffset = CGPointMake(0, 0);
2) connect the scroll view to the files owner
3) Implement UiScrollViewDelegate in the .h file of the class you are using
4) declare Scrollview in the class you are implementing and connect the scrollview in the IB
5) Implement pieces of code in .m file