Overriding in Swift programming

This article is a continuation from previous article

A subclass can provide its own custom implementation of an instance method, class method, instance property, class property, or subscript that it would otherwise inherit from a superclass. This is known as overriding.
When you provide a method, property, or subscript override for a subclass, it is sometimes useful to use the existing superclass implementation as part of your override. For example, you can refine the behavior of that existing implementation, or store a modified value in an existing inherited variable.

Overriding Methods:

You can override an inherited instance or class method to provide a tailored or alternative implementation of the method within your subclass.

The following example defines a new subclass of Vehicle called Train, which overrides the makeNoise method that Train inherits from Vehicle:

class Train: Vehicle {
    override func makeNoise() {
        println("Choo Choo")
    }
}

If you create a new instance of Train and call its makeNoise method, you can see that the Train subclass version of the method is called:

let train = Train()
train.makeNoise()
// prints "Choo Choo"

Overriding Properties:

You can override an inherited instance or class property to provide your own custom getter and setter for that property, or to add property observers to enable the overriding property to observe when the underlying property value changes.

Overriding Property Observers:

You can use property overriding to add property observers to an inherited property. This enables you to be notified when the value of an inherited property changes, regardless of how that property was originally implemented.

Closures in Swift programming

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.

Closure expression syntax has the following general form:

{ (parameters) -> return type in
statements
}

The example below shows a closure expression:

let names = [“Chris”, “Alex”, “Ewa”, “Barry”, “Daniella”]
reversed = sorted(names, { (s1: String, s2: String) -> Bool in
return s1 > s2
})

Enumerations in Swift programming language

An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

Enumeration Syntax:

enum SomeEnumeration {
// enumeration definition goes here
}

Here’s an example for the four main points of a compass:

enum CompassPoint {
case North
case South
case East
case West
}

You can match individual enumeration values with a switch statement:

directionToHead = .South
switch directionToHead {
case .North:
println(“Lots of planets have a north”)
case .South:
println(“Watch out for penguins”)
case .East:
println(“Where the sun rises”)
case .West:
println(“Where the skies are blue”)
}

How to record ,save and playback sound using AVAudioRecorder in Xcode

