app|0gⅰC是什么?

作者简介:韩重赞,独立开发者。零基础学习开发,用 4 个月的时间制作出「0528」「恋人清单」「开垦世界」这 3 款应用。其中,「恋人清单」曾被 App Store 首页推荐。

前段时间,我在 AppSo(微信号 appsolution)分享了自己独立开发的一款游戏——「开垦世界」。

在文章留言中,发现有很多人惊讶我为何能 4 个月可以做出 3 款不错的 app。除此之外,还收到许多关于「零基础学开发经验分享」的请求。

在被大家的学习热情感动之余,我写了这篇文章来分享我的开发学习经验。

在分享之前,我列出了学开发的一些先决条件,估计也是很多人想问的问题:

Q1:真是零基础学开发,而不是零基础学代码?

很多人认为,零基础学代码,很可能是之前有学过或做过其他领域的开发,如 PC 端开发、后台开发,现在来重新学习移动端开发。

如果你之前没接触开发,也没关系。

本文是针对的是零基础,完全无开发经验的人写的。

Q2: 我现在的专业/职业,跟程序员没任何关系会有影响么?

说说我自己吧,我的专业是工业设计,职业是 UI 设计转产品。

你说和程序员有关系么?好像有那么点,至少我懂得什么东西实现不了,什么东西难实现,什么东西容易实现

而你可能是运营专员,可能是银行柜员,也可能是卖菜的。

学代码这事,打个比方就是我是一个用过冰箱的,你是一个没用过冰箱的,现在都要去造一个冰箱。不管是那种情况,我们彼此之前的路途相差并不远。

Q3: 英文基础不好学得来代码么?

还是说我自己,我高中英语常常全班倒数,大学英语没超过 65 分,英语四级刚过及格线,六级呵呵。

Q4: 数学基础重要么?

我高中时数学算好的,大学因为是工业设计,只上过一学期的高数。

其实在大部分情况下,学代码只要有初中级别的数学知识就好了。

Q5: 学代码是更像学英语还是学数学?

这个也是我没学代码前,一直萦绕在心头的问题。

现在我的感觉是,一开始你会觉得像在学英语,后来会觉得像在学数学。写代码很多情况有点类似于做数学证明题。

Q6: 需要哪些硬件设备?

学 iOS 开发,一台 Mac 和一部 iPhone 真的是硬性条件,没办法(啥,你说黑苹果配 iPod touch?我觉得认真点还是算了吧)。

学安卓要求会低一点,一台普通 PC 和一部 Android 机就可。

Q7: 需要会科学上网,会用 Google 么?

我家里没搭梯子,一直用的国内某搜索引擎。

如果你喜欢搭梯子和看英文文档,也是极好的。不喜欢也没什么可耻的,能找到知识,学到知识,会用知识才是本质。

有很多人说,Swift 强势来袭,没必要学 OC 了。

我也在工作的时候曾花了几个晚上,学过一点 Swift。不得不说,Swift 的程序逻辑真的很人性化,很简洁,很优雅。但是,现在学习的话为时尚早,不论是教学视频、demo 例子,还是疑难解答都少的可怜。很多时候,你想要一个效果都找不到资源来做。

而 OC 的话,已经非常成熟,从小白到高手之间的所有资源,网上都找得到。

Q9: 需要看什么书,有什么教学网站推荐,甚至是相关学习 app?

最后这部分,估计是大部分人最想知道的。

初学者可以先看看《Objective-C 基础教程 第 2 版》这本书,我当时看的是电子版,上下班时在地铁上用手机看。看了几天,大概到书一半内容的时候就云里雾里,完全看不下去了。我尝试过从头开始看,还是不行。

但是没关系,这很正常,你只要对 OC 这门语言有一定印象就行。就像一个冰箱,你知道它大概多大、多重,有什么形状等信息就好了。

我只看过极客学院和慕课网的,里面的教学视频良莠不齐。

我看过几个 OC 入门系列。每个视频的时间都不是很长,大概 10 分钟到 30 分钟,照着里面的步骤,依样画葫芦做下来就好了。

