Haven's Blog

此刻打吨,你将做梦;而此刻学习,你将圆梦. QQ交流群(疯狂IT人):93916004

Xcode7 Storyboard Reference

| Comments

Storyboard在团队开发中一直被人鄙弃,因为其Merge的时候很容易出现冲突。在Xcode7中Storyboard Reference的引入,这个问题将得到解决。

接下来我们就来看看它能做什么。

用Xcode7创建一个tabbar的工程。

  1. 分离storyboard

在Main.storyboard中选中要分离的UIViewController, 然后顺序点菜单:Editor->Refactor to Storyboard, 这样就可以将选中的UIViewController分离到一个新的storyboard中去。而在Main.storyboard中被分离出来的UIViewController将被Storyboard reference取代。点击它,我们看看它的属性,如图: 右边的属性表示这引Storyboard reference指向的Storyboard。

我们也可以拖一个Storyboard Reference出来,然后在它属性中选择指向的Storyboard建立关系。

  1. 不同Storyboard中相互引用UIViewController

在Main.storyboard中拖一个UIViewController,并设置其Storyboard ID为ThreeViewController(可以为任意值), 如下图:

然后在First.storyboard中拖一个Storyboard Reference, 并设置其属性,如图:

Storyboard Reference如果没有设定Refenenced ID, 那么就指向Storyboard的Initial View Controller, 指定了,就指向指定的View Controller.

很好用吧。

编译opencore-amr for iOS8并支持bitcode

| Comments

由于很多网友向我反应,这儿这个编译脚本不能成功编译iOS8的库,所以在空闲时间搞了一下, 让其支持iOS8与bitcode.

直接上菜

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/bin/sh

set -xe

VERSION="0.1.3"
SDKVERSION="8.4"
LIBSRCNAME="opencore-amr"

CURRENTPATH=`pwd`

mkdir -p "${CURRENTPATH}/src"
tar zxvf ${LIBSRCNAME}-${VERSION}.tar.gz -C "${CURRENTPATH}/src"
cd "${CURRENTPATH}/src/${LIBSRCNAME}-${VERSION}"

DEVELOPER=`xcode-select -print-path`
DEST="${CURRENTPATH}/lib-ios"
mkdir -p "${DEST}"

ARCHS="armv7 armv7s arm64 i386 x86_64"
# ARCHS="armv7"
LIBS="libopencore-amrnb.a libopencore-amrwb.a"

DEVELOPER=`xcode-select -print-path`

for arch in $ARCHS; do
case $arch in
arm*)

IOSV="-miphoneos-version-min=7.0"
if [ $arch == "arm64" ]
then
IOSV="-miphoneos-version-min=7.0"
fi

echo "Building for iOS $arch ****************"
SDKROOT="$(xcrun --sdk iphoneos --show-sdk-path)"
CC="$(xcrun --sdk iphoneos -f clang)"
CXX="$(xcrun --sdk iphoneos -f clang++)"
CPP="$(xcrun -sdk iphonesimulator -f clang++)"
CFLAGS="-isysroot $SDKROOT -arch $arch $IOSV -isystem $SDKROOT/usr/include -fembed-bitcode"
CXXFLAGS=$CFLAGS
CPPFLAGS=$CFLAGS
export CC CXX CFLAGS CXXFLAGS CPPFLAGS

./configure \
--host=arm-apple-darwin \
--prefix=$DEST \
--disable-shared --enable-static
;;
*)
IOSV="-mios-simulator-version-min=7.0"
echo "Building for iOS $arch*****************"

SDKROOT=`xcodebuild -version -sdk iphonesimulator Path`
CC="$(xcrun -sdk iphoneos -f clang)"
CXX="$(xcrun -sdk iphonesimulator -f clang++)"
CPP="$(xcrun -sdk iphonesimulator -f clang++)"
CFLAGS="-isysroot $SDKROOT -arch $arch $IOSV -isystem $SDKROOT/usr/include -fembed-bitcode"
CXXFLAGS=$CFLAGS
CPPFLAGS=$CFLAGS
export CC CXX CFLAGS CXXFLAGS CPPFLAGS
./configure \
--prefix=$DEST \
--disable-shared
;;
esac
make > /dev/null
make install
make clean
for i in $LIBS; do
mv $DEST/lib/$i $DEST/lib/$i.$arch
done
done

