FourV Zhang'Blog

开发随记,生活随笔,读书随感,旅游随心


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 搜索

APP上架被拒日常(1)- Information Needed

发表于 2018-06-06 | 分类于 发布上架 | 阅读次数

原文:

Guideline 2.1 - Information Needed
We have started the review of your app, but we are not able to continue because we need additional information about your app.
Next StepsTo help us proceed with the review of your app, please review the following questions and provide as much detailed information as you can.

  • Does your app access any paid content or services?
  • What are the paid content or services, and what are the costs?
  • Do individual customers pay for the content or services?
  • If no, does a company or organization pay for the content or services? - Where do they pay, and what’s the payment method?
  • If users create an account to use your app, are there fees involved?
  • How do users obtain an account?Once you reply to this message in Resolution Center with the requested information, we can proceed with your review.

译文:

准则2.1 -所需的信息
我们已经开始评估你的应用程序,但我们不能继续,因为我们需要更多的信息关于你的应用。
下一步
来帮助我们进行应用程序的审查,请检查以下问题,并提供尽可能多的详细信息
应用程序访问付费内容或服务吗?
付费内容或服务是什么?费用是什么?
个人客户支付内容或服务?
如果没有,公司或组织是否为内容或服务付费?
他们支付,支付方式是什么?
如果用户使用你的应用程序创建一个帐户,有涉及费用?
用户如何取得帐户?一旦你回复这个消息在解决中心所请求的信息,我们可以开始你的审查。

解决方案:

此一般出现在APP首次上线或者APP时隔一段时间提交一个大的更新版本时,按照译文所描述的,在问题中心的回复框里回复相关问题即可.不过也需要谨慎回复!!!

  • 如果APP中涉及到付费内容/付费服务,并且使用了苹果的内购(iap)支付,或者APP干脆没有相关的付费内容/付费服务,则可以如实回答;
  • 如果APP中含有付费内容/付费服务,但是不想使用内购(iap)支付给苹果分成,从而使用支付宝/微信/网银等第三方支付,则此处就需要编造一个善意的谎言,否定APP中的相关付费信息.

回复例句:
Our Application without access to any paid digital content and services, so will not involve the issue of pay for content. Our Application Have registered entrance application, the user can get an APP account function through registration
应用没有访问任何付费的数字内容或服务,所以更不会涉及到为内容付费的问题.应用有注册入口,用户可以通过注册功能获得一个APP账户

No accounts with itunes connect access have been found for the team "xxxx"

发表于 2018-03-26 | 分类于 发布上架 | 阅读次数

距离这一次打包发版很近的两三天前,xcode内配置文件和证书都正确无误,打包过程还很顺利!
这次打包出现如下图的问题

no account.png
在网上查找了好多相关问题的解决方法,都没能解决我遇到的问题;隔天在stackoverflow社区里,查找到了几个解决问题的方法,其中一个对我起到了很大的作用!
Xcode 9 “no iTunes Connect account” error when uploading

####解决方案1
采用little的解决方法
little.jpeg

  1. 关闭xcode
  2. 终端执行命令rm -fr ~/Library/Developer/Xcode/DerivedData/
  3. 重新打开Xcode,再次打包上传

####解决方案2
采用Jayprakash Dubey的解决方法
dubey.jpeg

1.打包生成IPA应用包
2.使用Application Loader 上传IPA文件!

不过才用上述两个方法的前提就是 确保Xcode里配置的描述文件和证书没有过期/失效,可以按照博客中的方法去检查。点击首张图左下角的 Manage Accounts去添加设置帐号信息。

1. 你点add,删掉你的账号,再添加一次上去,重启Xcode再来一遍试试
2. 检查你的证书、描述文件在开发者中心有没有过期,在Xcode有没有配置好
3. 如果你此时要做的是提交App上架审核的操作,请你打开Xcode,按 command+逗号 检查你账号的身份,member,admin,还是agent,只有agent才有权限提交上架

浅析collectionView的item间距

发表于 2018-03-13 | 分类于 研发随笔 | 阅读次数

ios开发中比较常用到的就是 tableView 和 collectionView,二者分别用于列表展示和 网格展示;由于tableView的易用性几乎每个APP都会用到; 相对tableView,collectionView使用起来比较繁琐,所以collectionView的使用不常见。但UICollectionView也有自身的特点,比如横向布局、多行或者多列(瀑布流)展示。