- (IBAction)recordAction:(UIButton *)sender {
    NSError *error;
    
    NSLog(@"recording");
    
    // Recording settings
    NSMutableDictionary *settings = [NSMutableDictionary dictionary];
    
    [settings setValue: [NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [settings setValue: [NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
    [settings setValue: [NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
    [settings setValue: [NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
    [settings setValue:  [NSNumber numberWithInt: AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];
    
    NSArray *searchPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath_ = [searchPaths objectAtIndex: 0];
    
    NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[self dateString]];
    
    // File URL
    NSURL *url = [NSURL fileURLWithPath:pathToSave];//FILEPATH];
    NSLog(@"url = %@",url);
    
    
    //Save recording path to preferences
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    
    
    [prefs setURL:url forKey:@"Test1"];
     NSLog(@"prefs = %@",prefs);
    [prefs synchronize];
    
    
    // Create recorder
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [audioSession setActive:YES error:nil];
    [recorder setDelegate:self];

    recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
    [recorder prepareToRecord];
    //recorder.delegate = self;
    [recorder record];
    
    
}
- (IBAction)stopRecording:(UIButton *)sender {
     //Stop recording
    [recorder stop];
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setActive:NO error:nil];
}

- (IBAction)playRecord:(UIButton *)sender {
    //to play recorded sound
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    [audioSession setActive:YES error:nil];
    
    //Load recording path from preferences
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    temporaryRecFile = [prefs URLForKey:@"Test1"];
    NSLog(@"temporaryRecFile = %@",temporaryRecFile);
    
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
    player.delegate = self;
    [player setNumberOfLoops:0];
    player.volume = 1;
    [player prepareToPlay];
    [player play];
    
}

- (NSString *) dateString
{
    // return a formatted string for a file name
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"ddMMMYY_hhmmssa";
    return [[formatter stringFromDate:[NSDate date]] stringByAppendingString:@".aif"];
}

How to save/export iPhone library music into our app?

-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
    
    MPMediaItem *item=[mediaItemCollection representativeItem];
    url = [item valueForProperty: MPMediaItemPropertyAssetURL];
    NSLog(@"url == %@",url);
    
    song = [mediaItemCollection representativeItem];//[[mediaItemCollection items] objectAtIndex:0];
    
    [self dismissModalViewControllerAnimated: YES];
    
    [self handleExportAudio];

}

-(void) handleExportAudio {
    // get the special URL
    NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
    
    NSLog (@"compatible presets for songAsset: %@",
           [AVAssetExportSession exportPresetsCompatibleWithAsset:songAsset]);
    
    
    /* approach 1: export just the song itself
     */
    exporter = [[AVAssetExportSession alloc]
                                      initWithAsset: songAsset
                                      presetName: AVAssetExportPresetAppleM4A];
    NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);
    exporter.outputFileType = @"com.apple.m4a-audio";
    NSString *exportFile = [myDocumentsDirectory() stringByAppendingPathComponent: @"exported.m4a"];
    
    // set up export (hang on to exportURL so convert to PCM can find it)
    myDeleteFile(exportFile);
    exportURL = [NSURL fileURLWithPath:exportFile];
    exporter.outputURL = exportURL;
    
    NSLog(@"exportURL = %@",exportURL);
    
    // do the export
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        int exportStatus = exporter.status;
        switch (exportStatus) {
            case AVAssetExportSessionStatusFailed: {
                // log error to text view
                NSError *exportError = exporter.error;
                NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);
                break;
            }
            case AVAssetExportSessionStatusCompleted: {
                NSLog (@"AVAssetExportSessionStatusCompleted");
                break;
            }
            case AVAssetExportSessionStatusUnknown: { NSLog (@"AVAssetExportSessionStatusUnknown"); break;}
            case AVAssetExportSessionStatusExporting: { NSLog (@"AVAssetExportSessionStatusExporting"); break;}
            case AVAssetExportSessionStatusCancelled: { NSLog (@"AVAssetExportSessionStatusCancelled"); break;}
            case AVAssetExportSessionStatusWaiting: { NSLog (@"AVAssetExportSessionStatusWaiting"); break;}
            default: { NSLog (@"didn't get export status"); break;}
        }
    }];
    
}

#pragma mark conveniences
NSString* myDocumentsDirectory() {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [paths objectAtIndex:0];;
}

void myDeleteFile (NSString* path) {
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        NSError *deleteErr = nil;
        [[NSFileManager defaultManager] removeItemAtPath:path error:&deleteErr];
        if (deleteErr) {
            NSLog (@"Can't delete %@: %@", path, deleteErr);
        }
    }
}

- (IBAction)playAudio:(UIButton *)sender {
    
    NSLog(@"DOcs dir = %@", myDocumentsDirectory());
    NSURL *myURL = [NSURL URLWithString:[NSString stringWithFormat:@"file://localhost%@/exported.m4a",myDocumentsDirectory()]];
    player=[[AVAudioPlayer alloc]initWithContentsOfURL:myURL error:nil];
    [player play];
}

iOS replacement for UDID, uniqueIdentifier

Since the uniqueIdentifier is deprecated in iOS, we must find a better alternative for it.

For iOS version greater than or equal to 6.0 we may use the identifierForVendor, and for others the advertisingIdentifier can be used.


-(NSString *) getUniqueIdentifier {

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)

return [[[UIDevice currentDevice] identifierForVendor] UUIDString];

else

return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

}

NOTE: dont forget to import

#import <AdSupport/ASIdentifierManager.h>

for the advertisingIdentifier

How to use UIRefreshControl in XCode

You can use UIRefreshControl as below:

- (void)viewDidLoad {
  [super viewDidLoad];
  UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
  refreshControl.tintColor = [UIColor redColor]; //you can customize the tint color
  //tell refreshControl where its refreshing will be handled
  [refreshControl addTarget:self action:@selector(refreshing:) forControlEvents:UIControlEventValueChanged];
  [self setRefreshControl:refreshControl];
}

-(void)refreshing:(UIRefreshControl*)refreshControl{
  //refresh code here
  [refreshControl endRefreshing];
}

How to set the height of a label with large variable text in length and with a fixed width

NSString *LabelText = @"This will be the large varying text.....";
UIFont *LabelFont = [UIFont boldSystemFontOfSize:14];
float maximumExpectedHeight = 1000.0f; //it is the maximum expected height for your label. You can set this to a high value like 10000
float LabelWidth = 80.0f;
float LabelHeight = [LabelText sizeWithFont:LabelFont constrainedToSize:CGSizeMake(LabelWidth, maximumExpectedHeight) lineBreakMode:UILineBreakModeWordWrap].height;