for i in $LIBS; do
input=""
for arch in $ARCHS; do
input="$input $DEST/lib/$i.$arch"
done
lipo -create -output $DEST/lib/$i $input
done

Mac iOS推送测试

| Comments

今天给大家介绍一个自己写的iOS推送测试程序,在Mac下有一个同类产品PushMeBaby,它使用的是.cer证书。一般我们都使用p12文件来保存证书与密钥,所以我写了一个用p12文件来测试推送的App,命名为EasyPush. 源码在此,感兴趣的朋友可以拿来看看。

使用到的第三方库有:CocoaAsyncSocket

库依赖管理:Carthage

OpenGL ES简明教程之2

| Comments

在本系统教程1中我们做好了准备,这次我们开始我们的OpenGLES的渲染。

Step 1

创建一个Single Page的iOS工程。

Step 2

创建一个UIView的子类,比如叫EGLView.
在EGLView.h中声明三个变量

1
2
3
EAGLContext *m_context;
GLuint m_renderbuffer;
GLuint m_framebuffer;

在EGLView.m中引入OpenglES头文件

1
2
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>

然后实现如下方法

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

- (id) initWithFrame: (CGRect) frame
{
    if (self = [super initWithFrame:frame]) {
        CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer;
        eaglLayer.opaque = YES;
        
        // step 1 创建Context
        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
        m_context = [[EAGLContext alloc] initWithAPI:api];

        if (!m_context) {
            api = kEAGLRenderingAPIOpenGLES1;
            m_context = [[EAGLContext alloc] initWithAPI:api];
        }

      // step 2 马上设置为当前Context
        if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
            return nil;
        }

        if (api == kEAGLRenderingAPIOpenGLES1) {
            NSLog(@"Using OpenGL ES 1.1");
        } else {
            NSLog(@"Using OpenGL ES 2.0");
        }

      // step 3 创建render buffer 也叫 color buffer
        glGenRenderbuffersOES(1, &m_renderbuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_renderbuffer);
        
        // step 4, 这一步一定要在step 3之后,否则会失败
        [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable: eaglLayer];
        
        
        // step 5 创建frame buffer
        glGenFramebuffersOES(1, &m_framebuffer);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, m_renderbuffer);
        
        //这句可有可无
        GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
        if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
            NSLog(@"err");
        }
        
        // step 6 设置 view port
        glViewport(0, 0, frame.size.width, frame.size.height);
        
        [self drawView: nil];
        m_timestamp = CACurrentMediaTime();

        CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView:)];
        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
    return self;
}

- (void) drawView: (CADisplayLink*) displayLink
{
    
    glLoadIdentity();
    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
     
    static GLfloat vertexData[] = {-0.4f,-0.4f, 0.0f, 0.4f,-0.4f, 0.0f, 0.0f, 0.4f, 0.0f};
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertexData);
    glColor4f(1.0f, 1.0f, 0.66f, 1.0f);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    [m_context presentRenderbuffer:GL_RENDERBUFFER];
}

Step 3

使用EGLView
在ViewController.m中的viewDidLoad中加以下代码

1
2
3
4
5
6
7
8
9
10
11
12
CGRect frameSize;
UIScreen* screen = [UIScreen mainScreen];
CGFloat    scale = 1.0;
if ([UIScreen instancesRespondToSelector:@selector(scale)])
{
    scale = [screen scale];
}
CGRect appFrame = [screen bounds];
frameSize       = CGRectMake(appFrame.origin.x, appFrame.origin.y, appFrame.size.width, appFrame.size.height);
EAGLView *v = [[EAGLView alloc] initWithFrame:frameSize];

[self.view addSubview:v];

运行吧,将会看到一个黄色的三角形,代码里有明确的注释不不多解释。
glVertexPointer第一个参数表示每个顶点占几个顶点数组成员,这儿3表示点3个(因为一个点是x,y,z). 第二个参数是顶点是什么类型数据,这儿是GLfloat对应的就是GL_FLOAT, 第三个是每个顶点之间的步长,如果数据中有存color就需要设置这儿,这儿没有color,所以就设为0表示边续,最后一个参数则是存顶点数据的内存。

