3 days from zero to the AppStore process record

3 days from zero to the AppStore process record

Just a week after the Qingming holiday, I got my wish and put an app I wanted on the AppStore

From the idea to the technical selection, from the design draft to the framework development, from the review of the AppStore to the launch, it took a total of 3 days. During these 3 days, I stepped on a lot of pits and was very busy. During the period, I found that a lot of information on the Internet was outdated. So with a summary idea, I wrote this article.

One, idea to design draft

(1) Source of idea inspiration

Usually I’m very busy at work, and when I’m at leisure, I swipe my phone to watch videos from station B and Youtube, but because I follow too many people, I only want to watch those few, but I can’t help but click on the videos recommended by the algorithm.

  • "xdm clean and hygienic"
  • "Don't be like this, man"
  • "Guarding every unrealistic dream"

Station B is rich in content. Not only can I not see the video I want to watch every time, but it takes several times longer than expected.

So I want to make a product, I like to be able to help me track the dynamics of the people I want to follow most on the B station and Youtube platform, I don't need to open the B station and Youtube every time to check the content, so I schedule it according to my daily work. The process schedules functions for itself:

- 喵酱爱订阅
	- 展示导航栏
	- 搜索页面
	- 写搜索的cgi
	- 写解析用户状态的cgi
	- 要支持右滑取消订阅
	- 把用户状态数据更新到缓存
	- 把缓存落到DB
	- 每次启动读取DB
	- 制作宣传视频
	- 制作启动教育页
	- 联系页
	- 联系跳转等页面
	- 性能优化
	- 加一个by xxx 关注,然后谈起一个半屏
	- 加一个  xx、yy和另外x人关注了此账号
	- 需要加入loading等逻辑
	- 全局extension call:按id注册,还是全部接收
	- 开始更新订阅数据

- 搜索页面
	- 出现导航栏
	- 出现关闭按钮
	- 点击搜索要能过渡到另外一个搜索界面
	- 开始接B站搜索的api
	- 开始实现订阅该Up主功能
	- 滑动删除
	- 搜索交互调整

- 订阅数据
	- 开始更新订阅数据,获取更全的信息
	- 按timeline排序


接下来要做的:
	- 支持Youtube订阅
	- 完成B站跳转逻辑
	- 完成Youtube跳转逻辑
	- 完成清理红点逻辑
	- 调整搜索中间页逻辑
	- 「关于」页面设计
		- 帮助和常见问题
		- 隐私政策
	- 视觉还原和调整(添加约束)
		- 添加主页元素的联动约束
		- 主页下滑不到最底部
		- 导航栏颜色问题
	- 修bug
		- 订阅完之后,不会立刻出现
	- Youtube API无限调用
	- App选一个图标
复制代码

(2) Make the design draft by yourself

After having the idea, according to the serious development process, it is equivalent to determining the product plan, and then the design draft is required.

Consulted with design colleagues in the company, they gave two suggestions: SketchOr Figma, choose Figmathis .

After choosing the software, it took half a day to draw a simple design draft:

Here I want to blow the software of Figma. It really doesn't take a long time to get started from scratch. It's really "just have a hand".

2. Framework selection and development

(1) Basic framework

First of all, let me say that this software is written in Objective-C, why not use Swift? Because the basic libraries I accumulated before were all written in Objective-C, I chose Objective-C for the sake of speed.

1. Clean up main.storyboard

A slightly larger project will not use main.storyboard, so we first clean up main.storyboard and change it to pure code mode.

(1) 删除main.storyboard和launchScreen.storyboard,右键delete-Move to Trash

删除SceneDelegate.h和SceneDelegate.m文件,也要选择Move to Trash

(2) 选中工程 - General - Deployment Info - Main Interface 设为空

App Icons and Launch Images - Launch Screen File 设为空

(3) 删除 Info.plist 下 Application Scene Windows

(4) 在AppDelegate.h 和AppDelegate.m文件中添加如下代码:

