仿美团项目-第一部分

最近想写一个个人项目,选了好久最后选择了仿照美团做一个app,好将学到的语言和开发基础知识用到具体项目上试试!

一、团购数据来源:

1. 网络数据来源(团购数据):点评网开发者SDK  (key/secret)

2. 网络数据来源(元数据) —> cities.plist(城市名字)

二、首先处理数据(Model)层:

SDK: Software Development Kit 软件开发包

API: Application Programming Interface: 应用程序接口

IDE: Intergted Development Environment: Xcode/Eclipse

通过API获取申请到你自己的 ID 和 Key ,牢记Key!!

基本操作步骤:首先下载点评网的SDK,然后读懂如何使用SDK,最后将SDK导入到项目中。

三、开始创建项目:

1.将SDK中的类导入到Project中的方法:

(1)将需要的文件拽到项目中;

(2)然后遵循协议;

(3)实现协议的方法;

实现收据发送接收的一般步骤为:客户端发送请求->服务器 -> JSON数据 (订单数据);

2.创建YKDeal.h/.m模型类, .h中的属性针对和服务器返回的JOSN中的key要一一对应(注意点:一定要一一对应,完全一样!)

3.解析JSON数据 (对象NSDictionary转模型)

1) 针对团购订单创建模型对象YKDeal.h/.m:NSObject

2) 使用setValuesForKeysWithDictionary方法解析JSON数据:

a.在该文件下声明的属性的名字需要和服务器返回的key要一模一样

b.如果遇到有OC中的关键字,需要改成其他的(eg:description--->desc)

c.遇到第b中情况,必须手动来绑定description和desc,必须要实现setValue:forUndefinedKey:方法

3)调用解析步骤

a.创建一个模型对象

YKDeal *deal = [[YKDeal alloc] init];

b.使用setValues方法将传入的字典对象自动地和deal模型对象匹配 (通过dealDic中的key和YKDeal模型对象.h中的属性一一对应)

[deal setValuesForKeysWithDictionary:dealDic];

代码区:

YKDeal.h文件内容:

#import <Foundation/Foundation.h>

@interface YKDeal : NSObject

/*不同:
 1.在该文件下声明的属性的名字要和服务器返回回来的key要一模一样
 2.如果遇到oc中的关键字,需要将属性名改为其他的(eg:description ---> desc)
 3.遇到第二种情况,则必须要手动的绑定关键字(eg:descrption和desc),必须要实现setValue:forUndefinedKey:方法
 */
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *desc;/**<订单描述 */
@property (nonatomic, strong) NSNumber *list_price;/**<原价 */
@property (nonatomic, strong) NSNumber *current_price;/**<现价 */
@property (nonatomic, strong) NSNumber *purchase_count;/**<购买数量 */
@property (nonatomic, strong) NSString *image_url; /**<团购订单(大图)图片对应的url */
@property (nonatomic, strong) NSString *s_image_url;/**<团购订单(小图)图片对应的url */

@end

YKDeal.m文件内容:

#import "YKDeal.h"

@implementation YKDeal

//重写方法 ---> 目的:将字典中的那个description关键字和属性中的desc进行绑定
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    if ([key isEqualToString:@"description"]) {
        self.desc = value;

    }
}

@end

到此处 处理网络JSON数据基本上就算完了!

四、原数据文件的处理

一)处理网络中的“元数据”:

1. 四个plist文件 (分类元数据;城市元数据;区域元数据;排序元数据)

2.采用单例方式读取每个plist文件中的数据(读取一次);

3. 类的划分:

viewController.h/.m

YKMetaDataTool.h/.m -> 处理所有和元数据相关的逻辑

YKCity.h/.m; YKCategory.h/.m; YKSort.h/.m

YKDeal.h/.m

将程序需要的四个plist文件和所有的图片拖拽到项目中;

二)创建三个模型类:

a. YKCity.h/.m; YKCategory.h/.m; YKSort.h/.m

b. 针对这三个模型类的.h中声明属性(需要和plist文件中的key一一对应)

三)YKMetaDataTool.h提供三个类方法,分别对应分类、城市、排序 方法

a.排序数据(返回所有排序模型对象)

+ (NSArray *)sorts;

b.城市数据(返回所有城市模型对象)

+ (NSArray *)cities;

c.分类数据(返回所有分类模型对象)

+ (NSArray *)categories;

代码区:

YKMetaDataTool.h文件内容:

#import <Foundation/Foundation.h>

@interface YKMetaDataTool : NSObject

/**
 *  排序数据(返回所有的排序模型对象)
 */
+ (NSArray *)sorts;

/**
 *  城市数据
 */
+ (NSArray *)cities;

/**
 *  分类数据
 */
+ (NSArray *)categories;

/**
 *  根据传入的城市,返回该城市对应的所有区域和子区域
 */
+ (NSArray *)regionWithCityName:(NSString *)cityName;

@end

YKMetaDataTool.m文件内容:

#import "YKMetaDataTool.h"
#import "YKSort.h"
#import "YKCategory.h"
#import "YKCity.h"
#import "YKRegion.h"

