分享

Artoirus

 plumbiossom 2013-12-16

       未找到应用程序的“aps-environment”的权利字符串

总是想到这个忘了那个,记录一笔

  1. bundle_id 和实际的 appid 一致
  2. 选择的Provisioning profile对不对(有时候auto会使用通配的profile)
  3. portal中对应的appid是否开启推送,是否有推送证书
  4. provisioning profile是否是在appid开启推送后再生成的
  5. 设备是否是adhoc的profile包括的设备

WWDC 2013: Session 203 What’s New in Cocoa Touch

继续简单贴WWDC的笔记。这个session内容相当多啊。

session 203 关于Cocoa Touch的改动,先看这个也是个人兴趣所致。随着iOS7的大动作,Cocoa Touch的改动真心多,还有更多更多细节可能没发现。

多任务

iOS7中多任务是一个重头戏。这里讲到三种。这些改动都是让我非常激动的。

background fetching | 后台抓取

这个应该是为了满足类似ping、心跳这样的需求,定时往服务器去抓数据。xcode5的Capabilities设置里,打开Background Modes,可以直接勾选到一个background mode:「Background fetch」。

主要涉及的API如下

1
2
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
- (void)setMinimumBackgroundFetchInterval:(NSTimeInterval)minInterval;

remote notifications | 远程通知

这是个很酷的功能。让app能够在接到一条推送消息的时候后台打开一个下载任务。

例如微信收到新消息推送后打开app,还会有一个连接下载的过程。现在接到推送的同时,就可以在后台把新消息抓过来,打开应用后app已经呈现了这个消息。另外可以想到的更酷的应用,是例如追美剧的那些视频软件,美剧一更新就通过推送把新的一集抓下来,用户下次进入app的时候就可以直接离线看了。

同样Capabilities设置里有一个选项「Remote notifications」

1
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;

background transfers | 后台传输

这是个比较基本的功能,发起一个网络请求可以在app切到后台或关闭后继续完成(当然你也可以中端或暂停它)

这里有个变化是Cocoa提供了一个新的类NSURLSession来取代NSURLConnection,这个新类可以快速发起background的请求。请求完成后app可以处理一个回调,展示下载完成的图片或其他资源。更多关于NSURLSession的内容在WWDC session 705「What’s new in Foundation Networking」中有更具体的说明。

1
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;

Views and Images

UIImage的renderingMode

- (UIImage *)imageWithRenderingMode:(UIImageRenderingMode)renderingMode; 可以得到一个设置了renderingMode的图片,默认他是auto的,另外它还会有original和template两种绘制模式,后者无视图片中的颜色信息。

Tint

现在好像可以很懒惰的处理整个app的风格了,只要设置好tint,各种文字、图标的颜色都会自动切换过去。具体涉及到UIViewtintColor属性以及tintAdjustmentMode属性。而新的代理- (void)tintColorDidChange;可以让你知道tint改变的情况。

UIView Animation

iOS7的动画加强了不少。涉及动画的改动也不少。

+ (void)performWithoutAnimation:(void (^)(void))actionsWithoutAnimation; 可以强制一些动作不使用动画。不知道之前让我郁闷的要死的UITableViewRowAnimationNone还是有动画的问题能不能解决。

CocoaTouch提供了关键帧动画的API。

1
2
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
- (void)addKeyframeValue:(id)value time:(CGFloat)time;

另外还有Motion Effects,动画可以结合重力感应什么的大概是这样。

Collection View

这个是去年的新东西,强大到什么瀑布流、coverflow都能用layout实现。今年提供了一个在layout之间快速切换的方法。数据不变,layout换一下界面从瀑布变coverflow不是梦想。具体细节不纠结了。

View Controllers

其实我觉得最担心的就是这个东西。因为可以看到statusbar navigationbar tabbar都是半透明毛玻璃了,我怎么让一个tableview显示在整屏却只在中间区域让用户滚动呢(能滚到中间,不会有cell躲在tabbar下面,但要让tabbar半透明看到滚下去的cell)?

viewcontorller涉及到下面的一些改动。

wantsFullScreenLayout

现在的viewcontroller始终保持iOS6设置wantsFullScreenLayout为YES的状态。StatusBar、NavigationBar等等都会变成半透明。真是丧心病狂!然后wantsFullScreenLayout这个属性就没了。因为它被始终设为YES。

extended edges

这个extended edges的属性,帮我解决了之前的担心。现在怎么让一个scrollView内容显示在中间部分,却可以滚到那些Bar下面实现半透明,就靠这个属性。让viewcontroller的extended edges变成你要躲开的控件的高度宽度就可以。描述不清楚,你们体会下。orz