self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
BNMainViewController *vc = [[BNMainViewController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
复制代码

(5) 注释掉 AppDelegate.m 中的 Lifecycle 代码

   #pragma mark - UISceneSession lifecycle

//- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
//    // Called when a new scene session is being created.
//    // Use this method to select a configuration to create the new scene with.
//    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
//}
//
//
//- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
//    // Called when the user discards a scene session.
//    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
//    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
//}
复制代码

(6) 展示导航栏

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {新增:

[[UINavigationBar appearance] setTitleTextAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:18], NSForegroundColorAttributeName : [UIColor whiteColor]}];
复制代码

2. Cocoapods和基础库

之前我问过一些大学里的学生,学完iOS知识后为什么不自己尝试做一个项目呢?年轻人有想法有精力的,他们中有一些人的回答是:"太麻烦了,iOS语法真繁琐"

我有点惊讶,iOS的语法为什么会繁琐呢?后面和他们深入聊的时候才发现他们大多数人是因为缺少基础库,导致他们开发门槛非常高。

比如哪些基础功能呢? 最常见的就是:

@interface UIView (Extension)
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
@property (nonatomic, assign) CGFloat centerX;
@property (nonatomic, assign) CGFloat centerY;
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat height;
@property (nonatomic, assign) CGSize size;
@property (nonatomic, assign) CGPoint origin;
@end
复制代码

布局是项目中最高频出现的,一个新项目如果你没有做 UIView 如上的category方法,那么你每次改变一个frame都要写全,相当繁琐。

还有一些比如支持SVG图渲染、自定义颜色、导航栏状态栏默认高度等等,就是因为这些基础的逻辑无形中提升了开发的门槛。

所以我在项目中集成这些能力后,将这些基础能力抽成一个项目,如果想开发App的基础这个项目开发上手速度会更快:

一个通用的iOS开发底层模板(持续更新)

项目集成了如下的库:

	pod 'YYKit'
	pod 'Colours'
	pod 'SDWebImage'
	pod 'SVGKit', :git => 'https://github.com/SVGKit/SVGKit.git', :branch => '3.x'
	pod 'WCDB'
	pod 'AFNetworking', '~> 3.1.0'
	pod 'ViaBus'
	pod 'FCAlertView'
	pod "Aspects"
复制代码
  • YYKit:提供各种基础通用能力的库
  • Colours:一个提供比系统更全的颜色库
  • SDWebImage:https图片加载框架
  • SVGKit:SVG图加载框架
  • WCDB:通用强大的iOS本地数据库
  • AFNetworking:开源的http网络请求框架
  • ViaBus:订阅总线框架
  • FCAlertView:比系统alertView功能更强大的类
  • Aspects:业内公用Num.1的AOP框架

因为使用cocoapods集成了基础库,所以下载使用前先执行 pod install

(二)B站、Youtube API 和 PostMan调试

1. 我是如何获取API的?-Chrome开发者模式

既然要搜索订阅的up主,那么就需要获取blibil和youtube的查询api,那怎么获取 B站 的API呢?

我们知道 Chrome 的开发者模式可以抓取网络请求,所以我们按照下面的流程操作:

打开B站的搜索界面:

然后打开Chrome浏览器自带的 开发者工具:

打开之后界面是这样的:

接着我们重新刷新界面,让开发者工作抓到我们的网络请求:

可以看到「网络」这一栏出现了如此多的网络请求回包,其中有一个网络请求就是我们查询B站的接口,我们如何快速从中获取我们想要的API?

我们在「响应」这一栏中可以看到网络回包的结果:

{
	"code": 0,
	"message": "0",
	"ttl": 1,
	"data": {
		"seid": "1742183592668294498",
		"page": 1,
		"pagesize": 36,
		"numResults": 1,
		"numPages": 1,
		"suggest_keyword": "",
		"rqt_type": "search",
		"cost_time": {
			"params_check": "0.000513",
			"get upuser live status": "0.002915",
			"illegal_handler": "0.012658",
			"as_response_format": "0.003668",
			"as_request": "0.023251",
			"save_cache": "0.000952",
			"deserialize_response": "0.000201",
			"as_request_format": "0.000448",
			"total": "0.045491",
			"main_handler": "0.027793"
		},
		"exp_list": {
			"7706": true,
			"5507": true,
			"6604": true
		},
		"egg_hit": 0,
		"result": [{
			"type": "bili_user",
			"mid": 41487006,
			"uname": "木南之的技术生活",
			"usign": "腾讯iOS开发工程师,有一只仓鼠(二狗)一只猫(芝士),我的网站:https://bninecoding.com",
			"fans": 2,
			"videos": 7,
			"upic": "//i2.hdslb.com/bfs/face/2399a9747dbc4449139da82cbaff23e332a8d94d.jpg",
			"face_nft": 0,
			"verify_info": "",
			"level": 4,
			"gender": 1,
			"is_upuser": 1,
			"is_live": 0,
			"room_id": 22106726,
			"res": [],
			"official_verify": {
				"type": 127,
				"desc": ""
			},
			"hit_columns": ["uname"]
		}],
		"show_column": 0
	}
}
复制代码

可以看到 data->result 中发现了 木南之的技术生活 的信息,而且还是一个标准的json格式,这肯定就是我们需要的 api了,我们点击请求头把请求api拷贝出来:

https://api.bilibili.com/x/web-interface/search/type?__refresh__=true&_extra=&context=&page=1&page_size=36&order=&duration=&from_source=&from_spmid=333.337&platform=pc&highlight=1&single_column=0&keyword=木南之的技术生活&category_id=&search_type=bili_user&order_sort=0&user_type=0&dynamic_offset=0&preload=true&com2co=true
复制代码

里面有一些我们用不上的参数,经过精简,我们得到如下的B站查询接口api:

https://api.bilibili.com/x/web-interface/search/type?page=1&page_size=5&search_type=bili_user&order_sort=0&user_type=0&keyword=木南之的技术生活
复制代码

2. B站、Youtube API大公开

(1)B站搜索API

https://api.bilibili.com/x/web-interface/search/type?page=1&page_size=5&search_type=bili_user&order_sort=0&user_type=0&keyword=木南之的技术生活
复制代码

(2)B站获取发表内容API

https://api.bilibili.com/x/space/arc/search?mid=xxxxx
复制代码

(3)Youtube搜索API

https://youtube.googleapis.com/youtube/v3/search?part=snippet&maxResults=5&type=channel&key=秘钥&q=搜索内容
复制代码

秘钥可以在 Google Youtube API 上注册获取,免费但有每日调用约束。

(4)Youtube获取内容API

https://youtube.googleapis.com/youtube/v3/search?part=snippet&order=date&type=video&key=秘钥&channelId=xxxx

复制代码

3. PostMan API调试利器

在调整API期间,我使用了 PostMan 这款API调试利器,可以非常方便帮我们验证究竟是iOS的代码有问题,还是接口的问题。

三、提审AppStore斗智斗勇

iOS 打包和上架流程可以参考这篇文章,iOS App的打包和上架流程

我按照这篇流程走下来,基本没踩什么坑,如果你要进行iOS App的打包和上架,建议你先看完上面这篇文章,然后再看我下面的补充:

在使用 Xcode - Product - Archive - upload 打包上传后,我们预期是能在 Apple Development 提审网站 的 「构建版本」 看到我们上传的ipa包的

但实际上会发现我们 upload 后,大约要等上个 10分钟 左右,才能在网站上刷到我们上传的包,是什么原因呢?

是因为Apple会对我们上传的包进行一遍静态代码扫描,比如调用私有API、使用过期无法维护的组件都会被reject,比如我下面收到的一个警告:

ITMS-90809: Deprecated API Usage - New apps that use UIWebView are no longer accepted. Instead, use WKWebView for improved security and reliability. Learn more (https://developer.apple.com/documentation/uikit/uiwebview).
复制代码

意思很清楚,说我们不能在项目中使用 UIWebView ,因为已经被废弃了,建议我们改用 WKWebView,我们按建议修改即可。

当静态代码扫描通过后,我们会收到如下一封右键,这就表示我们可以提审ipa包了,我们添加构建版本即可。

Guess you like

Origin juejin.im/post/7084593544744140813