一开始很简单,后来的比较难,学完一遍就忘了,自己完全不知道怎么写。

但是没关系,这也很正常。你只要对 Xcode 这个工具有一定的印象就行了。就像一个冰箱,你知道它需要用电,可以冷藏,可以冷冻啥的这些信息就好了。

GitHub 是程序员们的乐园,但小白看一下就好了,你可能很久以后才会真正用到;

CocoaChina 是不错的论坛,小白也可以看看,以后有问题可以去这里;

Code4App 上有很多 demo 例子,入门之后做一些好的效果,可以去这里看看。

但一定要切记,真正动手做东西才是成长最快的方式,看书、看视频、逛论坛都只是辅助而已。

看到这里,如果你觉得自己有这些条件和觉悟,那就可以继续接着看,我做第一个 app 的经历。

我的第一款 App 开发经验

注:下面的内容会涉及到一些 iOS 的开发术语,如果你没有接触过 iOS 开发,可能会看不懂,我尽量用最简单的话来说明。

经验一:不要选择一个超出能力范围太大的 app 来做,先做一个技术含量最低的产品练练手,增长自信心。

2016 年的 6 月 16 日,我下定决心开始我的独立开发之路。

当时,虽然自己在过年前后看过一本入门的书和一些教学视频。但小半年下来,我已经忘得一干二净,甚至连 Xcode 的打开新建流程,还是找了之前的网页书签重新练了一遍。

我知道以我那时的水平,做个拍照 app 简直异想天开,估计连记事 app 也够呛。

我又急于做一个成品出来,这个成品不能是烂大街的计算器、天气预报这类,没有发挥余地的 app。所以,这个成品必须对技术要求很低,可以用其他比如创意或设计来弥补

看着自己手机里上百个 app,突然,我看到了一款符合目标的文字冒险游戏—— (生命线)。

如果剔除掉 Lifeline 的一切辅助功能,如推送、模式转换、语言更改等,它的核心技术点其实很简单,就是一个显示文字的视图和两个增加文字的按钮。

所以,我只要实现「点击一个按钮,让视图加一行字」这个功能,基本上就可以做出一款像 Lifeline 一样的 app 了。

(这是我当时真实的想法,后来发现核心技术远远不止这些,只能说幸亏当时这么单纯,不然就不可能一步步做下去了。)

经验二:一切以用户体验为中心,以目标产品为大方向。一步步从易到难解决问题,各个击破。沉迷于技术研究或设计细节只会误入歧途。

确定好产品方向之后,我开始制作 demo。

打开 Xcode,根据网上教程往 Storyboard(可以往里面拖各种控件的可视化工具,对新手很友好)上拖了一个文本视图和一个按钮。

我先在这个文本视图里打上一行字,如「苟利国家生死以」。接着要做的事就是,点这个按钮让文本视图增加第二行字「岂因祸福避趋之」。

我的直觉告诉我,这件事应该分为两个步骤:

  1. 先学会如何点一个按钮触发一个效果
  2. 再学会做一个效果,让文本视图加一行字

于是,我在某搜索引擎上搜索「iOS 如何点击按钮触发一个事件」,点开了几个搜索结果,找到一个看起来挺靠谱的教程,就照着做。同理,我又把加文字的功能学会了。

很快在这个视图里,就出现了两行字「苟利国家生死以」、「岂因祸福避趋之」。我每次点一下按钮,「岂因祸福避趋之」就会出现。

但是,我发现了一个问题:每行字挨得太近了。我很聪明地在「岂因祸福避趋之」前面加了两个回车符号,看起来就好多了。

在欣喜之余,我又发现一个问题:当我按钮点得多了,新增的「岂因祸福避趋之」会超出文本视图区域。难道让用户每次点一下按钮,然后手动滑上去么(太蠢了)?

我回头看了一看 Lifeline,发现他会把新增的文字顶上来,这样,就可以看到最下面的那句话了。

我又去网上搜教程,很快我就知道了让文本自动顶上来的方法。

