看知乎已经成为了我的日常,自从发现了这个知乎精选站,它就成了我浏览知乎的流量入口。感觉它能比日报提供更丰富的内容。
突然下线了,还真不适应。不过这种非官方的爬虫,能坚持这么久也是蛮不容易的。
]]>于是很轻松就找到了 App Store Marketing Guidelines,里面给出了所有可能用到的图片资源,包括所有语言的 Download on the App Store 按钮图片、所有苹果设备的图片等。以及在宣传品中使用这些图片时的规范要求。
Download one the App Store Badge
Apple Product Images
看了一下,国内按照苹果这个标准来的不多,违反规定的一抓一大把。比如滴滴出行的下载页面,就错误地使用了 Apple 的 Logo:
这在 1.6 Avoid mistakes
里有专门的说明。
管理屏幕截图差不多是 iTunes Connect 里最麻烦的。最初只有一两种屏幕尺寸时还好,现在 iPhone 有四种尺寸,iPad 有两种尺寸,如果再需要支持多种语言,那上传图片的人基本就要疯了。比如词记提供 4 张截图,每种设备都有对应的截图,目前支持 3 种语言,那么总共就有 4 × (4+2) × 3 = 72 张图片。截图、压缩、上传,还是很磨性子的。相信我,这个数量不算多。
今年的 WWDC 上苹果提出了 Media Manager 来专门解决这个问题,但今天实际一看,并没有那么神奇。它的原理是让你可以只上传最大尺寸、主要语言的图片,其他屏幕尺寸的都显示最大尺寸的图片,其他语言的都显示主要语言的图片--是的,它并没有神奇地帮我们把图片处理成对应的情况,只是缩放和能凑合看而已。如果你是完美主义者,照样需要为每一种屏幕尺寸、每一种语言都上传对应的图片。
其实 iOS 本身提供了一种分享的方式,App Store 里的分享就是一个实现的例子:
这个弹出的分享框,叫做 UIActivityViewController。通过它来实现分享,好处是样式统一、实现简单,更重要的是它直接使用系统中设置的平台账号,并且不需要对应用进行授权。这一点降低了用户分享的心理负担。同时,开发者不需要去平台为应用申请 App Key,也一定程度上降低了开发的门槛。
但正是因为这种分享不依附于应用,所以也会带来一些缺点。比如分享出去的东西会显示“来自 iOS” 而不是你的应用,也导致了不能进行用户统计。而且通过这个只能做分享,不能用做 SSO 登录。对于只需要分享的简单场景下,用 UIActivityViewController 完全足够并且更加合适,所以我在词记里尝试了一下。
基本的实现非常简单,把需要分享的内容,可以是文字、图片、链接,传入初始化方法即可:
|
|
如果需要为不同平台提供不同的分享内容,或者生成某个分享内容的过程较复杂,可以为这个内容创建一个 UIActivityItemProvider 的子类,并实现方法 -(id)activityViewController: itemForActivityType:
,如:
|
|
利用它去初始化 UIActivityViewController 时:
|
|
注意初始化方法里的 PlaceholderItem,它应该是能够正确反应内容数据类型的简单数据。在弹出的 UIActivityViewController 里,会根据这些 PlaceholderItem 的类型,来决定显示哪些选项,此时并不会去调用 ItemProvider 里的方法。比如有两个 UIImage,则会显示“存储 2 张图片”;如果没有 UIImage,则不会显示存储图片这一个按钮。当你真正点击某一项分享渠道时,才会调用其 itemForActivityType 方法来得到真正的内容。
你可能注意到了,上面微信的 activity type 用了字符串 @”com.tencent.xin.sharetimeline”。而关于 UIActivityType,查看 UIActivityType.h
,可以看到这些:
|
|
里面并没有发现微信。通过运行时打印,可以整理出如下的表格:
方式 | 字符串常量 | 字符串内容 |
---|---|---|
AirDrop | UIActivityTypeAirDrop | com.apple.UIKit.activity.AirDrop |
SMS | UIActivityTypeMessage | com.apple.UIKit.activity.Message |
UIActivityTypeMail | com.apple.UIKit.activity.Mail | |
备忘录 | N/A | com.apple.mobilenotes.SharingExtension |
新浪微博 | UIActivityTypePostToWeibo | com.apple.UIKit.activity.PostToWeibo |
iBooks | UIActivityTypeOpenInIBooks | com.apple.UIKit.activity.OpenInIBooks |
N/A | com.tencent.mqq.ShareExtension | |
微信 | N/A | com.tencent.xin.sharetimeline |
UIActivityTypePostToTwitter | com.apple.UIKit.activity.PostToTwitter | |
UIActivityTypePostToFacebook | com.apple.UIKit.activity.PostToFacebook | |
Flicker | UIActivityTypePostToFlickr | com.apple.UIKit.activity.PostToFlickr |
Vimeo | UIActivityTypePostToVimeo | com.apple.UIKit.activity.PostToVimeo |
腾讯微博 | UIActivityTypePostToTencentWeibo | com.apple.UIKit.activity.TencentWeibo |
提醒事项 | N/A | com.apple.reminders.RemindersEditorExtension |
保存到相册 | UIActivityTypeSaveToCameraRoll | com.apple.UIKit.activity.SaveToCameraRoll |
指定到联系人 | UIActivityTypeAssignToContact | com.apple.UIKit.activity.AssignToContact |
复制到剪贴板 | UIActivityTypeCopyToPasteboard | com.apple.UIKit.activity.CopyToPasteboard |
打印 | UIActivityTypePrint | com.apple.UIKit.activity.Print |
添加到阅读列表 | UIActivityTypeAddToReadingList | com.apple.UIKit.activity.AddToReadingList |
可以查阅 NSHipster上的这篇文章了解有关 UIActivityViewController 的更多信息。
]]>是下暴雨的那天,输入的是下雨的 emoji 表情:☔️。
试了一下,在 TextField 编辑状态还是正常的,退出编辑状态后就成这样子了。另外,除了这个下雨的表情外,还有几个经典的 emoji 也显示成了黑白颜色的,但好在还是一个字符,没有出现后面的 VS16。基本可以锁定是字体的原因。
先查看了下雨的编码,在表情与符号里拷贝字符简介:
粘贴出来可以看到这个 emoji 编码是 U+2614 U+FE0F:
|
|
为了营造回忆的气氛,词记选用了花园明朝体,打开 ttf 文件后查看 U+2614 和 U+FE0F 位置的字符:
果然没错,就是字体里面覆盖了一部分的 emoji 表情导致的,还能找到其他一些 emoji 表情:
可能是花园明朝体在开始制作的时候,主流操作系统对 emoji 表情的支持还不到位,所以在字体文件里加入了一些 emoji 符号。当你输入这些表情时,因为字体里有这些符号,所以会显示字体里面的符号,而不会显示系统默认的彩色 emoji 字体。
但是,下雨表情里后面那个 VS16 是什么鬼?为什么这个下雨表情,由两个 Unicode 组成?
表示下雨的字符就是前面的 U+2614,而后面的 VS16 表示第 16 号字形变体(Variation Selector)。用 iOS 的表情键盘输入的下雨表情,默认就是第 16 号变体,在苹果的 emoji 字体里,就是一把蓝色的雨伞,上面五个雨滴。一个表情允许有多种不同的展示形式,比如苹果系统中有关人物的 emoji 表情都可以选择不同的肤色,就是采用了这种字形变体的方式。
于是这个 bug 就容易解决了,删掉所有的表情就好了,这样就会用系统的 emoji 字体进行显示。
另外,在浏览这个 ttf 文件时,发现了 Unicode 标准中很多有意思的符号,比如:
各种奇怪的性别:
还专门定义了各种单位:
音乐符号:
回收标记:
镰刀和锄头:
麻将牌:
扑克牌:
可惜的是,markdown 的图片标签并没有提供设置图片宽高的方法(有些方言增加了支持)。但好在 markdown 里可以随意插入 html,所以对于之前截的图片,用 html 的 标签进行了替换,里面直接指定了图片宽高为实际的一半,就感觉舒服多了。以后写博客再需要截图时,要先缩小图片尺寸再上传。
]]>回家吃饭,又一个很好的互联网尝试,但是貌似也要面临很大的政策风险。食品安全相当重要,固然需要监管。不过貌似即使处于监管之下,卫生状况也不一定怎么样。
]]>首先是前年 CCTV 的一则针对 iPhone 的新闻报道,内容是指责 iPhone 会不断对手机进行定位并记录下来。抛开内容是否足够公正不谈,这则“新闻”也早就不是新闻了。如果去核对左下角的日期和星期几,可以很容易地发现这是前年播出的新闻,但巧合的是这则新闻播出时正好也是 7 月份。大多数网民也根本是看个热闹,积极转发,吓坏了手里拿着 iPhone 的小伙伴们。
然后又出现了关于 iPhone 输入法的舆论,说是在 iPhone 上输入“击沉”后,输入法会出现提示“中国”。这可是了不起的证据,这下看你苹果怎么解释。很多网友试都不试也就友情转发了。
再接下来就是各种禁售 iPhone 的假新闻了。有 CCTV 版,有天安门前 LED 版,仔细看看稍微思考一下就知道是假的,但依然在祖国大地的朋友圈传播得有模有样。
这一系列针对 iPhone 的网络舆论,第一个是苹果为了提供更个人化的服务,进行的常去地点统计,可以推测出你的家庭住址、工作地点、每天的交通规律等,提前为你查询交通状况并预测出行所需时间,展示在通知栏里。如果你并不需要这个功能,也可以很容易地把它关掉。苹果有没有妥善地加密这些信息,有没有把这些信息上传或泄漏,甚至会不会影响到国家安全,我不能做出保证。但在 Apple 和 CCTV 中间,我选择相信 Apple。
第二个,是现在所有输入法都具有的功能,就是个人词库和云词库嘛。所以,这事儿不应该怪 Apple,应该怪频繁输入这些词语的国人。第三个,现在好多人动不动就吆喝着抵制、禁售,这都是没知识的表现。不只苹果,就连肯德基麦当劳这次都躺枪了。
更让人可惜的是,竟然有很多高学历知识分子、很多年轻人热情地转发这些舆论,并热血地评论要抵制。可笑的是后面还带了个“来自 iPhone”的小尾巴,你倒是扔了啊…
]]>上次是在做优优育儿时,有一个新功能非常简单,就是一个单纯的列表页,所以尝试着用 Swift 进行了实现。而我当时正是像文章中写的那样,只是把之前 Objective-C 的写法按照 Swift 的语法进行了变化,然后相信了 Xcode 的代码更正提示,结果虽然可以正常运行,但代码里全是 exclamation mark。
阅读了这个系列的文章,发现 Swift 的确是个现代化的语言。虽然凭借传统语言的知识可以很容易地入手,但它所带来的不仅仅是语法的改变,更多的是编程思路的变化。
下面我将分别展示三段代码,功能是从 JSON 串中得到一个 Article 对象的数组。第一段是用 Objective-C 编写的代码,这也是我写这种功能的标准形式。第二段是按照传统思路编写的 Swift 代码,是应该避免的。第三段是用正确的思路编写的 Swift 代码。
|
|
|
|
可以看到,这段代码完全就是上面代码的 Swift 版,很容易理解,但里面有很多的惊叹号。至于为什么这样做非常不好,可以参见最开头提到的文章。
|
|
这里面就有很多 Swift 的新东西了,比如 guard let, if let, flatMap 等。虽然代码好像更长了,也不那么易懂了,但这才是更安全可靠的代码。
|
|
测试环境(Sandbox)下一切正常,可根据 product ID 获取到 product,完成支付。
推测应该是由于 IAP 审核通过后并没有同步及时的上线,所以导致无法正常获取到 product,等待一段时间即可。(我等待了约 7 个小时就正常了,也有人等待了一两天)
所以在程序中要注意,如果获取不到 product 做相应的处理,防止程序崩溃。
]]>因为广电总局电影卫星频道节目制作中心具有电影《血搏敌枭》的独家网络传播权,而优酷侵权播放了这部电影,所以广电总局状告了苹果公司。
是不是很奇怪?优酷的错为什么状告苹果?
因为优酷的应用是通过苹果 App Store 下载的,所以,苹果,自然要怪你喽。
苹果最终还是拿它没有任何办法,在最后一刻公布了这个决定。
游戏个人开发者可以放弃了。但愿不要插手其他类型的应用。我们并不是怕审核,怕的是没有具体审核规则,怕的是自由裁量,怕的是复杂的审核流程、漫长的审核周期、徒增的审核成本,怕的是会应运而生的各种代理。
]]>找了很多方法,最后终于找到了一个管用的--把 3G 网络禁用,只允许 2G 网络。不知道是什么原因,但事实证明的确只跟这个有关。
]]>从网上下载了 4.4.2 的官方五件套,然后按照网上的方法用 Odin 工具刷入。过程很顺利,重启后变成了 Kitkat 的风格,进入首次设置页面。但马上发现,右上角的信号位置,变成了 ⦸ 这样的符号。查看系统设置,或者拨号键盘输入 *#06#,发现 IMEI 丢失。
上网搜索,发现 Samsung 的机器有个叫 efs 的东西,其中保存了包括 IMEI 在内的一些信息。如果降级前没有备份的话,可能会丢失!绝望了好一阵儿,发现把 SIM 卡放到另一个卡槽里可以用,只不过另一个卡槽只支持 2G 网络。可是这让我越想越觉得奇怪,于是又下载了 5.0.1 的固件刷进去,发现 IMEI 回来了,这说明 efs 并没有丢失。马上 ROOT 之后备份 efs,继续折腾。
再次降级,依然没有信号。ROOT 后查看文件,发现 /efs 目录有个叫 .nv_data.bak
的文件,用这个文件替换这个目录下的 nv_data.bin
文件,然后删掉 nv_data.bin.md5
文件,重新手机,IMEI 恢复。
另外,如果只是把原有的 nv_data.bin
文件删掉,也能恢复信号,但是查看 IMEI,发现是一个不正确的 IMEI(一大串 0,后面是 0049)。
2016.3.30。山城。一个 3D 的城市。既有文化底蕴,又有现代繁华。夜晚的江景非常美。
2016.4.3。蓉城。最早的城市,闲适的大都市。同样作为省会,比济南好太多。
2016.5.28。山东省最不像山东的城市,德国的味道。正在修地铁。第二次来,现代化了许多。
2016.5.30。母校变了一些。万平口准备收费。路上开始堵车了,修了条地下隧道。有了机场。
2016.6.1。魔都。住在弄堂里。外滩的钟声、万国建筑。陆家嘴的东方明珠、三大高楼。城隍庙的蟹黄汤包、南翔馒头。
我的最新作品,词记,已正式上线 App Store 啦!
你一定写过日记。或许是小学语文老师布置的家庭作业,或许是青春期时懵懵懂懂的情感记忆,或许是长大后日记本里给自己的加油打气,或许是旅行在外每天晚上写下的旅途随笔。
词记,让你用一个独特的方式写日记。把今天所有的点点滴滴,在思绪中整理、精心挑选,然后只用一个词来概括。
或许随着时间流逝,再看到这些词时,早已想不起这词背后的故事。但这些故事给自己留下的感觉,却依然明晰:惊喜、开心、阳光明媚、意外收获,亦或失落、无聊、阴雨绵绵、心情好糟。
是的,这就是我们的生活。
词记,用一个词记录今天!
一天一个词,烦恼去无边~
You have ever written diary. Maybe homework assigned by your teacher, maybe affection memories in your teens, maybe “fighting” in your notebook after graduation, maybe notes in every evening on your trip.
Ciji (詞記), a special way to keep a diary. All things happened today, in mind, pick only one word to describe!
Time flies, maybe you cannot remember the things happened behind these words, but the feelings are clear: surprise, happy, sunshine, windfall, or disappointed, boring, rainy, restless, etc.
Yeah, it is our life.
Ciji (詞記), use one word to record today.
A word a day, keep the sadness away~
喜欢请五星好评哦!
]]>ERROR ITMS-90475: “Invalid Bundle. iPad Multitasking support requires launch story board in bundle ‘org.stoneark.worddiary’.”
原因是,iPad 程序(或者 Universal 程序),从 iOS 9 / Xcode 7 开始,默认要求支持多任务分屏。但这要求必须使用 Launch Storyboard,而不能再用 Launch Image。而正如之前说过的,所以我并没有采用 Launch Storyboard,所以导致了这个问题。
目前可以暂时不支持多任务分屏,在工程属性的 General 里,把 Requires full screen
勾选上即可(会在 Info.plist 里增加字段 UIRequiresFullScreen
)。
在 Project 属性中,有 Localizations 一项,在其中可以管理支持的语言列表,还可以选择是否开启 Base 语言。
在资源文件(如 strings/xib/storyboard)的文件属性中,可以在 Localization 项中进行国际化语言的管理。如果尚未国际化,会有一个长长的 Localization 按钮,点击后开启这个文件的国际化。如果已国际化,会显示并可管理当前文件已支持的语言。
如果想取消对这个文件的国际化,在 Xcode 里做不到。唯一的办法是,去 Finder 里把各个语言的 .lproj 目录下的这个资源文件删掉,只留一份放到工程目录的最外层(而不从属与任何 .lproj 目录)。
自己新建一个 String 文件到工程里,名为 Localizable.strings
即可。(这是默认的文件名,调用 NSLocalizedString
方法默认取这个文件,如果用了其他的文件名,则每次调用方法时,需要指定文件名)
例如,Localizable.strings 内容为:
|
|
|
|
获取时:
|
|
上面是常用的情况。还有一种复杂的情况,是在有些语言里,某两个参数的位置可能会颠倒,这时需要使用转义符:
|
|
更为详细的可参照:
http://nshipster.com/nslocalizedstring/
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/InternationalizingYourCode/InternationalizingYourCode.html
除了借助 localizable strings 文件进行界面国际化之外,对于 xib/storyboard 可以直接进行国际化。虽然看上去很方便、很直观,但其实并不是特别好用。
它的原理其实还是 localizable strings,只不过这个 strings 文件是 Xcode 自动创建的。创建的时机是在你对这个界面开启 localization 时,而且它并不会监控 xib/storyboard 的变化。如果你在 localization 之后又改变了这个 xib/storyboard,主要是增加了新的控件,那么这个新控件并不会自动出现在 strings 文件中。
那你就没办法了,Xcode 也没有提供同步的手段,你唯一能做的是查看 xib 的源代码,从中找到新建控件的 ID,然后自己写到那个 strings 文件里--噢,这一点都不方便。
显然,需要对不同语言设定不同的应用名称,也就是 Bundle Display Name,我们都知道它在 Info.plist 里。
但注意,不是把 Info.plist 进行 Localization,如果对 Info.plist 进行了 Localization,会编译报错 the file Info.plist does not exist.
正确的方式是在工程里新建一个名为 InfoPlist.strings
的文件,然后对这个 strings 文件进行国际化,在里面写入:
|
|
即可。
注意,需要把 InfoPlist.strings 文件加到工程属性里的 Copy Bundle Resources 里(默认应该就给加上了,如果有问题可以检查一下)。但不要把 Info.plist 文件加到 Copy Bundle Resources 里,否则出现编译警告。
测试发现,将 iOS 设备设置为并没有支持的语言时,应用并没有正确地显示为 Base 中的字符串(英语),而是显示成了简体中文。
Stackoverflow 上有很多国内外开发者遇到了这个问题,但都未找到原因和解决方法。
http://stackoverflow.com/questions/20241256/ios-app-default-language-en-is-not-applied
http://stackoverflow.com/questions/20584984/ios-set-a-default-language-in-xcode-for-my-app
http://stackoverflow.com/questions/18114994/does-my-base-internationalization-storyboard-have-to-correspond-to-a-fallback-la
希望让应用在不同国家的 App Store 中显示不同语言的名称,在 iTunes Connect 里新建应用时先用一个主要语言新建,如简体中文,新建成功后在 App 信息里可以看到“可本地化的信息”,可以在右侧选择语言,并且填入相对应的信息。另外,在版本中对应用简介、关键字、截图等也都须进行国际化。
如果未做本地化,则按照选择的主要语言显示。
]]>之前一直没在实践中真正采用过它,这次一试,可真是让人摸不着头脑。
一旦有两个 ImageView,则它们的表现会非常奇怪。尤其是两个图像有重叠部分的时候。
即使一张图片在另一张下方,也会把上方图片的重叠部分遮盖住。
设计时:(灰色渐变背景在底层,词记图标在上层)
运行时:(重叠部分被底层遮盖了)
关于 Launchscreen storyboard,涉及到 UIImageView 出现了很多问题,至今也没有解决:
https://forums.developer.apple.com/thread/17146,
https://forums.developer.apple.com/message/62721
暂时还是不用它了,用回 Launch image asset。
]]>