一、创建collectionView(collectionView控制器)
1
2
3
4
5
(collectionView)
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
(collectionView控制器)
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout ;

初始化类似tableView,设置delegate 和 datasource;
不同于tablView初始化设置UITableViewStyle,而collctionView初始化设置UICollectionViewLayout(一般用它的子类UICollectionViewFlowLayout)。
此处的UICollectionViewLayout是用于存储collectionView的一些布局属性:

1
2
3
4
5
@property (nonatomic) CGFloat minimumLineSpacing;
@property (nonatomic) CGFloat minimumInteritemSpacing;
@property (nonatomic) CGSize itemSize;
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
@property (nonatomic) UIEdgeInsets sectionInset;

cell间距的设置需要用到以上这些关键性属性。

二、布局协议

UICollectionViewDelegateFlowLayout

协议中有以下这几个和布局相关的方法

1
2
3
4
5
6
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;

这几个方法的功能和UICollectionViewLayout的4个属性基本相对应:
1.属性用于统一设置
2.对象方法既可以统一设置,也可以区别设置

这几个方法名的区别在后半部分

1
xxxxx sizeForItemAtIndexPath:(NSIndexPath *)indexPath

等同于属性 itemSize;

1
xxxxx insetForSectionAtIndex:(NSInteger)section

等同于属性 sectionInset;

1
xxxxx minimumLineSpacingForSectionAtIndex:(NSInteger)section

等同于属性 minimumLineSpacing;

1
xxxxx minimumInteritemSpacingForSectionAtIndex:(NSInteger)section

等同于属性 minimumInteritemSpacing;

三、图文解析对应属性(针对不同滚动方向)

collectionView布局.gif
gif中每个不同颜色代表不同的section

水平方向滚动.png

水平方向滚动的collectionView,竖直方向的间距是固定的:minimumInteritemSpacing指的是同一个section 内部item的竖直方向间隙;
minimumLineSpacing指的是同一个section 内部 item的水平方向间隙;

竖直方向滚动.png

竖直方向滚动的collectionView,水平方向的间距是固定的:minimumInteritemSpacing指的是同一个section 内部item的水平方向间隙;
minimumLineSpacing指的是同一个section 内部 item的竖直方向间隙;

总结:

minimumInteritemSpacing表示 同一个section内部间item的 和滚动方向垂直方向的间距;

minimumLineSpacing指的是同一个section 内部 item 的滚动方向的间距;
sectionInset指的是每个section内缩进;属性设置的每个section的内错进是相同的,都是正数。如果需要实现不同的setion的不同的内缩进,可以使用对象方法

1
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;

来实现。

注意:

在写demo的过程中,发现collectionView的contentInsetAdjustmentBehavior(等同于控制器的automaticallyAdjustsScrollViewInsets属性)默认为UIScrollViewContentInsetAdjustmentAutomatic枚举值,会自适应控制器的边距,避开导航栏和状态栏,而使得collectionView的真实高度 和设置的高度不一致(相差状态栏和导航栏的高度和)。

demo地址:https://github.com/NightSkyWatchers/collectionView,欢迎下载观摩指正,内有*彩蛋*

软件生命周期&&测试的工作流程

发表于 2018-03-01 | 分类于 技术拓展 | 阅读次数

软件的生命周期

1.问题定义及规划

解决用户的痛点,方便用户
软件开发目的以及可行性,制定开发计划。。。

2.需求分析
3.软件设计
4.软件编码

开发人员进行程序编码

5.软件测试

开发做,单元测试
开发or测试做, 集成测试
开发做, 系统测试
测试做,验收测试

6.软件维护

版本上线,产品上线,版本的升级改造,修复bug

软件测试的工作流程

接触到哪些岗位人员———-开发人员、产品经理、客服(收集用户反馈)、实施/技术支持/现场实施(驻场)、设计师
软件测试工作流程.png

系统学习---软件测试的分类

发表于 2018-03-01 | 分类于 技术拓展 | 阅读次数

1.按照测试阶段

单元测试,集成测试,系统测试,验收测试(正式验收测试,Alpha测试,Beta测试)

