Developer J.K.

明明可以靠颜值吃饭但偏偏想要写代码做产品的jaykon

Cocoapods遇到的问题

Cocoapods方便了集成和管理第三方类库,但其使用起来也不是一个省油的灯,这里记录一下遇到的问题和解决办法:

使用方法

请见唐巧的文章《用CocoaPods做iOS程序的依赖管理》

里面也提到一些问题,但说到使用镜像问题,还是放弃吧,

在执行初始化时,第一次一般卡定在 Setting up CocoaPods master repo 很久。

毕竟唐巧写文章时才80M,现在已经是400多M,而且是从github上下载下来,经常失败,他说到使用国内镜像,但现在已经无效,oschina已经几个月没更新,gitcafe迁到Coding.net后也没有做镜像了。那我觉得最土的方法是将最新的(2016-11-8)的索引文件下载下来,第一次直接从网盘下载吧:

https://pan.baidu.com/s/1pLGpZL5

密码:5293

下载解压好,放到

1
~/.cocoapods/repos/master

然后执行

1
pod install --verbose --no-repo-update

升级后,首先终端执行pod指令报错,需要重新安装

1
sudo gem uninstall cocoapods

然后可能有选项

1
2
3
4
5
6
7
8
Select gem to uninstall:
1. cocoapods-0.29.0
2. cocoapods-0.32.1
3. cocoapods-0.33.1
4. All versions
> 4

in addition to the gem? [Yn] n

再执行

1
gem install xcodeproj

接着安装

1
sudo gem install cocoapods

测试是否安装成功

1
pod --version

版本0.34后,可以项目会因为找不到 ”../Pods/Pods-environment.h“

找到类似以下代码

1
2
3
#ifdef COCOAPODS
#import "../Pods/Pods-environment.h"
#endif

改为

1
2
3
4
5
#if __has_include("Pods-environment.h")
#import "Pods-environment.h"
#else
do something......
#endif

3、ERROR: While executing gem … (Errno::EPERM)Operation not permitted - /usr/bin/pod

新系统使用如下指令安装

1
sudo gem install -n /usr/local/bin cocoapods

Apple iOS Rejects Collection

翻了一下记录才发现,第一次被苹果决绝已经是很久以前的事情,从2012年6月14号通过了第一个用黑苹果开发的应用《天下3》,一直以来也被虐了N次,时至今日,每次收到进入审核状态的邮件时,心里依然忐忑,都没什和把握,唯将一些惯犯记录整理一下。

当然,过去不代表未来,有一些点可能在过去某个时间抓得比较紧,也会有某个新的点在未来某天开始抓,没事多看看最新风向是必要的,另外,stay foolish(意思是老乔叫你保持被虐的心态)

苹果审核被拒绝大全,不断更新