经验三:做好 demo、设计稿、其他素材的准备,让你在学习开发的过程中没有后顾之忧,有万事俱备只欠东风之感。

就这样,我根据心里想的产品原型方向,一步步完善这个 demo。每当我遇到一个问题,就去找资料搜教程。解决完之后无比兴奋,但很快又会陷入新的难题当中。

在如此循环 N 次之后,终于完成了一款小明上学被车撞的超简单文字冒险游戏。在有了这样一个 demo 的基础上,我相信,要做出一个像 Lifeline 一样的游戏只是时间问题了。

所以,我开始放心地设计 UI 和编写故事,花了大约 4 天时间,经历了反复修改设计稿和小说情节的痛苦之后,一套 UI 和一纸故事文档已准备完毕。

经验四:一个好的老师是成功的一半,但不要一味的靠别人指点来解决问题,做伸手党只会让你毫无进步。

在接下来没日没夜的十几天时间里,我遭遇了一个个更高层级的技术挑战:

  • 如何加背景音和点击音效
  • 如何打包并提交 app

在此期间,我也数次遇到寻遍各种资料,也找不到解决方法的情况。但幸运的是,我的一个程序员朋友每次都能出手解决我的问题,并细心告知我其中的原理。

就像七龙珠里的设定一样,当赛亚人濒死时如果有幸(比如吃仙豆)死里逃生,就会成长很多。如果没有这位朋友,我可能已经死了不知多少回了。

就这样,2016 年 7 月 12 日成功上线了我的第一款产品——「0528」。

从 6 月 16 号正式走向独立开发的道路,到完成这款游戏,总共用了不到一个月的时间。

在这篇文章中,我回顾了自己从零开始学开发,以及第一次独立开发产品的所有经验。也希望自己的经验,能对想要零基础学开发的朋友提供帮助。

记住,真正动手做东西才是成长最快的方式

本文由让手机更好用的 AppSo 原创出品,关注微信号 appsolution,回复「开垦世界」获取本文作者韩重赞最新开发的游戏和背后的理念故事。

12,在有uinavigation,uitoolbar的情况下,如何添加一个全屏的 uiview (作为显示一个进度框,任何区域无法触摸而使用)
只需要在要添加view时侯这样写:

 这样,直接把waitingview添加到了uiWindow上,而不是self.view上。再次运行,会发现屏幕全部区域都已经遮挡住了。

13,使用了storyboard,运行程序模拟器显示黑屏
这是由于,操作不当,获取点击了例如 navigationViewController属性种的in init ViewController选项,然后重置了当前进入程序后的首界面,解决办法就是选择入口界面,属性种重新勾选此选项。


在项目中添加如下代码:

//设置自定义的图片:

5.0以上,api有了上面setBackgroundImage的方法,可以直接设置,如果项目需要适配5.0以下版本的设备,最好加一个判读,是否有此函数,有则设置,没有就通过drawRect方法设置。

在storyboard或xib中,添加一个uiview,属性设置栏一般都有设置背景颜色,样式,透明度alpha,但是没有提供设置image,只有在imageview中才有,所以,要想设置背景图片,只能在代码中设置,如下:

这样,背景就可以变成想要的图片了。另外,设置大小:

 //以下是通过id打开此软件的评价 

把以上代码直接拷贝到想要实现点击跳转的操作方法内就可以了,通过appID,随意可以通过appstore打开应用,直接用url就可以链接到了。很简单,一般都用在检查更新的时候。

// 处理发送完的响应结果

默认发送短信的界面为英文的,解决办法为:在.xib 中的Localization添加一組chinese

20,程序中获取软件的版本号和app名称