集成测试——-开发与开发之间的联调,接口测试
系统测试——整体全部功能的测试,不是模块的测试
Alpha测试—–前期用户测试,内部人员模拟实际环境进行验收测试(内测)
Beta测试——后期用户测试,通过内部测试,即将正式发布。 在一个或多个真实环境下发布版本进行公测。(预发步版本,公测,预测)

2.按照测试技术分类

白盒测试,黑盒测试,灰盒测试

白盒测试———- 知道程序内部代码逻辑,代码拿过来,输入测试数据就知道是否ok
黑盒测试———-不知道xxxxxxxxxxxx,通过表面的反应才知道是否ok
灰盒测试———-介于二者之间,既有xx,也有xx

3.按照被测试对象是否运行分类

动态测试,静态测试(文档检查,代码走查,界面检查)

4.不同测试手段

手工测试,自动化测试

5.按测试包含的内容划分

功能测试,界面测试,安全测试,兼容性测试,易用性测试,性能测试,压力测试,负载测试,恢复测试(灾备)

恢复测试—-主要检查系统的容错能力。采用各种办法强迫系统失败,然后验证系统能否在指定的时间间隔内尽快恢复并重新启动系统
易用性测试—-测试软件是否易用,主观性比较强

6.其他测试

冒烟测试,回归测试,探索性测试(测试思维)

详解:
冒烟测试——在真正测试开始之前,都会对应用版本 主干功能做一下测试,如果主干功能都测试不通过,就可以打回这个版本;

回归测试——-指之前提出的bug被修正后/软件功能发生变化后进行的重新测试,确认修改部分已经ok,并且不会对其他功能造成影响!
1.验证bug是否被修复
2.和该bug相关功能是否被影响

###软件测试是什么
定义:为了发现程序中的错误而执行程序的过程

1.为了发现程序存在的代码或业务逻辑错误
2.为了检验产品是否符合用户需求
3.为了提高用户的体验

软件测试的原则

1.测试应该尽早介入
2.所有测试追溯到用户需求
3.程序员英国避免检查自己的程序,除了单元测试,交给第三方/专业测试
4.设计测试用例时,应该考虑合法的输入和不合法的输入以及各种边界条件,意外状态
5.二八原则,测试发现的错误中80%很可能起源于20%的模块中(聚集效应,bug比较集中)
6.对错误结果要进行一个确认过程(必现,偶现;复现!!!)
7.制定严格的测试计划
8.完全测试是不可能的,测试需要终止(测试不是无休止的,没有明显bug测试就可以终止)
9.妥善保存测试过程中的所有文档

分享与支付中的磕磕碰碰

发表于 2018-01-29 | 阅读次数

1.分享菜单栏汉化

使用ShareSDK自带的UI分享界面,出现英文的分享界面!分享英文.jpeg
在cocopods中,能看到ShareSDK是有中英文名称的(国际化)

分享.png
所以只需要在项目的info.plist文件中增添一个 “Localizations”字段,并添加一个 “chinese (simplified)”即可切换为想要的汉化名称。
分享中文.jpeg

##2.分享微信– bundle id验证不通过

部分手机分享不正常,(ios9,ios10 OK, ios11.2出现此问题)
bundle ID验证不通过.png
这是微信有段时间开始验证项目的bundle id相关信息,
1)去微信的开放平台(https://open.weixin.qq.com)查看注册的应用是否包含ios平台,如若不包含ios平台,请添加!!
微信开放平台.jpeg

2)注册的应用的bundle id 和项目的bundle id是否一致,如果不一致,修改一致!

3.微信支付,调不起微信App

可能存在的问题
1)

1
2
3
4
5
6
7
8
9
//调起微信支付
PayReq* req = [[PayReq alloc] init];
req.partnerId = model.partnerId;
req.prepayId = model.prepayId;
req.nonceStr = model.nonceStr;
req.timeStamp = model.timeStamp;
req.package = model.package;
req.sign = model.sign;
[WXApi sendReq:req];

这些是调起微信app的关键值,如果这些值中任何一个值不存在都会发生调不起微信app的可能!

打上全局断点就崩溃在main函数上

发表于 2017-11-30 | 分类于 研发随笔 | 阅读次数