Metadata 部分

  1. App标题不要明显地堆砌关键字,过度ASO会被拒绝
  2. 哪怕你的软件是17+,但是,在AppStore的介绍的图片和内容必须是4+的,
  3. 产品介绍和介绍图绝对不要出现的字眼,尿性如:逼格、逗比(逼)、牛逼、绿茶婊,苹果婊…
  4. 介绍不要提及隐藏起来的功能(为什么要隐藏,你懂的 #_#)
  5. 对于App本身的描述,不要出现”demo”、”trial”、 “test”、”测试版”、”Beta“
  6. 不要提及其它平台或产品字眼或图片,比如”Android”,其它品牌手机
  7. 因为后台一直调用定位信息,需要在app描述里附上一句“持续调用位置信息会很快消耗电池电量”。

功能部分

  1. 不要有”检查版本更新“这个功能
  2. 不要出现”敬请期待“、”即将推出“等占位符元素或入口,未完成就不要出现
  3. 操纵或欺骗用户影响app排名的行为是禁止的,比如引导用户五星好评等
  4. 支付苹果管得严格大家都懂的,总的来说:苹果不允许使用外部支付来购买内部的功能,不允许使用内部支付(IAP)购卖外部的实物,购买的积分,虚拟币只能在应用内部使用
  5. 真钱赌博,必须符合当地法规,并且必须免费,不能使用IAP充值
  6. 有排行榜时,用户填资料时需要弹出给用户知情,他的资料会参与排行榜。(游戏类应用经常会因这个被拒)
  7. 用了QQ第三方登陆,如果用户没有安装QQ的话,使用QQ登录会进入引导下载QQ页面,结果被苹果退回审核
  8. App没有自己的账号体系,只采用了第三方登陆被拒
  9. 需要用户注册,获取用户信息时,必须要有”隐私条款”
  10. 注册的时候,账号格式不要只限定邮箱,可以是其他格式,如果限定死,就会被拒。
  11. 注册时,苹果要求性别和头像都可以非必填。
  12. 如果软件需要用户注册才能使用,建议在审核备注里说明注册的必要性,免得浪费时间和他们扯皮

Apple Watch

  1. 因为在Apple Watch上面显示了时间被拒绝了,理由是你目前不能这样做

Extentions

  1. Extentions不能含有广告、营销、支付的功能

APP内容部分

  1. UGC产品没有举报功能被拒
  2. 出现“测试”,“Demo”等类似信息易被拒绝,比如提供给苹果的帐号昵称是“测试1”…
  3. 涉及到奖励,要显著表明和苹果无关,奖品尽量不要使用苹果产品
  4. 不要拼错苹果产品名称,比如Iphone,iphone,IOS,ios等会被拒

视觉和交互部分

  1. 按钮不能点击需要呈现一种不能点击的视觉,比如置灰或隐藏
  2. 网络读取内容为空时,需要有空状态,否则苹果会认为异常拒绝
  3. 界面和功能不能和苹果已有应用太像
  4. 出现和iphone桌面一样的ui风格(就是说出现圆角的icon并且按照桌面风格排列)被拒
  5. 不要隐藏Status Bar,或将其用作提示区域
  6. 符合《iOS Human Interface Guidelines》 《Apple Watch Human Interface Guidelines》

技术部分

  1. 任何界面,不能出现加载不出来的错误,比如必现的“网络错误”。
  2. 运行在iPad上不要有什么异常状况,苹果基本上用iPad进行使用审核(穷嘛)。
  3. 有个内置的IAP收费的VIP商品,我们我们用的是Consumable类型,苹果认为这个是持续性的应该算是Auto-renewable subscriptions,所以被拒(要选对商品类型)
  4. 本地储存要符合iOS Data Storage Guidelines ,比如不要将没必要的大文件放进itunes同步

附:竞赛、赌博、彩票以及抽奖Guideline

  1. 赌博和竞赛必须由应用程序的开发者或者app所属公司发起。
  2. 应用程序必须展示赌博和竞赛的正式规则,并声明苹果不是发起者,也没有以任何方式参与活动。
  3. 开发者运营一款具有抽奖性质的应用必须经过法律允许,并且抽奖应用必须具备以下特征:报酬、机会以及奖品。
  4. 允许用户在应用中直接购买彩票或彩券的应用将会被拒。
  5. 提供真钱游戏(比如体育博彩、扑克牌、赌场游戏以及赛马)的应用程序必须有应用使用区当地必要的许可和允许,必须限制在这些区域,必须可以从App Store免费下载。
  6. 使用IAP购买信誉或者货币,且结合真钱游戏的应用将会被拒绝。

Git的日常

第一步当然把代码Clone下来进进行管理

1
git clone git@192.168.1.1:xxx.git

习惯性动作

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
31
32
//当面代码有哪些文件修改了
git status

//当前所在分支
git branch

//更新代码
git pull

//查看提交记录
git log

//将新增的文件加入版本管理
git add . //全部加入
git add [file] //单个加入


//提交代码:建议每完成一件事都提交代码,注释很重要
git commit -a -m"我随意改一下,别生气"

//将代码推到服务端
git push

//从当前分支新建分支
git checkout -b dev
git push --set-upstream origin dev //当这个分支需要推送到服务器时,须执行如下指令

//切换分支
git checkout dev

//将dev合并到当前分支
git merge dev

删除分支

1
2
3
4
5
//删除本地分支
git branch -D dev

//删除远程分支
git push origin --delete dev

查看本地和远程分支

1
git branch -a

Tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//新增tag
git tag v2.2.0

//推送到服务器
git push —-tags

//删除tag
git tag -d v1.0.0

//从服务器删除tag
git push origin :refs/tags/v1.0.0

//checkout某个tag 变成一个新的分支
git checkout tags/<tag_name> -b new_branch

恢复到某个版本

1
2
3
4
5
//首先,查看一下版本记录
git log //每次提交都写注释的好处来了

//挑一个版本号进行恢复
git reset –-hard 9aa51d89799716aa68cff3f30c26f8815408e926

单独文件恢复到某个版本

1
2
3
4
5
6
7
8
//查看文件修改记录
git log -p /model/abc.xib

//恢复文件
git reset 9aa51d89799716aa68cff3f30c26f8815408e926 [文件路径]

//如查本地正在编辑且未commit这个文件,需要checkout一下
git checkout /model/abc.xib

直接在远程恢复到某个版本(一般很少用到)

1
2
git reset --hard <commit-hash>
git push -f origin <branch>

正在开发,须要去修改别的分支的BUG,但又不想提交当前代码

1
2
3
4
5
6
7
8
9
10
11
12
13
//现在代码变成最后提交的版本,刚刚正在编辑的代码已经暂存到缓存区
git stash

//切换到另一分支修改代码
git checkout dev
git commit -a -m"修改紧急的BUG"
git push

//回到原来的分支
git checkout

//恢复现场,可以继续开心地coding
git stash pop

暂时只想到这么多了,有更好用的场景求指点

其实更重要的是版本管理的策略和思路,具体可见文章 《Git分支管理策略》 《Git手册》

审核被拒,检查第三方接口被调用情况

收到苹果的拒绝:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Reasons Program License Agreement PLA 3.3.12

We found your app uses the iOS Advertising Identifier but does not include ad functionality. This does not comply with the terms of the iOS Developer Program License Agreement, as required by the App Store Review Guidelines.

Specifically, section 3.3.12 of the iOS Developer Program License Agreement states:

"You and Your Applications (and any third party with whom you have contracted to serve advertising) may use the Advertising Identifier, and any information obtained through the use of the Advertising Identifier, only for the purpose of serving advertising. If a user resets the Advertising Identifier, then You agree not to combine, correlate, link or otherwise associate, either directly or indirectly, the prior Advertising Identifier and any derived information with the reset Advertising Identifier."

Please check your code - including any third-party libraries - to remove any instances of:

class: ASIdentifierManager
selector: advertisingIdentifier
framework: AdSupport.framework

If you are planning to incorporate ads in a future version, please remove the Advertising Identifier from your app until you have included ad functionality.

To help locate the Advertising Identifier, use the “nm” tool. For information on the “nm” tool, open a terminal window and enter, “man nm.”

If you do not have access to the libraries source, you may be able to search the compiled binary using the "strings" or "otool" command line tools. The "strings" tool lists the methods that the library calls, and "otool -ov" will list the Objective-C class structures and their defined methods. These techniques can help you narrow down where the problematic code resides.

The third party libraries I'm using is the latest version of parse.com sdk, latest version of flurry analytics, and version 2.2 of test flight. Does anybody know which library is the issue?

因为使用了IDFA,但没苹果审核时没有看到广告。
我自己没有使用,但第三方类库就难说了,怎么检查呢?
查了一下stackoverflow,找到了方法:

在终端执行

1
grep -r advertisingIdentifier . (最后这个点,非常关键)

还有一个指令也非常有用,可以查看包内的接口调用情况

1
strings YoumiSDK_5.1.3/libYouMi.a

iOS4-iOS7屏幕旋转的控制

之前做了一个应用,但由于整应用界面个都是竖屏,不允许横屏,所以一直没有关注这个,昨天开发一个图片预览的类库(类似系统的查看图片),其中一个特性当然需要支持横屏,所以就压找了一下资料,之前已经听闻在屏幕控制上,iOS6上有了比较坑爹的变化。比如,让视图支持正常坚屏和两种横屏,兼容的做法是:

//for iOS4,iOS5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation==UIInterfaceOrientationMaskLandscape);
}