CFBundleVersion,标识(发布或未发布)的内部版本号。这是一个单调增加的字符串,包括一个或多个时期分隔的整数。
CFBundleShortVersionString 标识应用程序的发布版本号。该版本的版本号是三个时期分隔的整数组成的字符串。第一个整数代表重大修改的版本,如实现新的功能或重大变化的修订。第二个整数表示的修订,实现较突出的特点。第三个整数代表维护版本。该键的值不同于“CFBundleVersion”标识。 图片里的 Version 对应的就是CFBundleShortVersionString (发布版本号 如当前上架版本为1.1.0 之后你更新的时候可以改为1.1.1) Build 对应的是 CFBundleVersion(内部标示,用以记录开发版本的,每次更新的时候都需要比上一次高 如:当前版本是11 下一次就要大于11 比如 12,13 ....10000)

21,如何使屏幕一直保持唤醒状态?(就是不自动黑屏)
比如,如果我们做一个播放视频的功能时,想在播放的时候,不会自动进入屏保(黑屏)
只要在代码里加入这一行:

当然,在想要黑屏的时候还需要把它设置为NO(比如视频播放完毕时),不然屏幕会在此软件运行下一直亮着。

22,在Xcode中,文件名后小方框中的A(M或C)表示什么意思啊?



表示在版本控制中,自上一次提交以来,文件做了修改。貌似只有在带有版本控制的项目代码中才会显示,也就是说你的项目使用了SVN、GIT等工具后,会在Xcode中识别出来。

屏幕旋转一共有4个相关属性(旋转方向):


其中涉及到两个方法,在ViewController中默认会实现这个方法:

这个方法是声明此ViewController所运行屏幕旋转的方向,一共4种类型,全部允许返回YES,上图所示除了不允许上下颠倒,其余都可以。【注意,项目设置Supported Device Orientations 所支持的屏幕旋转类型并不影响此方法的设置,也就是说,哪怕Support只支持Portrait,方法里设置UpsideDown,此ViewController也会实现上下颠倒旋转的】

第二个方法,是我们比较常用的,也就是在设备即将以某个方向旋转之前,我们在其状态(方向)设置组件或view的Frame,bound,等需要改变的属性时所用到的方法。

所有旋转屏幕后需要改变组件尺寸属性的设置都可以在这个方法里面实现。

【注意,以上两个方法,在最新的ios6貌似已经不提倡使用了,除非要适应旧设备,新的旋转屏幕的相关方法可以网络搜索一下】
IOS6屏幕旋转详解(自动旋转、手动旋转、兼容IOS6之前系统)
ios旋转屏幕总结 详细教程
Ios5(三)屏幕的旋转和大小设置;

25,如何设置视图(view)在最上层?或是view1和view2交换?
我们在storyboard的一个视图里添加了一个view1用作快捷功能导航;然后在对应的viewController里实例化了一个Mapview的地图view2,大小是整个屏幕,这样一来,就把我们在storyboard中添加的view1覆盖了,这个时候,我们想把view1在地图view2的上面,该怎么做?


我们现在要做的就是把后两者对调一下,所以在self.view 中寻找一下看有没有replace相关的方法



就是这个方法,第一个参数是要进行调换的地图view2,第二个参数是调换后显示的view1。


//输入内容的长度 - textfield区域字符长度(一般=输入字符长度)+替换的字符长度(一般为0)

这样虽然也能限制位数为11位,但是如果通过放大镜把光标切换到之前的位数后,你照样可以输入,并且还会导致输入11位后,键盘上的退格(X键)无法使用,原因是:我们在location到达11位后,返回了NO,键盘无法相应:添加,修改,删除。这是很严重的。所以照着我上面的。方法解读:



其实现在刚明白,一个很简单的方法:

所以后者 是调用 VC的所在的导航控制器导航控制器自己自己作为VC的 navigationItem,是导航的叠加。

此时,如果需要,就得自己画导航过程中的返回按钮了。

iOS 6中NSString对象有些新的使用方法,可以让字符串转变成全部大写,全部小写,或者每个单词首字母大写。 代码如下所示:


36,如何获取手机硬件信息?

在需要判断屏幕尺寸的地方:


虽然运行效果是对的,但是系统连续调用了2次loadView和viewDidLoad方法,导致创建了2次UIView,造成了不必要的开销。
状态栏由显示变为隐藏,意味着屏幕的可用高度变长了,UIViewController的UIView的高度也要重新调整,因此系统会重新调用loadView方法创建UIView,创建完毕后再次调用viewDidLoad方法。