content size

preferredContentSize属性来设置你期望的大小,iOS7现在会用它来决定自己的大小。一般应该只有子界面才用得到。

status bar

因为全屏,所以现在的statusbar是没有背景颜色的。 UIStatusBarStyleBlackTranslucentUIStatusBarStyleBlackOpaque两个枚举都被deprecated了。新的UIStatusBarStyleLightContent可以让你设置,万恶的毛玻璃。UIStatusBarStyleDefault不变。

custom transition

可以定制transition。比如navigation的push pop,viewController的present dismiss,或者手势控制的各种。另外新的代理UIViewControllerTransitioningDelegate(viewcontroller有相应属性)和新的protocolUIViewControllerAnimatedTransitioningUIViewControllerInteractiveTransitioningUIViewControllerContextTransitioning,具体的方法文档有,不知道用到的机会有多少。

状态恢复

现在新的App状态恢复,系统会给你截一张图,让你的程序的恢复变得无缝。

但事实上,很有可能截图和应用恢复后实际的数据或界面不一样,于是你可以用新的方法- (void)ignoreSnapshotOnNextApplicationLaunch;屏蔽之前的截图。

另外你可以用+ (void) registerObjectForStateRestoration:(id<UIStateRestoring>)object restorationIdentifier:(NSString *)restorationIdentifier;和界面无关的数据对象保存下来。

蓝牙状态也可以恢复,这一块不太熟悉,总之系统帮你保存了一些状态,有两个新的key让你取到他们。

AirDrop

这个session里笼统的说了一下,你可以注册protocol,每个app沙箱多了一个inbox目录等等,不深入了(视频里也没深入说啊)。

Dynamics

「Getting started with UIKit Dynamics」和「Advanced Techniques with UIKit Dynamics」两个session详细介绍了这一块。

具体这货就是让你做一些效果,两个view粘在一起,view带上物理特效,碰撞、重力感应什么的高级货。

  • UIDynamicAnimator 操作一些动画的模型
  • UIDynamicBehavior 记录各种动作的一棵树
  • UIDynamicItem 这个protocol让控件变成你要操作的对象

Text

iOS7的设置里,用户可以用一个滑槽修改字体大小了。

开发者可以用UIApplicationpreferredContentSizeCategory属性取到用户设置的字体大小。

取到的值是一个UIContentSizeCategorySize...枚举,有XS、S、M、L、XL、XXL、XXXL几个档次。

用户修改这个设置的时候,会发送一个notification: UIContentSizeCategoryDidChangeNotification,使用新的keyUIContentSizeCategoryNewValueKey可以从notification中取到修改后的字体大小。

另外+ (UIFont *)preferedFontForTextStyle:(NSString *)style;方法可以用「标题文字」「正文文字」这样的形式来获得一些固定的UIFont。

Text Kit

这是一个全新的Kit,基于CoreText。具体「Introducing Text Kit」和「Advanced Text Layouts and Effects with Text Kit」以及「Using fonts with Text Kit」三个session涉及到这一块。

这货大致有三个类

  • NSTextContainer 是最外面文字布局的容器
  • NSLayoutManager 是内部的布局
  • NSTextStorage 文字的数据

修改文字布局只要按需要派生其中一层就可以,还有个NSTextAttachment可以图文混排什么的。细节跳过。

More

Session最后提到了其他一下CocoaTouch的修改,罗列一下。

  • Local networking
  • Sprite Kit
  • game controllers
  • MapKit
  • CoreLocation
  • game center
    • new turn based api (like letter press)

WWDC 2013: Session 404 Advances in Objective-c

看了几个WWDC的session,做了一些笔记,简单贴在博客上吧。

404这个session大概说了objective-c的一些变化,和去年比起来改动实在是不多。

module

这个改动比较引人瞩目,简单说就是写#import的时候改成@import。#include是复制粘帖,#import是#define保护下复制粘帖,@import则用了一个结构去维护。

在工程设置里,把「Enable Modules (C and Objective-C)」设为YES,不用改代码就能自动生效。会提高编译和索引的速度。

有一句话很刺眼叫「not available for user frameworks」,呵呵。

另外随之而来的Auto Linking特性,你不用自己去加那些依赖了。

refactor tools

重构工具什么的,然后又提了提literals的语法什么的。说起后者今天看到一篇文章,把object subscripting(这货就是比如说array[@3], dictionary[@“key”]这样)扩展成一门DSL。

instancetype

这个改动我觉得挺重要。以前方法(尤其init)返回一个指针的时候用id作为类型。编译器其实很难(几乎不能)对它的类型作出判断。新增这个instancetype来声明返回值类型,可以避免很多不安全的问题。