//for iOS6
-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotate
{
    return YES;
}

还没有完事,在iOS4\5如果没有重写shouldAutorotateToInterfaceOrientation,则默认不旋转屏幕,而在iOS6上,如果没有重写shouldAutorotate和supportedInterfaceOrientations,则默认支持除UIInterfaceOrientationMaskPortraitUpsideDown外的3个高向。

最大的区别来了,iOS6顶层的controller(必须设置为window.rootViewController)决定了它及它下面所有子层的屏幕旋转属性,也就是说,如果顶层controller设为可旋转,它及它的子层不能设为不可旋转,相反亦然,因为子层的controller相关的supportedInterfaceOrientations和shouldAutorotate根本不会触发。

那如果现在有一个需求,非常常见,堆栈是window->navigationController->viewControllerA->viewControllerB
viewControllerA要求是竖直,viewControllerB要求可以支持多个方向。实际上这个在iOS6里面无法通过以前的方法实现,因为navigationController作为顶层controller决定了它的可旋转性。

比较方便的解决方法是,viewControllerB以presentModalViewController的方式出现,因为这样它不属于navigationController的堆栈,可以自行决定是否转向。

另一种方法是viewControllerB加入CoreMotion加速计,通过判断设备的手持方向来切换不同的视图,不过就比较麻烦了。