设置为YES后,UIImageView内部的按钮就可以被点击了
大部分app在启动过程中全屏显示一张背景图片,比如新浪微博会显示这张:


要想在iOS中实现这种效果,毫无压力,非常地简单,把需要全屏显示的图片命名为Default.png即可,在iOS app启动时默认会去加载并全屏显示Default.png。
也可以用其他名称来命名图片,在Info.plist配置一下即可:



配置过后,app启动时就会去加载并全屏显示lufy.png
在默认情况下,app显示Default.png时并非真正的"全屏显示",因为顶部的状态栏并没有被隐藏,比如下面的效果:


我只能说你的思路是对的,但实际上达不到想要的效果,你会发现显示Default.png时状态栏还是存在的,等Default.png显示完毕后,状态栏才被隐藏。
我先解释下为什么这种方法不可行,其实原因很简单:
1> Default.png是在app启动过程中加载的,并不是在app启动完毕后再加载的
下面说一下解决方案,在Info.plist中增加一个配置即可:



45,UITextField只有当有字符输入后,键盘右下角的搜索/返回/done/等等键才可以使用


46,类似QQ等IM软件,长度和高度不一的聊天气泡的图片是如何做的?拉伸?


其实是一个小气泡png,然后拉伸中间部分,四个角不拉动,就是局部拉伸。ios自带方法,四个角可以不拉伸的,如下:


48,ios如何在调试时,轻松找到程序在哪里崩溃?
我们给自己的工程添加一个通用的断点:



一步步按上面图完成操作。



自动就断点到这里来了,

这样很简单就能发现程序崩溃是因为value没有 isEqualToString方法。如果没加上面这个通用的断点,那程序会直接断点到main函数去。
49,UIImageView 如何实现windows 桌面类似的背景壁纸屏幕(很小的图片会显示N多个)?

下图所示:(原图是一个6X6的方格)


这样的话,第1行cell就应该是我们设置好的颜色,不过请注意,此方法在UITableViewStylePlain的风格下有效,在

使用系统或简单自定义的UITableViewCell时,当选中某一行Cell后,除了背景颜色改变外,Cell上所有的组件(数据)比如UILabel,UIbutton等都被自动显示成了其
Highlighted(高亮)状态下的效果,(如果想显示出效果,你的那些自定义的组件必须要设置高亮状态,比如highlightedTextColor,UIControlStateHighlighted等),所以这一点需要特别注意,如果不想要系统的这个自动特效,有两个解决办法:
2,如果自定义的Cell:

设置成员变量的@property属性时,默认为atomic,提供多线程安全。
禁止多线程,变量保护,提高性能。 atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定 nonatomic ,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了 nonatomic ,那么访问器只是简单地返回这个值。

assign 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char)等等。 此标记说明设置器直接进行赋值,这也是默认值。在使用垃圾收集的应用程序中,如果你要一个属性使用assign,且这个类符合NSCopying协 议,你就要明确指出这个标记,而不是简单地使用默认值,否则的话,你将得到一个编译警告。这再次向编译器说明你确实需要赋值,即使它是 可拷贝的。retain 对其他NSObject和其子类对参数进行release旧值,再retain新值 指定retain会在赋值时唤醒传入值的retain消息。此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数——译者注)。
注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1。copy 对NSString 它指出,在赋值时使用传入值的一份拷贝。拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效。更深入的讨论,请参考“复制”部分。

Copy其实是建立了一个相同的对象,而retain不是:1.比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同。
2.新的对象retain为1 ,旧有对象没有变化retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1。总结:retain 是指针拷贝,copy 是内容拷贝。

  1. 接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。2. 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。总结:上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int,

56,如何给UIbutton 同时设置图片(Image)和文字(Title)以及它们的各种状态?