比如Foo的init方法返回一个NSArray,调用的时候写成NSDictionary *dict = [[Foo alloc] init];。如果init方法是-(id)init,那编译器啥也不知道。如果改写成-(instancetype)init,xcode会警告你这里类型有问题了。

explicitly-typed enums

cell.selectionStyle = UITableViewCellAccessoryCheckmark这种不同枚举类型的赋值会得到一个警告了。另外xcode的自动完成也更智能了。别忘了用NS_ENUM这个宏来写枚举哟。

runtime

有一些改动,比如新的tagged pointer,以及使用isa的警告等等。下一节还提到了一些retain环的警告等等等等。

GC –> ARC

苹果不要GC了,都用ARC了,包括Xcode 5在内的一些工程都放弃GC了。

另外ARC还有些进化。__weak更快了,说是x2快。dubug的autorelease处理更接近release build了。

CF bridge

CoreFoundation框架的桥也全都优化了,提到implicit bridging的时候全场掌声,本人level太低不理解什么意思。

笔记大概就是这些,感觉很多都没怎么听懂,还需要补课。

快速使用uwsgi部署

之前尝试在阿里云部署一个bottle.py写的web服务,选择了unbuntu12.04,一穷二白的ubuntu上用uwsgi部署还挺简单的。这里简单记录一下。

先要改一改程序代码,声明一个application

1
application = bottle.app()

然后安装uwsgi,demo.py就是修改过的bottle的代码。

这里我遇到了— unavailable modifier requested: 0 --,要安装uwsgi-plugin-python,并且uwsgi启动时候添加--plugin python

一些uwsgi的操作看这里

1
2
apt-get install uwsgi uwsgi-plugin-python
uwsgi --socket :8000 --plugin python --file demo.py --processes 4 --pidfile /tmp/demo.pid --touch-reload=/tmp/restart -d uwsgi.log

安装nginx

1
2
3
4
5
6
7
apt-get install libpcre3 libpcre3-dbg libpcre3-dev
apt-get install zlib1g zlib1g-dbg zlib1g-dev
apt-get install make
cd /path/to/nginx
./configure
make
make install

最后配置nginx。默认安装路径在/usr/local/nginx/conf/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
server {
    listen       80;
    server_name  demo.;

    location /static/ { alias /home/root/demo/static/; }

    location / {
        uwsgi_pass      127.0.0.1:8000;
        include         uwsgi_params;
    }
}

自此搞定

via:

UIWebView加载本地资源

作为一个不会javascript只会jQuery的程序员,我在做Objective-c和HTML5页面交互的demo的时候需要HTML至少依赖一个jQuery,放在本地咋整?

创建UIWebView的时候

1
2
3
4
5
6
7
8
9
10
11
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height)];
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];

[_webView loadHTMLString:htmlString baseURL:baseURL];
// 把baseURL知道bundle的Url,就能调用bundle里的其他文件了,图片音乐什么的
[self.view addSubview:_webView];
[_webView release];

添加.js文件的时候

添加js文件有点特殊,xcode会以为js是可以编译的代码。要在Xcode的target里,把.js文件从 “Compile Sources” 移到 “Copy Bundle Resources” .

写HTML的时候

可以直接写相对路径了。<script src="jquery.min.js"></script>

题外话1: 有个基友要做一个HTML5播放视频的东东,想把视频缓存到本地,但是UIWebView无视HTML5 mainifest里指定的音频视频文件,还有5M的限制。其实也可以存下来本地加载撒。

题外话2: objc可以用stringByEvaluatingJavaScriptFromString:在webview里执行脚本。js要调用objective-c就比较麻烦。iOS可行的办法是利用custom URL scheme,跳转到应用之后应用或从path或从querystring来判断js要调用什么类什么方法,比较蛋疼。最理想的方式应该是safari插件支持的方式,可惜iOS没有。

via:

Arthur的2012总结

我觉得这篇2012年总结如果今天不写估计我这辈子都不会写了。2012的末日没有如期而至,以至于写2012年末总结的计划不得不又被提上日程了。

2012年总的来说发生的事情不算多,但是心态变了很多。

博客几乎没怎么折腾,偶尔写了几篇文章。换了octopress。换完博客系统的时候倒是热情高涨把evernote里攒下的素材写了一堆。不过现在又瞬间消极怠工了。

dev