iOS开发中的颜色问题

我们通常拿到设计稿开始实现时,会在设计稿做标注,比如颜色,字号,间距等。之前发现一个问题,我在程序里实现的颜色和设计稿的不太一样。过程通常是这样的,在photoshop、markman或者mac系统自带的取色工具取到一个RGB颜色,默认制式是Adobe RGB,然后在xcode的调色板实现,或者代码

[UIColor colorWithRed:15/255.0f green:120/255.0f blue:164/255.0f alpha:1]

咋一看好像没什么问题,但只要和设计稿对比起来,其实是有差别的,这里有一个坑,xcode调色板的颜色,和预览的颜色,到模拟器,再到真机,颜色都不太一样。到最后我们在真机截图,发回电脑,和设计稿对比色值,果然不一样。

多种颜色不同

这时候就有点蒙了,不知道程序上怎么实现才能和设计稿一样的颜色,特别在UI Builder的颜色制式有n种

多种颜色选择

最后发现,无论选哪种颜色制式,都是对不上photoshop的颜色的,最后找到解决方法如下:

用mac自带的取色工具,选中“以sRGB显示”来取设计稿的的颜色,然后这个颜色值用代码实现即可,如果用XIB,颜色制式选”Generic RBG“即可。

MACVIM 上手笔记

重新配置时,顺手重新整理一下这篇文章

##一、安装、配置

先下载它吧
https://github.com/b4winckler/macvim/releases

安装完毕后,运行,发现不对,传说中的透明背景呢?别急,这里先配置一下:

Edit->StartUp Settig

"不兼容vi模式
set nocompatible
"显示行号
set number
"语法高亮
syntax on
"按照C语法自动缩进
set cindent
"设置缩进长度
"详见http://dddspace.com/2010/03/vim-indentation-and-space-config.html
set tabstop=8
set shiftwidth=8
set softtabstop=8
set noexpandtab
"显示括号对应
set showmatch
"实时显示搜索结果
set incsearch
"编码设置
set encoding=utf-8
set fileencodings=gb2312,ucs-bom,utf-8,utf-16,cp936,gb18030,big5,euc-jp,euc-kr,latin1
"字体设置
set guifont=Arial_monospaced_for_SAP:h16
"设置颜色主题
colorscheme torte
"设置透明度
set transparency=20

保存重启即可。

##二:插件

装其它插件前,强列建义先安装pathogen.vim,它将大大减轻你管理和安装插件的复杂度。

pathogen.vimi
https://github.com/tpope/vim-pathogen

mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim

word_complete.vim http://www.vim.org/scripts/script.php?script_id=73

一个自动补全的插件,它是跟据上下文进行的补全的,挺好用的

ZenCoding.vim http://www.vim.org/scripts/script.php?script_id=2981

有写HTML的对应个应该很清楚

The NERD tree
http://www.vim.org/scripts/script.php?script_id=1658

目录浏览,安装后默认不调用,可以配置快捷将其调用与隐藏
let mapleader = “,”
nmap n :NERDTreeToggle
这样,<,+n>即可调用

The NERD Commenter
http://www.vim.org/scripts/script.php?script_id=1218)

在normal模式下进行快速注释,我常用到就下面几个:

<,+cc>注释当前行,或所选行,

<,+space>切换注释和不注释

