It is said to be, but how and why

NSURLRequest的超时陷阱

最近被报了个问题,说我们的模块在网络情况不佳的时候,接口访问经常在那儿等待,不会超时!

第一反应去查了代码里头设置的超时时间,发现设置的是30s,但是从表现来看,确实超时时间远超30s,经常一两分钟才超时,甚至更久。也就是说, 我明明设置了NSURLRequest(NSURLConnection)的超时时间,但是他却没有超时返回!超时参数timeoutInterval没 有生效!

开始怀疑系统的问题,于是上网查,终于在StackOverFlow上有人提到说iPhone的超时时间是4分钟;继续查找,发现有人提到,在iPhone上,仅仅当你使用POST方式的时候,系统的最小超时时间会是240s。

模态UIAlertView

UIAlertView,从个人角度来讲,认为苹果所提供的使用delegate,而将一个对话框的处理拆分为上下文的方式,并不是一个很好的方 案。很多时候,会复杂化程序以及处理逻辑,而一堆的if-else或者switch-case也是很烦人的一件事情。所以,很多开发者对它动手脚。

如果你需要找的是,能够优美的处理不同的UIAlertView按键事件,那么你可以参考林家男孩这篇博客

但是,如果你想找的是模态对话框的功能,你可以参照一下以下的内容。

NSArray和 Vector<struct>互转

最近写程序的时候遇到这样的问题,需要将Vector里头的struct转存到NSArray里头。
一般遇到这种问题,常见处理是再定义一个class,然后把struct里头的内容一一搬过来,然后放到NSArray里头。这个做法虽然麻烦,但是安全,不会引起其他的问题。
我不想再重新定义一个class,再为他初始化,写属性,转存的时候一一赋值,因为实在太麻烦了,我想直接用他的struct定义。所以,我通过NSValue来做这件事情。

C类型和NSValue之间的转换

#define MyGetNSValueFromCType(cValue) ([NSValue value:&cValue withObjCType:@encode(typeof(cValue))])
#define MySetCValueFromNSValue(ocValue, cValue) [ocValue getValue:&cValue]

使用方法如下:
int count = 10;
NSValue *value = MyGetNSValueFromCType(count);
int newCount;
MySetCValueFromNSValue(value, newCount);

Vector和NSArray之间的转化
#define MyGetArrayFromVector(vec) ({\
NSMutableArray *arr = [NSMutableArray array];\
for(int i = 0; i < vec.size(); i++)\
{\
NSValue *value = MyGetNSValueFromCType(vec[i]);\
if (value != nil)\
[arr addObject:value];\
}\
[arr count] == 0 ? nil : arr;\
})

#define MySetVectorFromArray(vec, type, arr) {\
for(int i = 0; i < [arr count]; i++)\
{\
type _value;\
MySetCValueFromNSValue([arr objectAtIndex:i], _value);\
vec.push_back(_value);\
}\
}

使用方法:
struct hello
{
int a;
int b;
};

vector<hello> aVector;
hello a;
a.a = 10;
a.b = 100;

hello b;
b.a = 20;
b.b = 200;

aVector.push_back(a);
aVector.push_back(b);
NSArray *myArr = NdGetArrayFromVector(aVector);

vector<hello> bVector;
NdSetVectorFromArray(bVector, hello, myArr);

注意:
这里的struct里头的成员类型只能是C语言的基础类型,不能是string,vector这些C++的类!因为它们不是简单的内存块,转换后的NSValue很容易出现依赖于原对象的内存的状况。(如果您仅在当前函数内使用转换后的对象,倒是没有问题的,但是这种需求应该不会出现吧^_^)

SSHViaUSB-通过USB连接iPhone的SSH

开发中有时候会遇到这样的情况,有人拿过来一台用户机,需要定位问题。该机器无法访问网络,但是你所需要的信息却需要ssh到这台机器上。这个时候就需要通过USB接口,进行端口复用,让SSH能够通过USB完成。

网上这样的工具很多,大多却都是Windows下的。Mac下其实这样的命令行工具也有,主要是利用usbmux(忘了他的链接地址,需要者自己google之)。有一个叫做tcprelay的python脚本利用usbmux实现了一个守护进程,能够让ssh通过usb通道完成。

我将该工具进行了简单的界面封装,做成了mac下的app,给公司的同事使用,大家都觉得还不错。一直是处于beta版,因为懒得改动。
下面贴几张截图:
e5b18fe5b995e5bfabe785a7-2011-09-02-e4b88be58d88112835
e5b18fe5b995e5bfabe785a7-2011-09-02-e4b88be58d88112850

版权声明:

该软件使用了usbmux,因而使用的也是GPLv2。

SSHViaUSB下载:

源代码:sshviausb

应用打包:sshviausb

iOS5:[UIDevice uniqueIdentifier]的替代方案

iOS5之后,原来获取iPhone的DeviceId的接口:[UIDevice uniqueIdentifier] 被废弃!

这个改动会影响非常多的人,尤其是数据分析者。由于iPhone取IMEI困难(属于私有方法),所以大多数应用将DeviceId,也就是uniqueIdentifier作为IMEI来使用。如果这个接口被废弃,那么,我们就需要寻求一个新的方式来标识唯一的设备。

官方推荐的方法是,每个应用内创建一个UUID来作为唯一标志,并将之存储,但是这个解决方法明显不能接受!原因是,你每次创建的UUID都是不一样的,意味着,你卸载后重新安装这个软件,生成的UUID就不一样了,无法达到我们将之作为数据分析的唯一标识符的要求。

现有的解决方案是,使用iPhone的Mac地址,因为Mac地址也是唯一的。unix有系统调用可以获取Mac地址。但是有些事情需要注意:

1.iPhone可能有多个Mac地址,wifi的地址,以及SIM卡的地址。一般来讲,我们取en0的地址,因为他是iPhone的wifi的地址,是肯定存在的。(例外情况依然有:市面上依然存在一部分联通的阉割版无wifi的iPhone)

2.Mac地址涉及到隐私,不应该胡乱将用户的Mac地址传播!所以我们需要将Mac地址进行hash之后,才能作为DeviceId上传。

网上已经有现成的解决方案:

https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5