glDrawArrays第一个参数表示绘制的方式,看下面图就明白了,第二个表示顶点数据内存中的起始索引,这儿为0,最后一个表示顶点的个数,三角形有3个顶点,所以这儿为3.如果不明白,再仔细消化一下。

时间仓促,难免有不少错误,还往指正。

iOS自动化测试

| Comments

给一些关键字,有时间再详细补上

MonkeyTalk

FruitStrap

ynma3k

Athrun

tuneup

InstrumentsDriver

ULAutomation

NodeJS版本管理

| Comments

在Mac上可以通过brew来更新nodejs

1
sudo brew upgrade node

还有一种方法是用n, n也是nodejs的项目,首先安装它:

1
sudo npm install -g n

下面命令升级nodejs

1
2
3
sudo n 0.10.33
sudo n stable
sudo n latest

更详细的命令请查看使用帮助:

1
n --help

时间仓促,难免有不少错误,还往指正。

Java解析Html

| Comments

最近用到了Java解析Html的一个库Jsoup, 这儿是官网, 在此分享给大家,有这方面需要的朋友可以试一试。

有三个类需要我们了解,分别是Document,Elements,Element

大至用法有两步

第一步:加载html,,这儿提供两种方式,一种是从本地加载,一种是从网上直接加载。

从本地加载:

1
2
String html = "YOU HTML STRING";
Document doc = Jsoup.parse(html);

也可以直接从文件加载

1
2
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

通过url从网络加载

1
2
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
String title = doc.title();

上面是通过http的get方法,下可以通过post来获取

1
2
3
4
5
6
Document doc = Jsoup.connect("http://example.com")
  .data("query", "Java")
  .userAgent("Safari")
  .cookie("auth", "token")
  .timeout(3000)
  .post();

第二步:定位元素

通过定义的api定位无素

定位body

1
2
3
String html = "<div><p>Lorem ipsum.</p>";
Document doc = Jsoup.parseBodyFragment(html);
Element body = doc.body();

定位标签

1
2
3
4
5
6
Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
  String linkHref = link.attr("href");
  String linkText = link.text();
}

常用的API有

查找API:

1
2
3
4
5
6
getElementById(String id)
getElementsByTag(String tag)
getElementsByClass(String className)
getElementsByAttribute(String key) (and related methods)
兄弟关系的:siblingElements(), firstElementSibling(), lastElementSibling(); nextElementSibling(), previousElementSibling()
父子关系的: parent(), children(), child(int index)

值操作API:

1
2
3
4
5
6
7
8
attr(String key) to get and attr(String key, String value) to set attributes
attributes() to get all attributes
id(), className() and classNames()
text() to get and text(String value) to set the text content
html() to get and html(String value) to set the inner HTML content
outerHtml() to get the outer HTML value
data() to get data content (e.g. of script and style tags)
tag() and tagName()

修改API

1
2
3
4
append(String html), prepend(String html)
appendText(String text), prependText(String text)
appendElement(String tagName), prependElement(String tagName)
html(String value)

通过select语法定位元素

这个不好用文字表达,直接看官网文档吧.

时间仓促,难免有不少错误,还往指正。

Ionic简明教程一

| Comments

ionic是一个Hybrid框架,关于它的介绍可以看它的官网

要使用这个框架,得配置环境。
需要安装nodejs,自行google。

安装cordova, ionic,cordova是什么?你应听说过PhoneGap吧,就是它,同一个东西。

1
sudo npm install -g cordova ionic

在Mac上开发测试iOS需要模拟器,还需要安装ios-sim

1
sudo npm -g install ios-sim

而Android则需要Ant, 在这儿下载并解压放到本地目录,然后配置环境变量

1
2
export ANT_HOME=/usr/local/apache-ant-1.9.4
export PATH=${PATH}:${ANT_HOME}/bin

查看ant版本

1
ant -version

下面就可以通过ionic的CLI来创建工程:

1
ionic start myApp tabs

其中myApp是工程名字,tabs是内置模板中的一种,与xcode创建iOS工程的一样,有模板选择。inoic内置模板包括:blank,tabs,sidemenu

下面编译并运行项目:

1
2
3
4
cd myApp
$ ionic platform add ios
$ ionic build ios
$ ionic emulate ios

发果一切顺利,就会启动iOS的模拟器运行工程。