<,+cs>多行注释

前面可以加数字来指定注释行数

syntastic
https://github.com/scrooloose/syntastic

代码语法检查的接口,下载好后还是一样,放到buddle文件夹自动加载。

然后配置vimrc

""syntax
"" Set symbol characters
let g:syntastic_error_symbol='✗'
let g:syntastic_warning_symbol='⚠'
"在打开文件的时候检查
let g:syntastic_check_on_open=1
"" Open and close error list console automatically
"let g:syntastic_auto_loc_list=1

由于各个语言是要分别配置的,所以比较麻烦。

###php:

php比较方便,打开syntax_checkers/php.vim

找到display_errors=0改为display_errors=1

配置vimrc:

et g:syntastic_phpcs_conf = "--tab-width=4 --standard=CodeIgniter"
let g:syntastic_stl_format = '[%E{Err: %fe #%e}%B{, }%W{Warn: %fw #%w}]'

这样就OK了,每次打开或保存时都会检查语法。

###javascript:

这个有点麻烦,要用到jshint

首先要安装npm,一个nodejs模块打包安装命令。

http://nodejs.org/download/

安装完毕之后,在终端执行下面指令,安装jshint:

sudo npm install jshint -g

输入密码,回车

等它安装完后,输入终端jshint,有响应即代表安装成功。

然后配置vimrc:

"" Choose a Javascript syntax checker
let g:syntastic_javascript_syntax_checker="jshint"
let g:syntastic_javascript_jshint_conf="~/jshintrc.json"

可以看到上面有个路径”~/jshintrc.json”,它用来配置检查器的风格,这是jshint和jslint最大的区别。

新建一个json文件,/用户/[yourname]/jshintrc.json,内容如下:

{curly:true}

意思为在if/for等block必须使用{},否则报错,更多配置请移步

http://jshint.org/docs/

##三、技巧

###1)转编码:
在Vim中直接进行转换文件编码,比如将一个文件转换成utf-8格式

:set fileencoding=utf-8

enconv 转换文件编码,比如要将一个GBK编码的文件转换成UTF-8编码,操作如下

enconv -L zh_CN -x UTF-8 filename(这个命令对windows的ANSI编码非常有效)。

iconv 转换,iconv的命令格式如下:

iconv -f encoding -t encoding inputfile

比如将一个UTF-8 编码的文件转换成GBK编码

iconv -f GBK -t UTF-8 file1 -o file2

###2)查找替换

:%s/foo/bar/g
Find each occurrence of ‘foo’ (in all lines), and replace it with ‘bar’.
:s/foo/bar/g
Find each occurrence of ‘foo’ (in the current line only), and replace it with ‘bar’.
:%s/foo/bar/gc
Change each ‘foo’ to ‘bar’, but ask for confirmation first.
:%s/\<foo\>/bar/gc
Change only whole words exactly matching ‘foo’ to ‘bar’; ask for confirmation.
:%s/foo/bar/gci
Change each ‘foo’ (case insensitive) to ‘bar’; ask for confirmation.
This may be wanted after using :set noignorecase to make searches case sensitive (the default).
:%s/foo/bar/gcI
Change each ‘foo’ (case sensitive) to ‘bar’; ask for confirmation.
This may be wanted after using :set ignorecase to make searches case insensitive.

##四、问题

###中文输入法:
我用的是QQ五笔,但在编辑模式中输入中文时,常常会触发MacVim的命令,原因是输是输入法没有完全截获按键;
解决方法:在命令行输入以下命令

defaults write org.vim.MacVim MMUseInlineIm 0

##五、在终端启动

下载后有一个mvim文件,将其拷贝到
$sudo cp -f mvim /usr/bin/

这里在终端通过mvim指令即可运行或编辑文件,编辑文件每次都是新建窗口,让他支持tab可以编辑这个mvim文件,首行加上
Shell

tabs=true

然后最后一个if 块替换成

# Last step:  fire up vim.
if [ "$gui" ]; then
  if $tabs && [[ `$binary --serverlist` = "VIM" ]]; then
    exec "$binary" -g $opts --remote-tab-silent ${1:+"$@"}
  else
    exec "$binary" -g $opts ${1:+"$@"}
  fi
else
  exec "$binary" $opts ${1:+"$@"}
fi