@implementation YKMetaDataTool

/**方式:单例模式
 *  1.从plist文件中读取数据(bounds里)---> NSDictionary
    2.循环解析从plist文件中读取的数据(数据)--->TRSort
    3.将解析好的所有模型对象存储到数组中,并返回
 */
static NSArray *_sorts;
+ (NSArray *)sorts{
    if (!_sorts) {
        _sorts = [[self alloc] getAndParseSortsFile:@"sorts.plist"];
    }
    return _sorts;
}

//从plist文件中读取数据并返回到数组中
- (NSArray *)getArrayFromPlistFile:(NSString *)fileName {
    //1.从fileName中读取数据
    NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
    NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
    return array;
}

- (NSArray *)getAndParseSortsFile:(NSString *)fileName {

    NSArray *sortsArray = [self getArrayFromPlistFile:fileName];
    //2.循环解析
    NSMutableArray *sortsMutableArray = [NSMutableArray array];
    for (NSDictionary *sortDic in sortsArray) {
        YKSort *sort = [YKSort new];
        [sort setValuesForKeysWithDictionary:sortDic];
        [sortsMutableArray addObject:sort];
    }
    //3.返回
    return [sortsMutableArray copy];
}

//城市
static NSArray *_cities;
+ (NSArray *)cities{
    if (!_cities) {
        _cities = [[self alloc] getAndParseCityFile:@"cities.plist"];
    }
    return _cities;
}

- (NSArray *)getAndParseCityFile:(NSString *)fileName {
    NSArray *cityArray = [self getArrayFromPlistFile:fileName];
    //循环解析
    NSMutableArray *cityMutableArray = [NSMutableArray array];
    for (NSDictionary *cityDic in cityArray) {
        YKCity *city = [YKCity new];
        [city setValuesForKeysWithDictionary:cityDic];
        [cityMutableArray addObject:city];
    }
    return [cityMutableArray copy];
}

//分类
static NSArray *_categories;
+ (NSArray *)categories{
    if (!_categories) {
        _categories = [[self alloc] getAndParseCategoryFile:@"categories.plist"];
    }
    return _categories;
}

- (NSArray *)getAndParseCategoryFile:(NSString *)fileName {
    NSArray *categoryArray = [self getArrayFromPlistFile:fileName];
    NSMutableArray *categoriesMutableArray = [NSMutableArray array];
    for (NSDictionary *categoryDic in categoryArray) {
        YKCategory *category = [YKCategory new];
        [category setValuesForKeysWithDictionary:categoryDic];
        [categoriesMutableArray addObject:category];
    }
    return [categoriesMutableArray copy];
}

//返回指定城市的所有区域
+ (NSArray *)regionWithCityName:(NSString *)cityName{

    if (cityName.length == 0) {
        return nil;
    }

    YKCity *findedCity = [YKCity new];
    //1.循环找到城市名字叫做cityName对应的城市模型对象YKCity
    NSArray *citysArray = [self cities];
    for (YKCity *city in citysArray) {
        if ([city.name isEqualToString:cityName]) {
            findedCity = city;
            break;
        }
    }
    //2.对YKCity中的区域数组进行解析(NSDictionary -> YKRegion)
    NSArray *regionArray = findedCity.regions;
    //循环解析(NSDictionary --> YKRegion)
    NSMutableArray *regionMutableArray = [NSMutableArray array];
    for (NSDictionary *regionDic in regionArray) {
        YKRegion *region = [YKRegion new];
        [region setValuesForKeysWithDictionary:regionDic];
        [regionMutableArray addObject:region];
    }
    return [regionMutableArray copy];
}
@end

YKSort.h文件内容:

#import <Foundation/Foundation.h>

@interface YKSort : NSObject

@property (nonatomic, strong) NSString *label;/**<label描述 */
@property (nonatomic, assign) int value;/**<value值 */

@end

YKCategory.h文件内容:

#import <Foundation/Foundation.h>

@interface YKCategory : NSObject

@property (nonatomic, strong) NSString *highlighted_icon;/**<分类高亮图标 */
@property (nonatomic, strong) NSString *icon;/**<分类图标 */
@property (nonatomic, strong) NSString *name;/**<分类名字 */
@property (nonatomic, strong) NSString *small_highlighted_icon;/**<分类高亮小图标 */
@property (nonatomic, strong) NSString *small_icon;/**<分类小图标 */
@property (nonatomic, strong) NSString *map_icon;/**<分类地图图标 */
@property (nonatomic, strong) NSArray *subcategories;/**<分类子分类 */

@end

YKCity.h文件内容:

#import <Foundation/Foundation.h>

@interface YKCity : NSObject

@property (nonatomic, strong) NSString *name;/**<城市名 */
@property (nonatomic, strong) NSString *pinYin;/**<城市拼音 */
@property (nonatomic, strong) NSString *pinYinHead;/**<城市首字母 */
@property (nonatomic, strong) NSArray *regions;/**<来描述当前城市所有的区域 */

@end

YKRegion.h文件内容:

#import <Foundation/Foundation.h>