不打全局断点能正常运行,打上全局断点就崩溃在main函数或者应用的其他莫名其妙的位置
可能原因
1. 当前应用在播放音视频文件,点击继续运行就可以了
2. 项目里面用了C++或者其他语言写的东东,可能会这样,all exceptions就表明,所有exceptions都会被catch,即使这个exception在代码里已经处理了的,也会被catch,高亮.如果是因为C++导致的,你可以右键点击all exceptions编辑将exception->all改为objective-c.如果不是这个原因,那你也不用管.

安装mysql(Mac)

发表于 2017-11-10 | 分类于 技术拓展 | 阅读次数

1.从官网下载dmg格式的安装包
官网下载安装包.png

2.双击下载的安装包,按‘‘继续’’/‘‘同意’’直到最后安装完成
继续.png

同意.png
安装.png

授权.png

3.为了方便使用,设置全局变量
打开终端(Terminal),
1)cd ~

2)如果没有 .bash_profile文件,会创建该文件
touch .bash_profile

3)打开并编辑.bash_profile文件
open .bash_profile 使用文本编辑器打开 .bash_profile文件
或者 vi .bash_profile 直接在终端界面编辑 .bash_profile文件

4)在.bash_profile文件中添加路径
export PATH=${PATH}:/usr/local/mysql-5.6.38-macos10.12-x86_64/bin
路径中 mysql-5.6.38-macos10.12-x86_64和下载的安装包的名称保持一致
mysql安装包.png
5) 保存并关闭.bash_profile文件
文本编辑器打开—保存(command+s) 关闭(command+w)
终端编辑的打开————-输入:wq

6)更新刚配置的环境变量
source .bash_profile

4.启动mysql服务器
打开系统偏好设置——>Mysql——>Start Mysql Sever
mysql连接状态.png

5.登录
终端输入mysql -u root -p
会提示输入密码,如果没设置过密码就直接按enter略过;
当看到 Welcome to the MySQL monitor.xxxxxx字样,表示登录成功

hexo+git一步一坑搭建博客

发表于 2017-08-07 | 分类于 技术拓展 | 阅读次数

根据这篇文章使用hexo+git搭建真正属于自己的博客的过程中是很顺利的,但是还是在部署到远程仓库的时候还是遇到了以下几个问题:

1
2
3
4
deploy:
type:git
repository: [email protected]:xxxxxx.githup.io.git
branch: master

1.修改了配置_config.yml文件之后,执行部署命令 hexo g/ hexo s,报错如下:

1
2
FATAL bad indentation of a mapping entry at line 81, column 13:
repository: https://github.com/NightSkyWat ...

原因:hexo语法比较严格,在修改配置文件_config.yml之后,一定要检查冒号后面的空格!!!检查冒号后面的空格!!!检查冒号后面的空格!!!

解决:将修改部分type/repository/branch后面都有一个空格

2.修改问题1之后,执行部署命令hexo d,报错如下:

1
ERROR Deployer not found: git

原因:部署远程博客前,需要安装git
解决:执行该命令 npm install hexo-deployer-git --save

3.使用SSH KEY,本地生成id_rsa 和id_rsa_pub文件,并复制id_rsa_pub文件中的内容添加到帐号之后,部署(hexo d)报错:

1
2
3
4
5
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html

测试当前的SSH是否配置成功,在git bash 中执行命令ssh -T [email protected]报错如下:
Permission denied (publickey).

原因:说明当前SSH没有配置成功

解决:
请确保以下2步均做到
1、远程服务器已经有了对应于本地主机上公钥
2、本地主机ssh服务开启(windows上是ssh-agent.exe运行),并且本地主机私钥要包含在ssh服务列表中

第一步已经完成,:已经将id_rsa_pub文件中的内容添加到了github帐号

检查本地私钥是否存在于ssh服务中

1
2
cd ~/.ssh
eval 'ssh-agent -s'

如果运行这句出现Could not open a connection to your authentication agent,那么就先运行
ssh-agent bash
再运行
ssh-add -l
如果不存在,需要添加进去
ssh-add ~/.ssh/id_rsa
添加完成之后,再执行ssh -T [email protected]测试SSH是否配置成功!!!

如果出现以下内容说明配置成功

1
2
Hi username! You've successfully authenticated,
but GitHub does not provide shell access.

