让iOS使用SSH Tunnel

为了突破局域网的限制,目前主流的方法还是SSH和VPN。 如果使用VPN的话,可以很方便的在自己的iPhone/iTouch/iPad设备上连VPN,上外网。 肯定还有不少朋友是在用SSH的。在自己的机器上一般使用以下命令来连接ssh,并且绑定到127.0.0.1:8080。 $ssh -D 8080 username@sshserver.com 之后,我们可以在设置proxy的地方指定proxy为127.0.0.1:8080。 但是在iOS上,如果不越狱的话是不能用SSH的。这样,我们必须让ssh绑定到外部IP,并且让iOS知道这个proxy。 假设本机的IP为192.168.1.2 步骤如下: 1. 不能再用上面这个命令来使用SSH了,命令如下 $ssh -g -D 192.168.1.2:8080 username@sshserver.com 这让SSH把连接转发到192.168.1.2:8080这个地址,-g让外部机器可以连到这个地址 2. 我们需要一个PAC文件。这是一个指定如何配置proxy的文件。 新建文件proxy.pac 内容如下 function FindProxyForURL(url, host) { return “SOCKS 192.168.1.2:8080″; } 3. 我们还需要让本机之外的其他机器可以访问到这个pac文件。比如,我们这里用HTTP来做。 Mac本身就支持Web Sharing,其实是一个Apache的Server。 在”System Preferences”->“Sharing”里,给Web Sharing打上勾. 把上面的proxy.pac文件拷贝到~/Sites/下面,这时,我们可以在浏览器里试试这个地址 http://192.168.1.2/~username/proxy.pac 看看是不是能够看到文件内容? 在lion下,可能会出现没办法勾选Web Sharing的情况。把httpd.conf用原始版本覆盖即可 $sudo cp /etc/apache2/original/httpd.conf /etc/apache2/httpd.conf 4.万事俱备,现在只要在iOS上设置就行了。 通过”Settings”->”WLAN Networks”找到现在连上的Wifi,查看details(蓝色箭头) 在最下面有设置http proxy的地方。 选择”Auto”, 填入 http://192.168.1.2/~username/proxy.pac […]

[cocoa demo]从图片中选取Frame的小工具

和设计相比,开发者的好处是遇到不好用的App就可以牛B哄哄的说: “这个不给力啊,等哪天有空的时候自己做一个吧”。 等到真正要做的时候就愣了,满脑子的按钮不知道怎么摆…. 在学校的时候,做的东西对UI的要求很低,不求美观,只要基本功能有就行了。 更不要谈什么用户体验,是不是User-Friendly之类的了。 工作的时候就大不一样了,做prototype的时候界面可能很粗糙。 但是等到Designer的东西(一般管这个叫mockup)出来,感觉就完全不一样了。 作为码农,常常觉得自己没有审美观…. 我认为完全重现mockup的效果是很重要的,尤其是一些细节。 功能上开发者可以发挥,但是在自己不擅长的领域还是不要胡闹了。 好了,扯远了…. 其实只是因为最近想学mac上的开发,然后因为有以上需求, 所以做了一个非常简单的工具作为练习。 真的很简单….不过如果你恰好有同样的需求,我觉得它还是有帮助的。 至少作为一个cocoa入门的demo,还是挺好的。 就是从mockup里框取一块区域,得到经过转换坐标的Frame。 左上的Button是用来打开图片文件的,左下的是用来切换显示的。 代码在Github上: GetFrame App下载链接: GetFrame.zip mac下的图标格式是icns 用这个网站转换图标比较方便,推荐一下: http://iconverticons.com/

[iOS]delegate和protocol

今天上班和同事讨论工程怎么组织的时候涉及到这个话题。 iOS开发上对delegate使用广泛。 记在这里,如果有新人Google到了,希望能有点帮助。 protocol和delegate完全不是一回事,放在一起说,只是因为我们经常在同一个头文件里看到这两个word。 protocol和java里interface的概念类似,是Objective-C语法的一部分。 定义protocol如下 @protocol ClassADelegate – (void)methodA; – (void)methodB; @end 那么就是定义了一组函数,这组函数放在一起叫作一个protocol,也就是协议。 函数是需要被实现的,所以如果对于class如下 @interface ClassB { } @end 就叫作ClassB conform to protocol ClassADelegate,也就是说ClassB实现了这个协议, 也就是实现了这一组函数。 有了上面这个头文件,我们就可以放心作调用 ClassB *b = [[ClassB alloc] init]; [b methodA]; [b methodB]; 而不用担心出现unrecognized selector sent to instance这种错误了。 所以protocol就是一组函数定义,是从类声明中剥离出来的一组定义。 id b = …; [b methodA]; 这种用法也常见,b是一个id类型,它知道ClassADelegate这组函数的实现。 那么delegate是什么?其实和protocol没有关系。Delegate本身应该称为一种设计模式。 是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。 比如ClassC @interface ClassC […]

[iOS]一句话Tip之redefinition of class

编译工程发现报redefinition of classXXX的错,但是确实是采用#import而不是#include包含头文件的时候,请从Finder里看看整个工程目录下是不是有两个同名的头文件…有的话这就是罪魁祸首,删之。 为了这问题折腾了好半天,当时多么希望能搜到一点提示… redefinition错误指编译器发现重复定义的类或者结构,用objective-C的时候建议全部采用#import,可以避免一个头文件被包含多次。 当然遇到坑爹的IDE又是另外一回事了…

[Tip]iOS上的OpenGLES无显示问题

最近的项目用到了OpenGLES。 两个很容易出问题的地方,容易造成很难找到的Bug。 一个是EAGLLayer的大小,必须是32的倍数。否则用OpenGL画出来的东西,统统不会被显示。 Apple的文档:In iOS 4.2 and later, the performance of Core Animation rotations of renderbuffers have been significantly improved, and are now the preferred way to rotate content between landscape and portrait mode. For best performance, ensure the renderbuffer’s height and width are each a multiple of 32 pixels. Apple Document 另一个是纹理的大小,必须是2的次方。 也就是说,如果使用一张图片来生成纹理,那么图片的长和宽的长度都必须是2的次方,否则加载纹理失败。

[Ruby]debian上更新gem

用Rails的时候需要配环境,配环境的大头是安装gem,安装gem的时候就会遇到各种令人崩溃的问题…Orz… 环境是Debian,需要安装refinerycms,出现了gem版本过低的错误。 比较通用的做法是 $gem update –system 但是可能会遇到这个错误 ERROR: While executing gem … (RuntimeError) gem update –system is disabled on Debian. RubyGems can be updated using the official Debian repositories by aptitude or apt-get. 这种情况下就需要自己动手。 这里需要安装的是gem 1.3.6的版本。 先得到rubygems-update-1.3.6.gem,可以直接下载得到 $wget http://gems.rubyforge.org/gems/rubygems-update-1.3.6.gem 然后安装这个叫作rubygems-update的gem $sudo gem install rubygems-update-1.3.6.gem 也可以 $sudo gem install rubygems-update -v=1.3.6 然后执行update_rubygems这个脚本 这个文件的位置由之前gem的设定而定。 $which update_rubygems /home/XXX/.gem/bin/update_rubygems […]