今年主要是iOS开发结结实实的盖了几层楼,从之前搭搭积木的阶段,终于到了可以自己造轮子的程度了。完成了几个公司里的产品、项目。现在正在给自己做一个简单的app,买了idp,打算最后把这个应用弄到appstore上,虽然很多人不看好,不过我的初衷也只是做着玩,才没有改变世界的伟大志向呢。

另外因为参与了一个微博应用开发,所以对python、bottle.py、uwsgi都熟悉了不少,之前提到的那个app,以及接下来要说的小玩具的服务端,也都是用bottle和mongodb架起来的,不过VPS能力有限部署的时候还是用了passenger wsgi。

说的小玩具是一个arduino做的小东西,其实就是按一下按钮发一条微博,把它当作门铃来用的话就可以知道家里有没有人按门铃了,虽然知道了也没办法进一步才去什么错失。。。 关于这个东西欢迎关注微博@阳哥的门铃

life

依然在魔都打拼,因为之前公司搬到杨浦,所以也住到杨浦来了,和好基友@lionelzhang 好基友@luosky 同居了,住在复旦大学附近,欢迎来做客,做客前记得联系,我好搞下卫生。

10月份的时候正式跳槽了,离开之前的人间网、爱折客,从创业公司来到了一家金融企业。新的工作新的环境,包括换工作这件事情本身,在我内心起了不少化学变化。说实话这个决定让我失去了不少珍惜的甚至引以为傲的东西,当然也感受到了很多期待之内期待之外的新东西。

要说今年印象深刻的好玩经历。十一的时候租了一辆车一路疾行500公里路去参加一个同事的婚礼,吃过晚饭出发,到了那里的时候已经是后半夜了。作为一个今年换了10年期驾照的「老司机」来说,第一次开这样的远门是不是太水了一点。在台州的时候还出了第一次车祸哦。。。

另一个大事就是欧洲杯,不被看好的意大利居然一路杀进决赛。决赛是转成跑到宁波去看的,不过输的也太难看了一点吧。

diagram

好吧最后是去过的地方、看过的书、看过的电影。

2013加油。

Bottle直接返回pymongo查询结果

以前提到过bottle,也写过在django里使用pymongo,这次是在bottle里用pymongo。

bottle有类似ROR的一些特性,比如处理请求的时候直接return一个字典,框架会自动把它parse成json(autojson)。

我是想偷个懒来着,把代码写成了下面这样。

1
2
3
4
@get('/api/today')
def api_today():
    udid = request.GET.get('udid')
    return self.coll.find_one({'udid':udid, 'date':today})

这会有问题,因为find_one返回的bson没办法直接parse。伟大的发明都是在偷懒的时候诞生的,看起来我要做的事情也很简单,只要能让我改一改parser就行了。

  1. 写一个dump方法替换原来JSONPlugin里的
  2. 设置Bottle app的autojson为False。Bottle(autojson=False)
  3. 把有自己dump方法的JSONPlugin给install到app里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MongoEncoder(JSONEncoder):
    def mongo_dumps(obj):
        # convert all iterables to lists
        if hasattr(obj, '__iter__'):
            return list(obj)
        # convert cursors to lists
        elif isinstance(obj, pymongo.cursor.Cursor):
            return list(obj)
        # convert ObjectId to string
        elif isinstance(obj, bson.objectid.ObjectId):
            return unicode(obj)
        # dereference DBRef
        elif isinstance(obj, bson.dbref.DBRef):
            return db.dereference(obj) # db is the incetance database
        # convert dates to strings
        elif isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) or isinstance(obj, datetime.time):
            return unicode(obj)
        return json.JSONEncoder.default(self, obj)

app = app()
app.autojson = False
m_encoder = MongoEncoder()
app.install(JSONPlugin(json_dumps=lambda s: dumps(s, default=m_encoder.mongo_dumps)))

via:

异或

不介绍什么是异或了,有人叫半加、数学系的叫按位模2加

下文用得到的一些简单的性质

  • x^0 = xx^x = 0

  • 交换律:x^y = y^x

  • 结合律:(x^y)^z = x^(y^z)

  • 自反性:x^y^y = x

下面是几个小题目,可以用异或解决,挺有技巧性

交换两个数ab

1
2
3
a = a^b
b = a^b
a = a^b

有意思的是搜索其他异或例子的时候,发现了这篇文章,文章里实现了一个异或交换的算法,和本文主题无关,不过很有意思,函数更多的时候应该只操作值而不是变量。

UPDATE_2013-05-06: 这个,看到云风写了一个利用这个特性做的双向链表,挺好玩,忍不住写过来。

A集合里拿掉数x得到B集合,求x

XOR(X)表示将X集合内所有的数做异或

XOR(B)^XOR(A) = XOR(B)^XOR(B)^x = 0^x = x