同时也可以使用浏览器来测试:

1
2
ionic serve
ionic serve --lab

编译与运行一步到位

1
ionic run ios 

更新cordova与ionic

1
npm update -g cordova ionic

更新项目中使用的js库

1
ionic lib update 

查看ionic版本

1
ionic -v 

ionic run android如果出现Failure [INSTALL_FAILED_OLDER_SDK],表示你用高版本的sdk编译,安装到低版本的android系统上,所以需要重新配置模拟器的target api level; 如果出现HAX is not installed on this machine (/dev/HAX is missing).表示没有安装Inter X86 Emulator Accelerator(HAXM installer),在Android SDK Manager下的Extras里。 这儿ADT里显示是installed,其实是没有安装的,需要到android sdk目录下的extras/intel/Hardware_Accelerated_Execution_Manager 中手动安装。

时间仓促,难免有不少错误,还往指正。

拯救越狱白苹果

| Comments

今天要一大早,太操蛋了,好久没玩越狱了,用了一个重启命令

1
killall -HUP SpringBoard

结果成了白苹果了。

然后我在ssh中用reboot重启,还是白苹果,最后用Home+开机键关机后重启还是不能解决。

重刷系统

首先强制关机Home+Power键 然后按一直按住Power键,直到屏上出现白苹果时(不要松开Power键)再按住Home键,当屏幕黑屏后松开Power键(Home键不要松),直到电脑ITunes上有反应时才松开。

如果不成功多次几次,顺序是Power->Power+Home->Home,先按先放,后按后放的原则,理一下过程就清楚了。

当ITunes检测到Recovery Mode,Mac系统上按住Option键(Windows上按Shift键)并点击Restore,在弹出的对话框中选你下载的iOS固件(ipsw文件),然后就是等待了。

安全模式

1、如果遭遇循环重启或白苹果,同时按住电源键和 Home 键
2、当苹果 Logo 出现又消失后松开两个键
3、同时按住电源键和音量增加键开机
4、当苹果 Logo 出现时,松开电源键,但一直按住音量增加键直至启动完成
5、前往 Cydia 卸载所有你认为和循环重启有关的插件
6、如果问题未能解决重复以上五步
7、问题解决

我只知道这两种解决白苹果,如果你有更好的方法还望告之。

时间仓促,难免有不少错误,还往指正。

OpenGL ES简明教程之1

| Comments

最近在弄一点3D相关的东西,大概有四年没有做3D相关的东西了,也忘得差不多了。我就把最近学到的东西总结一下,记录一下,方便查询。

在iOS上开发3D的东西,有三个选择:OpenGLES,GLKit,Metal.

我选择了直接用OpenGLES,因为这样更了解底层。 GLKit也是封装了OpenGLES, Metal则是新出来的苹果3D技术,也学微软了出自己DirectX标准.

iOS7就支持OpenGLES 1.0, 2.0,3.0。

本系列教程先介绍并学习OpenGLES 1.0,OpenGLES 1.0学完以后,再过渡到2.0, 最后再上3.0.因为学东西要先学基础,再深入,这样更容易。

在学习的过程中会用到PowerVR SDK, 大家可以去这儿下载并安装。

还会用到3D建模工具Blender,也请自行下载。

还会用到Blender导出格式为pod的插件与导出格式为collada格式的插件。

安装插件的方式,就是将下载好的插件文件复制到以下目录

1
/Applications/Blender/blender.app/Contents/Resources/2.73/scripts/addons/

collada格式的插件在这儿下载.

PowerVR Gen Pod的插件是在以下目录

1
/Applications/Imagination/PowerVR_Graphics/PowerVR_Tools/PVRGeoPOD/Plugins/Blender/OSX_x86/

注意是复制目录下的文件

要导出pod,还需要进Blender配置一下。打开blender, 左下角的列表中选择User Preference,在打开的界面中选择Addon,在Import-Export栏中找到Import-Export:PVRGeoPOD,并将其右侧的checkbox选中,保存用户设置。

还不明白的可以看这儿,有图有真相。

先准备好这些,下一节开始OpenGLES实战。

搞3D,给大家推荐两本书:

《iPhone 3D Programming》
《Learning OpenGL ES for iOS》

时间仓促,难免有不少错误,还往指正。