@interface YKRegion : NSObject

@property (nonatomic, strong) NSString *name;/**<区域的名字 */
@property (nonatomic, strong) NSArray *subregions;/**<区域的子区域 */

@end

写到这儿Model层基本上就算搭建完了,以后有需要再添加!

ps:刚用博客不久,想上传上文中的plist文件,可是不会上传文件,希望知道上传方法的朋友能在评论里告知,十分感谢!

时间: 2024-10-06 20:56:38

仿美团项目-第一部分的相关文章

高仿美团应用客户端项目源码

源码Tuan,这个案例是模仿MJ老师ipad版美团(swift版),高仿美团iOS版,版本号:5.7, 已更新到Swift 2.0 基于Xcode 7 源码下载: http://code.662p.com/view/11383.html <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore

仿LOL项目开发第四天

---恢复内容开始--- 仿LOL项目开发第四天 by草帽 上节讲了几乎所有的更新版本的逻辑,那么这节课我们来补充界面框架的搭建的讲解. 我们知道游戏中的每个界面都有自己的一个类型:比如登陆界面,创建角色界面. 既然有这么多的界面,所以呢,我们创建一个单例的UI管理器:WindowManager.cs,然后里面创建一个字典来存所有类型的界面: using UnityEngine; using System.Collections.Generic; using Game; using Game.C

仿LOL项目开发第二天

仿LOL项目开发第二天 by草帽 接着上节来讲,上节更新还没开始写代码逻辑,今天我们补充完整. 我们找到VersionManager脚本里面的CheckVersion方法: 首先我们想到检测版本,需要从服务器下载信息,那么肯定要提前检测下网络是否良好,并比较版本信息. 所以,我们写个BeforeCheck方法: /// <summary> /// 检测网络状况并对照版本信息是否一致 /// </summary> /// <param name="AsynResult

IOS-高仿bilibili项目

高仿bilibili项目成长之路 (logo) 高仿bilibili项目 Github链接:(https://github.com/MichaelHuyp/Bilibili_Wuxianda) 目前完成了如下功能: 启动页的业务逻辑 带有阻力效果的轮播图 直播.推荐.番剧界面的搭建 基于ijkplayer的视频播放器(普通视频.直播视频) 七月三十号更新: 个人中心模块的搭建 集成基于来疯直播开源的LFLiveKit的手机直播功能 RTMP推流 镜像 .美颜.手电筒.摄像头方向 更新展示 关于电

高仿美团&lt;二&gt;

由于在简书上已经把项目的思路和个个模块写的很清楚了. 点击以下链接高仿美团<2> 版权声明:本文为博主原创文章,未经博主允许不得转载.

MeiTuanRefreshListView高仿美团下拉刷新《IT蓝豹》

MeiTuanRefreshListView高仿美团下拉刷新 MeiTuanRefreshListView高仿美团下拉刷新,本项目来自:https://github.com/nugongshou110/MeiTuanRefreshListView项目主要构成部分:自定义MeiTuanRefreshFirstStepView,MeiTuanRefreshSecondStepView,MeiTuanRefreshThirdStepView,其中自定义MeiTuanListView继承了ListVie

Android开发:仿美团下拉列表菜单,帮助类,复用简单

最近在项目中需要用到下拉菜单,公司比较推崇美团的下拉菜单,于是要实现该功能,想着,这个功能应该是一个经常会用到的,于是何不写一个帮助类,只要往这个类里面传入特定的参数,既可以实现下来菜单,而且还可以实现菜单选择的回调,既可以重复使用,有简单便捷 首先,查看界面效果图 界面倒是比较简单,主要列下功能: 这个是靠一个帮助类实现的,下次想在自己的项目中实现该功能,一句引用代码,传入特定的参数既可以实现该功能 菜单弹出的时候,背景变灰色,菜单收回,背景回复白色 自动给选定的选项添加背景色,如果下次选择的

tkinter + cefpython 仿美团桌面程序

使用js开发桌面程序目前是一个趋势,Electron是其中一个佼佼者,网上也不乏很多文章.今天主要是来讲一下cefpython. 用python的朋友,特别使用过tkinter开发过界面的,一定会觉得使用纯tkinter开发是真的有点痛苦的一件事,开发难不说,做出来界面也不好看.前段时间做了一个项目,对方指定项目中必须用tkinter,后来我发现了cefpython这个库与tkinter结合,可以完成tkinter中像网页浏览器一样执行任何网页代码.也就是说,卡哇伊哎tkinter里面写js+h

仿LOL项目开发第三天

仿LOL项目开发第二天 by草帽 昨个我们已经实现了下载功能,但是发现没有,下载的包是压缩的,没有解压开,那么Unity是识别不了的. 所以今个我们来讲讲如何实现解压文件. 还记得吗,我们在DownloadTask里面添加了一个完成下载后的一个解压委托,我们还没有实现,那么,我们就去解决他. 回到VersionManager的DownloadPackageList方法里面,在OnDownloadFinished委托里面,添加解压缩的代码. 之前讲过类的单一职责,所以不可能在VersionMana