4.执行终端命令hexo s,并在浏览器里输入https://localhost:4000后,可以预览到修改的相关内容,但是部署到远程仓库后(成功部署),打开对应的http://username.githup.io网址却出现以下充斥着形形色色广告的界面,到底是什么原因导致的呢?

仓库名称错误.png
最后经过排查找出错误原因:
因为自己错误的拼写习惯,错把github拼成了githup,
修改了 userName.github.io 和 _config.yml中repository:键值之后,顺序执行 hexo clean / hexo g /hexo d命令重新部署到远程仓库, 并进入对应的 http://username.github.io

###大功告成!!!

参考
github设置添加SSH
Permission denied (publickey)
Hexo博客搭建中的坑
5分钟 搭建免费个人博客

梳理易引起retain-cycle的场景(使用block)

发表于 2017-08-03 | 分类于 研发随笔 | 阅读次数
  • 开发以及面试中,经常涉及到使用block的需要注意的问题—-循环引用,趁此时机梳理相关block引起循环引用的场景:
  1. 使用通知(notification) 系统自带的block方法,在block中使用self–>会发生循环引用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    TwoVC .m文件
    -(void)dealloc {
    NSLog(@"%s",__func__);
    }
    - (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor orangeColor];
    // Do any additional setup after loading the view.
    //__weak typeof(self) weakSelf = self; //弱引用
    [[NSNotificationCenter defaultCenter] addObserverForName:@"testBlock" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
    //__strong typeof(self) strongSelf = weakSelf;
    NSDictionary *userInfo = note.userInfo;
    NSLog(@"userInfo--%@ -- self.view - %p",userInfo,self.view);
    }];
    }
    - (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    NSLog(@"%s",__func__);
    }

控制台输出

1
2
3
4
2017-08-02 17:09:31.131 testBlock[36251:3586073] userInfo--{
Project = testNotificationBlock;
} -- self.view - 0x7fff0b501980
2017-08-02 17:09:34.073 testBlock[36251:3586073] -[TwoVC viewWillDisappear:]

######结论: 当前VC没有被释放,添加弱引用后,VC被释放掉;存在retain-cycle

  1. 使用MJRefresh框架中返回上下拉刷新的block方法,在block中使用self–>会发生循环引用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    ThreeVC .m文件
    -(void)dealloc {
    NSLog(@"%s",__func__);
    }
    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
    self.tableView.dataSource = self;
    // __weak typeof(self) weakSelf = self;//(弱引用)
    self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
    // __strong typeof(self) strongSelf = weakSelf;
    NSLog(@"MJrefresh --下拉刷新");
    [[NSNotificationCenter defaultCenter] postNotificationName:@"testBlock" object:nil userInfo:@{@"Project":@"testNotificationBlock"}];
    [self endrefresh];
    }];
    [self.tableView.mj_header beginRefreshing];
    [self.view addSubview:self.tableView];
    }
    - (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"%s",__func__);
    }

控制台输出

1
2
3
4
5
2017-08-03 10:39:44.381 testBlock[37278:3717266] MJrefresh --下拉刷新
2017-08-03 10:39:44.382 testBlock[37278:3717266] userInfo--{
Project = testNotificationBlock;
} -- self.view - 0x7f8747406440
2017-08-03 10:39:55.641 testBlock[37278:3717266] -[ThreeVC viewWillDisappear:]

######结论: 当前VC没有被释放,添加弱引用后,VC被释放掉;存在retain-cycle

3.强引用自定义的属性block,并在block中使用self–>,会引起循环引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** block */
@property (nonatomic, copy) void(^myblock)();
@end
@implementation FourVC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
_myblock = ^ {
NSLog(@"--%p",self.view);
};
_myblock();
}

控制台输出

1
2
2017-08-03 11:17:51.409 testBlock[37510:3750978] --0x7f8e7d70b460
2017-08-03 11:17:55.696 testBlock[37510:3750978] -[FourVC viewWillDisappear:]

######结论: 1)报警告 2)当前VC没有被释放,添加弱引用后,VC被释放掉;存在retain-cycle

未完待续,欢迎指正/添加
测试代码奉上

1234
FourV Zhang

FourV Zhang

记录生活的点点滴滴,待岁月逝去,回首往事,嘴角扬起久违的笑容

32 日志
4 分类
5 标签
© 2018 FourV Zhang
由 Hexo 强力驱动
主题 - NexT.Pisces