代码中我设置button背景图片为自己定义的一个regionImage,并设置了button的title = “ 07:00”【注意,设置了背景图片后,title只能这样添加,以button.titleLabel.text方式添加会无法显示的】,并且设置了tiitle正常和高亮下文字颜色。
所以看到这里,应该明白button.setBackgroundImage 和 set Image 的区别了吧,前者是可以同时设置文字,后者是一旦设置了image,无法再显示文字。


57,如何将NSDate类型转化为距离的毫秒差?

58,ios中的全局静态变量
(1)第一种和C/C++中的一样, 使用"extern"关键词;
(2)另外一种就是使用单例实现。
(比如我们经常会把一个变量放在AppDelegate里面作为全局变量来访问, 其中AppDelegate就是一个单例类) 在Objective-C中如何实现像C++中那样的静态成员变量呢?你需要做的是在一个类A的implementation(.m或者.mm)文件中定义一个static变量,然后为A类定义静态成员函数(class method,也就是类方法)来操作该变量。这样在其它类中你就不需要创建A类的实例来对static变量进行访问。虽然该static变量并不是A类的静态成员变量,但是也算达到了同样的效果。static变量的作用域被限制在单一的文件中。

上面的例子中你就可以通过[Example instanceCount]对静态变量count进行访问,无须创建实例。警告: static 写在interface外面编译是没有错误的,但是编译器会报警告,这么说这样的写法是不被编辑器认可的。错误:static 写在interface里面会直接报错,显然这样的语法是不被认可的。
static关键字声明的变量必须放在implementation外面,或者方法中,如果不为它赋值默认为0,它只在程序开机初始化一次。
简单点的来,两个界面间传值,直接上代码了:



如上图所示,遇到这个错误,从字面的意思我们大致能猜到,是有属性已经被release掉了,但是我们又使用它了,所以,一部一部排查把,一定有某个地方的属性提前被release掉了,自己手动管理内存就会有这样的困恼,代码很多,不想去找,一定要有耐心,找的过程还可以学到很多知识。



如上图,这个就是我找到的原因所在,unarchiver release掉了,而我们在其它的类中想使用location的属性。

3.安装完成之后,打开终端,输入“svn help”,如果出现如下所示,说明命令行工具安装好了。


63,简单的冒泡排序法

C享app是一款超高返利的购物软件,采取帮砍的机制,用户可以把自己想买的商品分享出去,让好友帮自己砍价,砍价之后你们都可以获得商品优惠。并且软件还设置了职业帮砍价板块,用户也可以直接在这里找一起砍价的好友,最高返利可以达到90%。值得一提的是,软件还首创了报告实拍晒单,不仅口碑保证,并且每一条评论都是真实有效的,用户可以听到最真实的买家声音,还有全国范围内免费包邮送货到家,所有购买的商品都承诺7天无理由退换,大家可以放心的在这里挑选需要的产品。

1、超高的返利,专业买手推荐,职业帮砍价,返利高达90%
2、天天签到领积分,还可以领取红包可以直接提现当钱花
3、注册可享受0元购的商品超值优惠
4、潮流尖货任你挑,好看又有品
5、晒单报告实拍晒单,口碑保障,买的更放心
6、时尚专题明星达人教你搭配,时尚教母解读流行

1、提供的商品种类全面,都是大家生活中的必需品,各个方面的海量产品都有覆盖;
2、一个人在手机上购物就能满足全家老小的生活需求,每一个年龄段用到的产品都有提供;
3、主打省钱的购物模式,让您在购物中省下很多的钱,并且对于产品的质量也都是严格把关的;
4、全国范围内免费包邮送货到家,承诺7天无理由退换,有任何问题可以找客服积极解决;
5、为您提供最热门的网红爆款商品,在您购物的时候少花冤枉钱,避免踩雷的情况发生;
6、产品都是一些知名的供货商提供,保证了产品的质量,大家可以放心的在这里挑选需要的产品。

1、为您优化了体验细节。
2、更稳定、更优质,邀您一起体验。
3、新增任务签到模块。
4、首页新增主体页,以及更多优惠接口。
5、新增完善资料功能。

我要回帖

更多关于 CⅰU 的文章

 

随机推荐