IOS菜鸟的所感所思(八)——coreData与网络歌曲的本地化

目标:利用coreData实现对网络歌曲信息的记录,并根据其信息下载歌曲到本地。

UI设计:


就是在原来的基础上添加一个button按钮,并且将按钮的类型改为Add Contact即可。

代码设计:

我们要实现的是点击按钮时,会做出相应的响应。

//向数据表中添加数据

- (IBAction)collectMusic:(UIButton *)sender {

    

    [DBManager music_insertNetItem:@"Music"andData:_musicDatamanagedObjectContext:self.myAppDelegate.managedObjectContext];

    

    [self downloadMusic:_musicData.songID andMusicName:_musicData.trackname];

    

}

当点击加号按钮时,我们会把该行cell中的信息用coreData提供的接口写入到SQLite数据文件中。

所以我们得先做好准备工作。

新建一个coreData类型的文件dataModel,取名CollectDataModel

打开该文件,新建一个Entity,名为Music,添加属性,


之后点击Editor,Create NSManagedObject Subclass,系统就会自动生成Music类。

CoreData基本概念:

CoreData提供了一种简便的对象持久化管理方法,使你可以不用关心数据的存储,只需要关心对象的增加、删除、更改、读写。


托管对象(managed object)
一个托管对象代表你想要保存到数据存储中的一个对象。这在概念上类似于SQL中的一条记录, 并且通常也包含一些域,这些域对应于你想要保存的对象的属性。

数据存储(data store)
Core Data支持4中类型的数据存储:SQLiteStore, XMLStore, BinaryStore, InMemoryStore。

托管对象上下文(managed object context)
托管对象上下文类似于应用程序和数据存储之间的一块缓冲区。这块缓冲区包含所有未被写入数据存储的托管对象。你可以添加、删除、更改缓冲区内的托管对象。在很多时候,当你需要读、插入、删除对象时,你将会调用托管对象上下文的方法。
 
持久化存储协调器(persistent store coordinator)
持久化存储协调器处理到数据存储的连接,并且包含一些底层信息,像用到数据存储的名字和位置。这个类通常被托管对象上下文用到。
 
托管对象模型(managed object model)
托管对象模型是一个类,这个类包含每一个你想存储到数据存储中的托管对象的定义

使用CoreData

1 在你可以读或写模型对象到当前数据存储之前,你需要实例化托管对象模型、托管对象上下文、持久化存储协调器。
托管对象模型由NSManagedObjectModel类的一个实例表示。在一个工程中我们只需要为所有的.xcdatamodeld文件实例化一个对象。
NSManagedObjectModel* managedObjectModel = [NSManagedObjectModel
        mergedModelFromBundles:nil];
mergedModelFromBundles: 搜索工程中所有的.xcdatamodeld文件,并加载所有的实体到一个NSManagedObjectModel  实例中。
这样托管对象模型知道所有当前工程中用到的托管对象的定义

2 有了托管对象模型实例之后,我们就可以创建一个持久化协调器实例了。持久化协调器处理到数据存储的连接。大概是处理怎么把对象写到数据存储或怎么从数据存储读对象吧。

有了持久化协调器实例之后,我们需要提供一个数据存储给它管理。你可以通过发送addPersistentStoreWithType:configuration:URL:options:error:消息来实现。

4 最后一步就是实例化托管对象上下文。有了托管对象上下文,你就可以方便的管理对象了。

coreData代码:

在我们新建项目时,可以勾选上coreData选项,然后在appdelegate中改一下相应的代码即可。由于我们的项目已经建立好了,你可以在建一个项目,勾选coreData后,把相应的代码拷过来即可,然后再在有些地方进行修改。

- (NSManagedObjectModel *)managedObjectModel {


    if (_managedObjectModel != nil) {

        return _managedObjectModel;

    }

    _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

    return _managedObjectModel;

}

创建一个托管对象模型,若有就返回该对象,反之,就创建一个托管对象。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

   

    if (_persistentStoreCoordinator != nil) {

        return _persistentStoreCoordinator;

    }

    

    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    NSURL *storeURL = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"TestCoreData.sqlite"]];

    NSLog(@"path is %@",storeURL);

    NSError *error = nil;

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

        NSLog(@"Error:%@,%@",error,[error userInfo]);

    }

    return _persistentStoreCoordinator;

}

创建持久化协调器对象,当然会用到托管对象,并且创建SQLite的数据文件,创建好持久化协调器之后将它与数据文件给它管理。
至于其余的都不需要改动。
到目前为止,我们的准备工作算是完成了。
接下的就是对数据的操作了。

回到前面的加号按钮的点击响应(加号需要和相应的类进行关联)。
点击加号按钮时我们想把数据写进数据文件中,所以这里会对数据进行操作,可以把这些操作再放入另一个接口中。

DBManager类:用于数据的管理

插入操作:(类方法并且是共有的)

//添加数据

+ (void)music_insertNetItem:(NSString *)EntityName andData:(MusicData *)musicData managedObjectContext:(NSManagedObjectContext *)context{

    //获得数据中的实体

    Music *music = (Music *)[NSEntityDescription insertNewObjectForEntityForName:EntityName inManagedObjectContext:context];

    //对实体Music对象进行添加数据

    [music setTrackname:musicData.trackname];

    [music setAlbumname:musicData.albumname];

    [music setLogoname:musicData.logoname];

    

    NSLog(@"%@\n%@\n logoname:%@\n",music.trackname,music.albumname,music.logoname);

    NSError *error;

    BOOL isSaveSuccess = [context save:&error];

    if (!isSaveSuccess) {

        NSLog(@"Error:%@",error);

    }else{

        NSLog(@"Save successful!");

    }

}

这样就完成了对数据的插入操作,每点击一行的加号按钮后,会把改行的信息写入后方SQLite的数据文件中。
[ self  downloadMusic : _musicData . songID  andMusicName : _musicData . trackname ];
我们会看到MusicData中有songID这个属性,因此我们需要在MusicData中添加这个属性,

@property (nonatomic,strong) NSString *songID;

当然我们还需要将它进行关联,在获取网络数据时,因为这儿我们需要歌曲的播放地址,然后根据播放地址把数据下载到本地。

在方法:+ (void)fetchSongDetailInfo:(id)item callback:(fetchDetailSongInfoCallback)callback;


songID = [[[itemDictionary objectForKey:@"songs"]firstObject]objectForKey:@"mp3Url"] ;

//把值与key相联

[item setValue:songID forKey:@"songID"];

接着我们需要的就是下载工作。

- (void)downloadMusic:(NSString *)musicPath andMusicName:(NSString *)name{

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        NSURL *url = [NSURL URLWithString:musicPath];

        NSData *data = [NSData dataWithContentsOfURL:url];

        

        

        //将数据保存到本地指定位置

        NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];

        

        NSString *filePath = [NSString stringWithFormat:@"%@/%@.mp3", docDirPath , name];

        NSLog(@"%@",filePath);

        

        [data writeToFile:filePath atomically:YES];

    });

    

}

到相应的地址去看,你会看到



下一篇我们会新建一个视图控制器,用来存放收藏的音乐。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值