1
2
3
4
A = (1..10000).to_a
B = A - [1234]
x = (A + B).reduce(&:^)
puts x #1234

via: http://www./topic/420487

A集合里拿掉数x、y得到B集合,求x和y

首先按上一个的办法可以推导出xor(A)^xor(B) = xor(B)^xor(B)^x^y = 0^x^y = x^y

x^y的二进制结果,第n位为1,说明x和y的第n位不相同

根据第n位是否为0把A里所有的数分成A1和A0两个数组(A1里的数的二进制第n位都是1,A0都是0)

A1和A0应该各包含了a或者b(这样第n位才能异或出1)

同理可以把B分成B1和B0两个数组

可以得到第一个数 x = A1^B1

第二个数可以y = A0^B0,当然也可以用x^y^x求得

另外如果x^y为0,即x == y,令SUM(X)为X集合内所有数求和

(SUM(A) - SUM(B)) / 2 = x

via: http://blog./uid-12453618-id-2935334.html

集合A里只有数x出现1次,其余数全都重复出现2次,求x

xor(A) = x^y^y^…^z^z = x^(y^y^…^z^z) = x^0 = x

1
x = A.reduce(&:^)

集合A里只有数x出现1次,其余数全都重复出现3次,求x

xor的本质相当于“按位模2加”(adding modulo 2),令p1,p2…pn为布尔值,true为1、false为0,(+)表示异或操作。

p1 (+) p2 (+) ... (+) pn == ( p1 + p2 + ... + pn ) % 2

所以只需要实现按位模3加

( p1 + p2 + ... + pn ) % 3

将集合中所有数二进制表示的同一位的0或1相加,最终的和对3去摸,得到的数即是x

A = {5, 7, 7, 7},二进制表示两个数

1
2
3
4
5
6
7
8
9
  101
  111
  111
+ 111
------
  434
%   3
------
  101

但愿这坨东西能让人看懂

via: http://www.cs./class/sum2003/cmsc311/Notes/BitOp/xor.html

没有^操作时候实现异或,只用&|~

这里的转换有很多,比如下面这个

x ^ y == (~x & y) | (x & ~y)

具体查看维基百科 《Equivalencies, elimination, and introduction》部分,各种公式

Xcode优化过的PNG

开始做iOS应用就有一个“公理”,图片素材要使用png格式,至于公理是怎么形成的完全不知道,只是听说在官方文档里提到过一句:苹果会对png进行优化。

为什么优化?谁优化的?什么时候优化的?怎么优化的?

和所有的魔术一样,说穿了就不好玩了。一切的根源是iPhone的显存。iPhone的vRAM在存放单个像素的颜色的时候,并不是按照传统的“红-绿-蓝”这样的顺序排列的,而是“蓝-绿-红”,即我们常说的RGB,在iPhone的显存里是BGR。并且,没有alpha通道。

另一边,png格式按照“红-绿-蓝”的顺序描述颜色,并且支持alpha通道的半透明,RGBA四个通道各占1个字节。

  • 为什么优化? 因为一边RGB一边BGR,一边有alpha一边没有alpha。
  • 谁优化的? 文章标题已经剧透了,Xcode优化的。
  • 什么时候优化的? Xcode在编译时,会对png资源进行优化。
  • 怎么优化的? 优化做了两件事:
    1. 把png里所有的RGB颜色转成BGR顺序
    2. 把png里所有的alpha通道先和RGB三通道先乘好(比如R:1 G:1 B:1 A:0.5的颜色直接转成 R:0.5 G:0.5 B:0.5)

这样最终设备在运行时渲染这些颜色的时候,不需要任何处理,一个汇编语句就把数据丢尽显存里了。

PS: 这里还有一个手动转换,和还原的办法

via: http://iphonedevelopment./2008/10/iphone-optimized-pngs.html

从wordpress搬到octopress

断断续续把wordpress转换到octopress上了。这是z-blog转到wordpress之后第二次更换博客系统了,octopress很酷,markdown的数据复用、搬家、存档都比lamp的wordpress轻便的多。

从导出wordpress数据库,转换为markdown,部署到github,搬图片文件,转换评论,磨磨蹭蹭的前前后后大约拖延了有两周,到今天终于把域名解析给换到这里来了。

最头疼的是转换文章的脚本不见得可靠,老文章的格式乱七八糟需要一篇一篇手动去修正,我现在做了一半,至少保证最新的大约3/5的文章是修改过的友好的格式。

很久没有更新博客,evernote的博客素材已经攒了一大堆,有空一篇一篇写出来吧。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多