2
\$\begingroup\$

Exercise:

Define three new classes, called Song, Playlist, and MusicCollection. A Song object will contain information about a particular song, such as its title, artist, album, and playing time. A Playlist object will contain the name of the playlist and a collection of songs. A MusicCollection object will contain a collection of playlists, including a special master playlist called library that contains every song in the collection. Define these three classes and write methods to do the following:

  • Create a Song object and set its information.
  • Create a Playlist object, and add songs to and remove songs from a playlist. A new song should be added to the master playlist if it’s not already there. Make sure that if a song is removed from the master playlist, it's removed from all playlists in the music collection as well.
  • Create a MusicCollection object, and add playlists to and remove playlists from the collection.

Search and display the information about any song, any playlist, or the entire music collection. Make sure all your classes do not leak memory!

This is my code:

Song.h

@interface Song : NSObject

@property (nonatomic, copy) NSString *artist, *title, *album, *time;

-(void) setSong:(NSString *)theSongName andArtist:(NSString *)theArtist andAlbum:(NSString *)theAlbum andPlayingTime:(NSString *)theTime;

@end

Song.m

#import "Song.h"

@implementation Song

@synthesize title, album, artist, time;

-(void) setSong:(NSString *)theSongName andArtist:(NSString *)theArtist andAlbum:(NSString *)theAlbum andPlayingTime:(NSString *)theTime{

    self.title = theSongName;
    self.artist = theArtist;
    self.album = theAlbum;
    self.time = theTime;
}

@end

Playlist.h

#import <Foundation/Foundation.h>
#import "Song.h"

@interface PlayList : NSObject

@property (nonatomic, copy) NSString *playListName;
@property (nonatomic, strong) NSMutableArray *songsCollection;


-(void) addSongToPlayList:(Song *) someSong;
-(void) removeSongFromPlayList:(Song *) theSong;
-(void) print;
-(id) initWithName:(NSString *) listName;
-(id) init;

@end

Playlist.m

#import "PlayList.h"
#import "Song.h"

@implementation PlayList

@synthesize songsCollection, playListName;

-(void) addSongToPlayList:(Song *) someSong{

    [songsCollection addObject:someSong];
}

-(id) initWithName:(NSString *)listName{

    self = [super init];

    if (self) {

        self.playListName = listName;
        songsCollection = [[NSMutableArray alloc]init];
    }

    return self;
}

-(id) init {

    return [self initWithName:@"No Name"];
}

-(void) removeSongFromPlayList:(Song *)theSong{

    [songsCollection removeObjectIdenticalTo:theSong];

}

-(void) print{

    NSLog(@"------------------- %@ -------------------------------------",playListName);

    for (Song *mySong in songsCollection) {

        NSLog(@"%-15s %-25s %-18s %-10s",[mySong.artist UTF8String], [mySong.title UTF8String], [mySong.album UTF8String], [mySong.time UTF8String]);


    }
    NSLog(@"-----------------------------------------------------------------");
}


@end

MusicCollection.h

#import <Foundation/Foundation.h>
#import "PlayList.h"

@interface MusicCollection : NSObject

@property (nonatomic, copy) NSMutableArray *playlistsCollection;
@property (nonatomic, copy) PlayList *library;
@property (nonatomic, copy) NSString *name;

-(id) initWithName:(NSString *) collectionName;

//-(void) addSongToPlaylist:(Song *) aSong toPlaylist:(PlayList *) playlistName;
//-(void) removeSongFromPlaylist:(Song *) aSong fromPlaylist:(PlayList *) playlistName;
-(void) addPlaylistToCollection:(PlayList *) playListToAdd;
-(void) removePlayListFromCollection:(PlayList *) playListToRemove;
-(void) searchCollection:(NSString *) someCollection;
-(void) list;

@end

MusicCollection.m

#import "MusicCollection.h"

@implementation MusicCollection

@synthesize playlistsCollection, library, name;

-(id) initWithName:(NSString *)collectionName {

    self = [super init];

    if (self) {


        name = [NSString stringWithString:collectionName];
        playlistsCollection = [NSMutableArray array];
        library = [[PlayList alloc] initWithName:@"Library"];

}

    return self;
}

-(void) addPlaylistToCollection:(PlayList *)playListToAdd{

    if ([playlistsCollection containsObject: playListToAdd] == NO)
        [playlistsCollection addObject: playListToAdd];


    for (Song *song in playListToAdd.songsCollection) {

    if ([library.songsCollection containsObject:song] == NO)

        [library addSongToPlayList:song];

    }

}


-(void) removePlayListFromCollection:(PlayList *)playListToRemove {

    if ([playlistsCollection containsObject: playListToRemove] == YES)
        [playlistsCollection removeObject:playListToRemove];

    for (Song *song in playListToRemove.songsCollection)
        [library removeSongFromPlayList:song];
}

-(void) list {

    for (PlayList *playlist in playlistsCollection)
        [playlist print];
}

-(void) searchCollection:(NSString *)someCollection {

    NSMutableArray *results = [[NSMutableArray alloc] init];

    for (PlayList *lookUp in playlistsCollection) {
        if ([lookUp.playListName rangeOfString:someCollection options:NSCaseInsensitiveSearch].location != NSNotFound)
            [results addObject:lookUp];
    }

   for (PlayList *playlists in results) {

       [playlists print];

   }


}


