Foundation Framework in Objective-C
The Foundation framework provides fundamental classes and data types for Objective-C development, including strings, collections, dates, and more.
Foundation Framework is a core Objective-C framework that provides basic utility classes and data types used across all Apple platforms.
Basic Data Types
NSString and NSMutableString
// String creation
NSString *immutableStr = @"Hello World";
NSString *formattedStr = [NSString stringWithFormat:@"Value: %d", 42];
// Mutable string
NSMutableString *mutableStr = [NSMutableString stringWithString:@"Hello"];
[mutableStr appendString:@" World"];
// Common operations
NSUInteger length = [immutableStr length];
NSString *substring = [immutableStr substringToIndex:5];
NSRange range = [immutableStr rangeOfString:@"World"];
NSNumber
// Number creation
NSNumber *intNum = @42; // Literal syntax
NSNumber *floatNum = @3.14f; // Float
NSNumber *boolNum = @YES; // Boolean
// Converting back to primitives
int intValue = [intNum intValue];
float floatValue = [floatNum floatValue];
BOOL boolValue = [boolNum boolValue];
Collections
NSArray and NSMutableArray
// Immutable array
NSArray *immutableArray = @[@"One", @"Two", @"Three"];
// Mutable array
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:immutableArray];
[mutableArray addObject:@"Four"];
// Fast enumeration
for (NSString *item in immutableArray) {
NSLog(@"%@", item);
}
// Common operations
NSUInteger count = [immutableArray count];
NSString *first = [immutableArray firstObject];
BOOL contains = [immutableArray containsObject:@"Two"];
NSDictionary and NSMutableDictionary
// Immutable dictionary
NSDictionary *immutableDict = @{@"key1": @"value1", @"key2": @"value2"};
// Mutable dictionary
NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:immutableDict];
[mutableDict setObject:@"value3" forKey:@"key3"];
// Accessing values
NSString *value = immutableDict[@"key1"]; // Modern syntax
NSString *oldValue = [immutableDict objectForKey:@"key2"]; // Traditional
// Enumerating
[immutableDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"Key: %@, Value: %@", key, obj);
}];
NSSet and NSMutableSet
// Set creation (unordered, unique objects)
NSSet *immutableSet = [NSSet setWithObjects:@"A", @"B", @"C", nil];
NSMutableSet *mutableSet = [NSMutableSet setWithSet:immutableSet];
// Operations
[mutableSet addObject:@"D"];
[mutableSet removeObject:@"B"];
BOOL contains = [immutableSet containsObject:@"A"];
// Set operations
NSSet *otherSet = [NSSet setWithObjects:@"B", @"C", @"D", nil];
NSSet *unionSet = [immutableSet setByAddingObjectsFromSet:otherSet];
NSSet *intersect = [immutableSet objectsPassingTest:^BOOL(id obj, BOOL *stop) {
return [otherSet containsObject:obj];
}];
Dates and Time
// Current date
NSDate *now = [NSDate date];
// Date from components
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:10];
[comps setMonth:10];
[comps setYear:2010];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *date = [gregorian dateFromComponents:comps];
// Date formatting
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *dateStr = [formatter stringFromDate:now];
// Date calculations
NSDate *yesterday = [now dateByAddingTimeInterval:-86400];
NSTimeInterval secondsBetween = [now timeIntervalSinceDate:yesterday];
File System Operations
// File manager
NSFileManager *fileManager = [NSFileManager defaultManager];
// Path utilities
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"data.txt"];
// File operations
BOOL exists = [fileManager fileExistsAtPath:filePath];
if (!exists) {
[@"Hello World" writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
// Reading data
NSString *fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
// Directory listing
NSArray *files = [fileManager contentsOfDirectoryAtPath:documentsPath error:nil];
Networking
// URL handling
NSURL *url = [NSURL URLWithString:@"https://api.example.com/data"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// URLSession data task
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
return;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) {
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (!jsonError) {
NSLog(@"Received JSON: %@", json);
}
}
}];
[task resume];
Key-Value Coding (KVC)
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic) NSInteger age;
@end
// Using KVC
Person *person = [[Person alloc] init];
[person setValue:@"John" forKey:@"name"];
[person setValue:@30 forKey:@"age"];
NSString *name = [person valueForKey:@"name"];
NSInteger age = [[person valueForKey:@"age"] integerValue];
// Key paths
NSArray *people = @[person1, person2, person3];
NSArray *names = [people valueForKeyPath:@"name"];
NSNumber *avgAge = [people valueForKeyPath:@"@avg.age"];
Key-Value Observing (KVO)
// Adding observer
[person addObserver:self
forKeyPath:@"age"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
// Implementing observer method
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:@"age"]) {
NSNumber *oldAge = change[NSKeyValueChangeOldKey];
NSNumber *newAge = change[NSKeyValueChangeNewKey];
NSLog(@"Age changed from %@ to %@", oldAge, newAge);
}
}
// Remember to remove observer
- (void)dealloc {
[person removeObserver:self forKeyPath:@"age"];
}
Notifications
// Posting a notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdated" object:self];
// Observing a notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleDataUpdated:)
name:@"DataUpdated"
object:nil];
// Handling notification
- (void)handleDataUpdated:(NSNotification *)notification {
NSLog(@"Data was updated by: %@", notification.object);
}
// Removing observer
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Best Practices
- Use immutable collections (NSArray, NSDictionary) when possible for thread safety
- Prefer modern literal syntax (@[], @{}, @42) when creating collections and numbers
- Use fast enumeration (for-in) instead of traditional for loops with collections
- Always check for nil when working with NSString methods that return objects
- Use NSURL for file paths instead of NSString to ensure proper encoding
- Be mindful of memory management with KVO - always remove observers
- Use GCD (Grand Central Dispatch) for threading operations with Foundation objects
Note: Many Foundation classes have toll-free bridging with their Core Foundation counterparts (e.g., NSString ↔ CFStringRef).