@end

main.m

#import <Foundation/Foundation.h>
#import "Song.h"
#import "Playlist.h"
#import "MusicCollection.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        Song *song1 = [[Song alloc] init];
        Song *song2 = [[Song alloc] init];
        Song *song3 = [[Song alloc] init];
        Song *song4 = [[Song alloc] init];
        Song *song5 = [[Song alloc] init];
        Song *song6 = [[Song alloc] init];
        Song *song7 = [[Song alloc] init];


        [song1 setSong:@"Heart Attack" andArtist:@"Demi Lovato" andAlbum:@"Demi's Album" andPlayingTime:@"3:15"];
        [song2 setSong:@"When I Was Your Man" andArtist:@"Bruno Mars" andAlbum:@"Bruno Album" andPlayingTime:@"1:31"];
        [song3 setSong:@"Harlem Shake" andArtist:@"Baauer" andAlbum:@"Baauer Album" andPlayingTime:@"3:22"];
        [song4 setSong:@"I believe I Can Fly" andArtist:@"R-Kelly" andAlbum:@"R-Kelly Album" andPlayingTime:@"2:33"];
        [song5 setSong:@"A Milli" andArtist:@"Lil Wayne" andAlbum:@"Lil Wayne Album" andPlayingTime:@"1:34"];
        [song6 setSong:@"Diamonds" andArtist:@"Rihana" andAlbum:@"Rihana Album" andPlayingTime:@"2:32"];
        [song7 setSong:@"Work Hard Play Hard" andArtist:@"Wiz Khalifa" andAlbum:@"Wiz Khalifa Album" andPlayingTime:@"1:54"];


        PlayList *playlist1 = [[PlayList alloc] initWithName:@"My Favorit's"];
        PlayList *playlist2 = [[PlayList alloc] initWithName:@"Good Time's"];
        PlayList *playlist3 = [[PlayList alloc] initWithName:@"Partying"];
        PlayList *playlist4 = [[PlayList alloc] initWithName:@"Hip Hop"];

        [playlist1 addSongToPlayList:song1];
        [playlist1 addSongToPlayList:song2];
        [playlist2 addSongToPlayList:song3];
        [playlist2 addSongToPlayList:song4];
        [playlist3 addSongToPlayList:song5];
        [playlist3 addSongToPlayList:song7];
        [playlist4 addSongToPlayList:song7];
        [playlist4 addSongToPlayList:song6];
        [playlist4 addSongToPlayList:song5];
        [playlist4 addSongToPlayList:song4];
        [playlist4 addSongToPlayList:song3];
        [playlist4 addSongToPlayList:song2];


        MusicCollection *myCollection = [[MusicCollection alloc] initWithName:@"music"];

        [myCollection addPlaylistToCollection:playlist1];
        [myCollection addPlaylistToCollection:playlist2];
        [myCollection addPlaylistToCollection:playlist3];
        [myCollection addPlaylistToCollection:playlist4];


        [myCollection list];

        [myCollection searchCollection:@"Hip Hop"];

        [playlist1 removeSongFromPlayList: song2];

        [myCollection removePlayListFromCollection:playlist2];

        [myCollection list];

        [myCollection.library print];


    }
    return 0;
}

Is this code decent?

\$\endgroup\$
5
\$\begingroup\$

As I already wrote on another of your questions:

-(void) setSong:(NSString *)theSongName andArtist:(NSString *)theArtist andAlbum:(NSString *)theAlbum andPlayingTime:(NSString *)theTime;

This violates the naming conventions. it should be named

-(void) setSong:(NSString *)theSongName artist:(NSString *)theArtist album:(NSString *)theAlbum playingTime:(NSString *)theTime;

If you dont believe me, trust apple

Don’t use “and” to link keywords that are attributes of the receiver.

- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes;

Right.

- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;

Wrong.

and… indicates a second distinct action

If the method describes two separate actions, use “and” to link them.

- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;

-(void) list {

    for (PlayList *playlist in playlistsCollection)
        [playlist print];
}

list is a quite unintuitive name. printPlayListCollection or similar would be better.


you should add a init… method to Song that take all important information. The idea behind this is that by using tis as designated initializer you ensure that your song objects will always be in a valid state. Let's assume you also write the sound playing functionality: with [[Song alloc] init] you would create a object that has nothing for playback. before you would play it, each time you must assure it is playable.
But if you would raise an exception if the plain init and create initWithArtistName:songName:…filePath:… as designated initializer you can be quite sure, everything is set up correctly once you try to play it.


@sythesize statements arent necessary anymore. It will be implicit added.

@property (nonatomic, copy) NSString *artist;

will result in an implicit synthesize statement equivalent to

@synthesize artist = _artist;
\$\endgroup\$
  • \$\begingroup\$ Thank you buddy. I know this and is annoying, it's just that the author in the book use it all the time so i just got use to it, but i will get out of it. i definitely see that its not acceptable, and would make more sense to use it if there if a different action to preform in the method. @vikingosegundo \$\endgroup\$ – MNY Mar 6 '13 at 12:36
  • \$\begingroup\$ What book is it? \$\endgroup\$ – vikingosegundo Mar 6 '13 at 13:19
  • \$\begingroup\$ "Programming in Objective C" by stephen Kochan @vikingosegundo \$\endgroup\$ – MNY Mar 6 '13 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.