目前分類:ios開發筆記 (78)

瀏覽方式: 標題列表 簡短摘要
转自
当我们加载Html时候,会在我们data/应用package下生成database与cache两个文件夹:
我们请求的Url记录是保存在webviewCache.db里,而url的内容是保存在webviewCache文件夹下.
WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源)、H5缓存(即AppCache)。

 

一、网页缓存

1、缓存构成
/data/data/package_name/cache/
/data/data/package_name/database/webview.db

戮克 發表在 痞客邦 留言(0) 人氣()

作 者: zhuliang
时 间: 2013-04-02,17:09:40
原文: http://bbs.pediy.com/showthread.php?t=167398 来自看雪论坛


本文阐述如何在iOS平台上对应用程序进行调试与分析,旨在指导新手分析iOS程序,高手请无视。内容包括软件硬件的准备、代码的解密、符号信息的获取、用gdb调试等,最后以京东LeBook为例子进行演示。
1.为什么要进行调试与分析
研究iOS程序有很多用处,比如:
找bug或者漏洞,想知道某程序有没有漏洞或者bug。
某程序能实现某功能,我想知道如何实现,如ios6发短信功能,还有比较时髦的iPhone5通话录音功能。
对iOS程序进行DIY扩展功能,比如曾半仙前辈的作弊插件http://bbs.pediy.com/showthread.php?t=163435,就是一个例子。2011年的时候我也实现了类似的功能,做了一个iPhone版的“欢乐斗地主”的记牌器功能。有朋友问到如何实现的,主要就是hook了recv函数,从封包得到想要的信息,经过处理得知54张牌还剩什么牌。
总的来说对iOS程序进行调试与分析的目的和调试与分析Windows平台程序的目的是一样的。

2. 调试与分析的准备工作
iOS的封闭性极大地增大研究它的难度。为使系统更加安全,iOS引入了很多安全机制;如代码加密,使得分析前先要解密代码,SandBox(沙盒),code signing(代码签名),使得不能运行未签名的代码。这些安全机制使得研究它的难度比Linux/Windows要大。
尽管这样,并不能阻挡我们前进的脚步。
必要的硬件准备:一个越狱的设备,最好是iPhone
  越狱是必要的,因为只有越狱才能运行非AppStore上的软件。
必要的软件准备:在Cydia里安装下面的软件
    1.OpenSSH,OpenSSH是Linux下常用的服务,装上后设备可充当服务SSH服务端
    2.GNU Debugger(gdb)调试工具
    3.adv-cmds(ps命令)
    4. darwin cc tools (otools)
    5. Link Identity Editor (ldid)
PC端安装SSH Secure Shell Client或putty等SSH客户端软件,以便能通过SSH建立到设备的连接。
Ida pro,该软件搞过逆向的都熟悉,静态分析功能很强大,特别是大于或等于6.2的版本,能识别Objective-C结构,能把Objective-C函数名显示如下图:

Hopper Disassembler,该软件是刚出来没多久的,我还没用过,据说功能也很强大。不管怎么说ida pro是太贵了,一般个人很少买得起,这时候Hopper Disassembler是另一个选择。最后是class-dump-z,在没有上面两个工具的情况下用它能获得符号信息。
有了软硬件的准备,便可以开始调试了。
1.PC端运行SSH客户端,连接到设备,输入用户名:root,默认密码:alpine,第一次连接上去后建议用passwd命令改掉默认密码,以防黑客通过局域网入侵。
2.在设备上运行想调试的程序,如iRead,运行命令ps –ax可以看到所有运行的进程id,gdb –p pid这样就可以调试指定进程(gdb –p 10110)。
另外,可以通过otool –l | grep crypt 输出可知道已加密代码的位置。有这些准备后,我们可以先运行下面命令测试一下。
SSH Secure Shell 3.2.9 (Build 283)
Copyright (c) 2000-2003 SSH Communications Security Corp - http://www.ssh.com/
This copy of SSH Secure Shell is a non-commercial version.
This version does not include PKI and PKCS #11 functionality.
MMs-iPod:~ root# passwd
Changing password for root.
New password:
Retype new password:
MMs-iPod:~ root# ps -ax
  PID TTY           TIME CMD
……(省略部分无关记录)
12416 ??         0:02.52 /var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/iRead
……(省略部分无关记录)
MMs-iPod:~ root# gdb -p 12416
/usr/bin/gdb: line 55: awk: command not found
warning: unrecognized host cpusubtype , defaulting to host==armv7.
GNU gdb 6.3.50-20050815 (Apple version gdb-1708 + reverse.put.as patches v0.4) (Mon Apr 16 00:53:47 UTC 2012)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "arm-apple-darwin".
/private/var/root/12416: No such file or directory
Attaching to process 12416.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............................................................................................................................................. done
Reading symbols for shared libraries + done
0x39556eb4 in mach_msg_trap ()
(gdb) quit
The program is running.  Quit anyway (and detach it)? (y or n) y
Detaching from process 12416.
MMs-iPod:~ root# otool -l /var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/iRead | grep crypt
cryptoff  8192
cryptsize 8601600
cryptid   1

3.解密代码并用IDA和gdb分析
按上文的步骤便能通过gdb来调试iOS平台的应用程序,但是在gdb下看代码是很不方便的,肯定没有在我们熟悉的ida pro上看得舒服。为了能在ida上进行静态分析,需要先去除DRM保护,iOS程序往往是以加密的状态存在于正版app的ipa文件中的,只有去除掉DRM保护(俗称ipa破解),才能用ida来进行静态分析。也许有人会说,用如维享应用汇、91助手、PP助手等工具下载下来的ipa直接拖到ida里就能分析,需知道这样的ipa是经过破解了的,不是正版的ipa。
3.1DRM破解(代码解密)基本原理
1.定位到待破解软件在var/mobile/Applications下所在位置 
2.复制软件目录下所有的文件到一个临时目录 
3.用工具otool分析程序主文件,找出cryptsize和cryptid 
4.运行待破解程序,用gdb附加到目标进程 
5.因为程序已经运行,所以此时是解密状态。dump当前未加密的内存 
6.将dunp结果输出到一个bin文件,退出gdb调试程序
7.将主程序文件的cryptid字段改为0,改加密状态为未加密 
8.将dump出来的bin文件中的未加密内存的内容覆盖到原主程序文件的相应位置 
9.对主程序签名 
10.删除一些垃圾文件 
11.打包IPA
下面以京东LeBook为例子,用gdb手工解密,具体操作如下:
先通过SSH客户端连接到iOS设备上,切换到对应程序的目录。依次输入下面的命令:
root# cd /var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/
root# gdb -e ./iRead     
/usr/bin/gdb: line 55: awk: command not found
warning: unrecognized host cpusubtype , defaulting to host==armv7.
/usr/bin/gdb: line 136: file: command not found
/usr/bin/gdb: line 171: file: command not found
/usr/bin/gdb: line 171: awk: command not found
GNU gdb 6.3.50-20050815 (Apple version gdb-1708 + reverse.put.as patches v0.4) (Mon Apr 16 00:53:47 UTC 2012)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "arm-apple-darwin".Reading symbols for shared libraries .. done
(gdb) set sharedlibrary load-rules ".*" ".*" none
(gdb) set inferior-auto-start-dyld off
(gdb) set sharedlibrary preload-libraries off
(gdb) rb doModInitFunctions
Breakpoint 1 at 0x2fe0cece
<function, no debug info> __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE;
(gdb) r
Starting program: /private/var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/iRead 
Breakpoint 1, 0x2fe0cece in __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE ()
(gdb)  dump memory dec.bin 0x3000 0x837000
该命令是把已解密的内存dump到dec.bin文件中,0x3000为开始地址,0x837000为结束地址,为什么是这两个地址呢?
从上文otool的输出知道cryptoff=8192(0x2000),cryptsize=8601600(0x834000),而当地址空间被加载的时候,开始地址是0x1000,而不是0x000。0x2000+0x1000等于0x3000,所以开始地址为0x3000,结束地址为开始地址加上被加密的映像大小,为0x3000+0x834000=0x837000。
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) q
到此,我们得到解密后代码,只要用它来替换掉原来被加密的代码即可,
root#cp iRead iRead.bak
root# dd seek=8192 bs=1 conv=notrunc if=./dec.bin of=./iRead
上面这条命令在iOS设备上执行完要大大几分钟,用WinHex来进行替换会快很多,从文件偏移8192(0x2000)开始替换,大小为加密块大小0x834000字节。在可执行程序有两个或多于两个Fat header的情况下,开始替换的偏移地址还要加上Architecture Offset,Architecture Offset可以用命令“otool –f ./iRead”得到。可参考《Hacking and Securing iOS Applications》第七章,解释得很详细具体。另喜欢看中文的朋友可以参考论坛里肖兄(Claud)的文章http://bbs.pediy.com/showthread.php?t=152843 ,只是要注意的是,要在doModInitFunctions下断,而最好不要在程序入口点下断。因为如果断在程序入口点,动态库的入口函数已被调用,有些程序会被inline hook,有可能造成dump出来的内容是错的。
接下来把cryptid由1改为0,表示不加密。再用“ldid –S iRead”重新签一下。而cryptid可以这样来定位到,从刚才替换区域开始处往上拉,一直拉到能看到很多.dylib的路径,放慢速度仔细看,在最后一个dylib的地方,再往上大概0x28的地方有个01,把它改为00就行,如果不是很确定,可以通过“otool -l iRead | grep crypt”来看cryptid是否变为0来确定。
至此完成代码解密,再打包成ipa文件便完成app的破解。
另外还可以在Cydia里装上Crackulous软件来破解,Crackulous软件是全自动化的图形界面的破解程序。只要点几下就能生成破解后的ipa文件,方便易用快捷。但是也有个缺点,就是有些软件不能用它来破解。相对于第二个是全自动化的方法,第一个方法虽然比较麻烦,但便于理解过程。
3.2获取符号信息便于调试
获取到尽可能多的符号信息对分析调试有很大的帮助,就像在茫茫大海中航行的船找到了灯塔,不至于迷失方向,不知所措。有了足够多的符号,我们就可以迅速地定位目标程序的关键点,不会迷失在二进制的海洋中,因找不到方向而无从下手。
前文提到了,利用ida pro可以帮助我们获取符号,特别是大于或等于6.2的版本,能识别Objective-C结构,能把Objective-C函数全都识别出来,如下图,为本人利用ida 6.4打开京东LeBook-1.0.4的截图。
 
可以从左边Functions window看出来,没有一个函数是以“sub_”开头的,也就说所有的函数都识别出来了。
没有ida pro的朋友可以使用Hopper Disassembler,也能把Objective-C函数识别出来。在版权方要求删除之前,可以从看雪论坛下载到。据说该软件很好用,但因本人习惯了ida pro没使用过它,不便进行过多的评论。
上面说到的两个软件都是商业软件,不是人人都愿意买或买得起,这时还可以利用class-dump-z获取符号信息,建议不能使用盗版、不愿意使用盗版而又没钱买正版的朋友使用,它的命令行如下:
  class-dump-z.exe -u armv7 -A -a iRead  >  iRead.txt
     class-dump-z.exe -u armv7 -A -a iRead -H -o C:\
其中-u armv7这个参数比较有用,而class-dump和class-dump-x 不支持-u armv7参数。两年前,ida pro还没有更新到6.2,Hopper Disassembler还没有问世,class-dump-z是唯一的选择。本人就是使用它来获取符号信息的。
上面的命令行生成的iRead.txt文件的部分内容如下图:

可以很清楚地看到类叫什么名,是如何定义的,有哪些成员,继承了哪些接口,还有函数的实现地址。这些信息都是对逆向很有用的信息。
3.3用gdb进行调试
有了足够的符号信息,通过静态分析,我们可以初步猜出程序的逻辑,哪里是关键点,再通过动态跟踪来证实猜想,结合上面给出的调试的步骤,下面开始用gdb进行调试:
ps –au                     注意输出信息中目标进程的pid
gdb –p pid              从上面的输出信息得到进程pid
info sh                      注意目标的基地址,记为base
break *(0xAABBCC+base)  0xAABBCC为你想下断点的地址
display /x $r0
display / $pc | $cpsr.t
ni
在实际的环境,命令行如下:
MMs-iPod:~ root# ps -ax
  PID TTY           TIME CMD
……(省略部分无关记录)
12416 ??         0:02.52 /var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/iRead
……(省略部分无关记录)
MMs-iPod:~ root# gdb -p 12416
/usr/bin/gdb: line 55: awk: command not found
warning: unrecognized host cpusubtype , defaulting to host==armv7.
GNU gdb 6.3.50-20050815 (Apple version gdb-1708 + reverse.put.as patches v0.4) (Mon Apr 16 00:53:47 UTC 2012)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "arm-apple-darwin".
/private/var/root/12416: No such file or directory
Attaching to process 12416.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............................................................................................................................................. done
Reading symbols for shared libraries + done
0x39556eb4 in mach_msg_trap ()
(gdb) info sh
info sh
The DYLD shared library state has not yet been initialized.
                                          Requested State Current State
Num Basename                Type Address         Reason | | Source     
  | |                          | |                    | | | |          
  1 iRead                      - 0x26000           exec C C /private/var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/iRead at 0x26000 (offset 0x25000)
                                               (objfile is) [memory object "/private/var/mobile/Applications/4DFD17D1-39AC-4F10-8AB8-3A4CB99E9E77/iRead.app/iRead" at 0x26000]
这条命令info sh很重要,特别强调一下。很多网友在QQ群小窗问我这个问题,ida里看到某个关键函数的地址为0x1C4038,用gdb成功附加进程后,break *0x1C4038下断点,老是断不下来,为什么呢。出现这样的情况是因为断点没下对,程序在编译时启用了PIE(Position Independent Executables),该安全机制是从ios4.3开始引进的,和Windows下的ASLR类似,这时候下断点的地址要加上基地址才对。注意到括号里的“(offset 0x25000)”,故这样下断(gdb) break *(0x25000+0x1C4038)
Breakpoint 1 at 0x1e9038

如果不肯定断点下得对不对,可用下面的gdb命令来确认,
(gdb) x/10i (0x25000+0x1C4038)+1
0x1e9039:  b5 03                         push   {r4, r5, r6, r7, lr}
0x1e903b:  af 4d                         add    r7, sp, #12
0x1e903d:  f8 04 8d 84                   str.w  r8, [sp, #-4]!
0x1e9041:  b0 05                         sub    sp, #16
0x1e9043:  46 00                         mov    r5, r0
0x1e9045:  20 0c                         movs   r0, #0
0x1e9047:  46 03                         mov    r4, r1
0x1e9049:  90 02                         str    r0, [sp, #12]
0x1e904b:  90 00                         str    r0, [sp, #8]
0x1e904d:  2a 18                         cmp    r2, #0
看到gdb反汇编出来的代码和ida里显示的一样,继续运行
(gdb) c
Continuing.
程序运行后,在iOS设备上点击一本书畅读,断点被触发中断下来,这时可以用如下display命令显示和ni或si一步一步跟进去分析。
Breakpoint 1, 0x001e9038 in dyld_stub_pthread_key_create ()
(gdb) display /x $r0
1: /x $r0 = 0x1fdae580
(gdb) display /i $pc | $cpsr.t
2: x/i $pc | $cpsr.t  0x1e9038:  f0 b5  push   {r4, r5, r6, r7, lr}
补充一点,如果觉得每次下断的地址都要加上基地址比较麻烦,可以像我们在Windows下调试启用了ASLR功能的程序那样操作,通过把PE头中表示ASLR的bit清零来禁用ASLR功能。对于iOS系统,mach_header是如下定义的,
struct mach_header
{
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};
根据头文件里的“#define MH_PIE 0x200000”,我们只要把flags里bit21清零即可。对程序进行了改动,重新签名一下“ldid –S iRead”,再重新运行,就会发现程序基地址不会再变化了。
还可以用removePIE(https://github.com/peterfillmore/removePIE)程序来帮我们做相同的工作。可以从代码看出工作原理是完全一样的。
最后,如何觉得gdb界面不够友好,用它来调试得不爽,还可以参考论坛obaby的帖子 (http://bbs.pediy.com/showthread.php?t=138472),用ida pro来进行图形化界面的调试。

4. 京东LeBook不严谨逻辑的绕过的演示
4.1背景交待
       京东商城(www.360buy.com)上10元的畅读卡,可以下载京东LeBook软件后,用该软件下载1000本电子书来阅读,但是有两个限制,一是要联网才能看,二是只能在一个月内看。还有下载的电子书以加密形式存在。
经过分析发现京东LeBook验证逻辑不是很严谨,既然解密pdf所需要的certificate都设计为从网络传送过来了,是不是畅读却简单地通过本地数据库来标识,这使得上面两个限制可以去掉。通过替换sqlite3数据库(jdreader.db)即可实现。
4.2绕过步骤
        解压附件中的injectHook1.zip(会员区有bin)到以下目录, /Library/MobileSubstrate/DynamicLibraries,并执行命令:chmod +x injectHook1.dylib给它加上可执行属性。该dylib对iRead进行了两处Hook,一处是让iRead认为设备的udid为“4A696E67646F6E67283336306275792E636F6D29”(下文的random就是由它计算得到的),另一处是把解密所需要的certificate写到数据库。
注册A、B两账号,A账号出10元买一个畅读月卡,用A账号从设备登录然后注销;B账号从设备登录然后注销,最后用A再次登录。
在iOS设备上下载你所想要的电子书(按照游戏规则最多可下载1000本),在设备上点畅读,每本书打开一次。这样才能确保解密所需要的certificate存到数据库里。
结束京东LeBook程序,把它的数据库文件复制到电脑上,路径为:/Library/Application Support/Root/jdreader.db,对该数据库文件用SQLite Database Browser程序 (http://sqlitebrowser.sourceforge.net/)执行下面几条SQL命令

update LocalBook set userid=2 where isJoyRead=1 and hasdownload=1
update LocalBook set isJoyRead=0 where isJoyRead=1 and hasdownload=1
update User set random="0001X2NNi+0gEX6kKfArTVWJCBZnWjRBeWFpWmZBZHpiYVQ=" where id=2
把数据库文件复制回去,再次启动京东LeBook程序,接下来
4.3 让我们一起来见证奇迹的时刻


可以看到,畅读标志没有了,断网情况点击能顺利阅读了,两个限制成功地去掉了。














参考文献:
1.  《Hacking and Securing iOS Applications》
2.  https://developer.apple.com/library/...reference.html
最后
感谢cd-team的各位朋友,DarkMage(dm557),Windknown,Daniel,s1mbily,Danniez等。
感谢kanxue,Albert_liuwei等各位朋友!

戮克 發表在 痞客邦 留言(0) 人氣()

方法一#import "Reachability.h"
  BOOL isExistenceNetwork = YES;
    Reachability *r = [Reachability reachabilityWithHostName:GetAdInfoList];
    switch ([r currentReachabilityStatus]) {
        case NotReachable:
            isExistenceNetwork=NO;
            NSLog(@"没有网络");
            break;
        case ReachableViaWWAN:

戮克 發表在 痞客邦 留言(0) 人氣()

转自

 

IOS中最常用到的控件UIButton、UISlider、UISwitch、UISegmentedControl通过Xib文件拖动生成非常简单,其实用代码实现也是一样的简单,当然,用代码实现能够掌握到更多的东西。

上图中包涵提到的4种控件,UIButton按钮、UISlider滑块、UISwitch开关、UISegmentedControl分类

首先创建一个名为CodeControls的Empty Application项目

AppDelegate.h和AppDelegate.m文件中和IOS代码实现Hello World中的一样

 

戮克 發表在 痞客邦 留言(0) 人氣()

转自

原文地址:http://blog.csdn.net/newjerryj/article/details/6446370

 

  这种switch开关,应该算是apple的又一个界面创新了。 简单直观,使用方便。 本文就来介绍下switch控件在ios中的使用。

 

  在这里,我使用插入图片开关来作为示例吧。

 

  1  从Library中拖一个switch控件在vewcontroller视图控制器上。

戮克 發表在 痞客邦 留言(0) 人氣()

要说这个其实网上已有人发出老版本的使用方法,可惜,古董了,有了些变动,折腾了段时间,终于搞定。

(Ps:顺带提一下,要是大家看的网上的那个原版教材,里面获取  IMEI 的方式已经失效,高版本的IOS 个人测试 IOS 4.3就已经没得办法获取 IMEI 了,有替代的方法,是获取 MAC 地址,然后算MD5)
 
 
效果嘛,当然是不会调用系统的sms程序去发送了。也就可以后台发sms,也就没得记录,也是为了一个娱乐项目中需要的一个功能罢了。
 
首先要在工程中添加  CoreTelephony.framework 添加这个在其他教程中说是在Private framework 中添加,但是我是  Xcode 4.2  sdk 是IOS 5,那么这里就是在 Public framework 中了。
 
要想知道路径,就是如下:
 

戮克 發表在 痞客邦 留言(0) 人氣()

转自

1,项目需求,是程序home键切入后台,3分钟后退出登陆,

  首先,iOS 会再持续切入后台,给我们5秒钟的时间去处理相关数据,5秒后,程序不会再执行任何代码,处于挂起状态。

   

 

- (void)applicationDidEnterBackground:(UIApplication *)application {

 //切入后台 ,申请后台任务时间,

    UIApplication *app = [UIApplication sharedApplication];

    UIBackgroundTaskIdentifier taskID;//一个后台任务标识符

戮克 發表在 痞客邦 留言(0) 人氣()

转自

1、使用SharedApplication,定义一个变量来传递.

2、使用文件,或者NSUserdefault来传递

3、通过一个单例的class来传递

4、通过Delegate来传递

5、通过NSNotificationCenter来传递


戮克 發表在 痞客邦 留言(0) 人氣()

转自

把下边的代码 放到UIVIEWCONTROLLER里,就能实现摇一摇效果

  1. #pragma mark - Shake  
  2. - (BOOL) canBecomeFirstResponder  
  3. {  
  4.     return YES;  
  5. }  
  6. - (void) viewDidAppear:(BOOL)animated  
  7. {  
  8.     [super viewDidAppear:animated];  
  9.     [self becomeFirstResponder];  
  10. }  
  11. - (void) viewWillAppear:(BOOL)animated  
  12. {  
  13.     [self resignFirstResponder];  
  14.     [super viewWillAppear:animated];  
  15. }  
  16. - (void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event  
  17. {  
  18.     if (motion == UIEventSubtypeMotionShake) {  
  19.         NSLog(@"Shake..........");  
  20.     }  
  21. }  


使用这段代码需要注意的是,如果ViewController不是FirstResponder的话,那么当前窗口就得到摇一摇的动作。

可以将montionBegan的事件,放到UIWindos中会更好一些

 

戮克 發表在 痞客邦 留言(0) 人氣()

iOS系统自带的UIToolbar的样式简单,往往不能满足开发或特殊目的的需要,例如设置完全背景透明的UIToolbar或者自定义UIToolbar的背景色,这时候就需要对UIToolbar进行单独定制。

设置UIToolbar背景透明,只需要设置UIToolbar的backgroundColor为[UIColor clearColor]即可,如果需要单独定制UIToolbar的背景色,则需要继承并自己实现UIToolbar对象。

直接修改背景色请参照以下的方法1,继承并自己实现UIToolbar对象请参照方法2。





方法1



//使button的tint色与导航条一致

toolbar.tintColor = self.navigationController.navigationBar.tintColor;

toolbar.backgroundColor = [UIColor clearColor]; //设置为背景透明

for (UIView *view in [rightToolbar subviews]) {

戮克 發表在 痞客邦 留言(0) 人氣()

手把手教你ARC——iOS/Mac开发ARC入门和使用

Revolution of Objective-cRevolution of Objective-c

本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和讨论。请不要将本文的部分或全部内容用于商用,谢谢合作。

欢迎转载本文,但是转载请注明本文出处:http://www.onevcat.com/2012/06/arc-hand-by-hand/

本文适合人群:对iOS开发有一定基础,熟悉iOS开发中内存管理的Reference Counting机制,对ARC机制有听闻很向往但是一直由于种种原因没有使用的童鞋。本文将从ARC机理入手对这个解放广大iOS开发者的伟大机制进行一个剖析,并逐步引导你开始使用ARC。一旦习惯ARC,你一定会被它的简洁高效所征服。

写在开头

虽然距离WWDC2011和iOS 5已经快一年时间,但是很多开发者并没有利用新方法来提高自己的水平,这点在ARC的使用上非常明显(特别是国内,基本很少见到同行转向ARC)。我曾经询问过一些同行为什么不转向使用ARC,很多人的回答是担心内存管理不受自己控制..其实我个人认为这是对于ARC机制了解不足从而不自信,所导致的对新事物的恐惧。而作为最需要“追赶时髦”的职业,这样的心态将相当不利。谨以此文希望能清楚表述ARC的机理和用法,也希望能够成为现在中文入门教学缺失的补充。


什么是ARC

Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化。ARC是新的LLVM 3.0编译器的一项特性,使用ARC,可以说一举解决了广大iOS开发者所憎恨的手动内存管理的麻烦。

在工程中使用ARC非常简单:只需要像往常那样编写代码,只不过永远不写retain,release和autorelease三个关键字就好~这是ARC的基本原则。当ARC开启时,编译器将自动在代码合适的地方插入retain, release和autorelease,而作为开发者,完全不需要担心编译器会做错(除非开发者自己错用ARC了)。好了,ARC相当简单吧~到此为止,本教程结束。

等等…也许还有其他问题,最严重的问题是“我怎么确定让ARC来管理不会出问题?”或者“用ARC会让程序性能下降吧”。对于ARC不能正处理内存管理的质疑自从ARC出生以来就一直存在,而现在越来越多的代码转向ARC并取得了很好的效果,这证明了ARC是一套有效的简化开发复杂程度的机制,另外通过研究ARC的原理,可以知道使用ARC甚至能提高程序的效率。在接下来将详细解释ARC的运行机理并且提供了一个step-by-step的教程,将非ARC的程序转换为ARC。


ARC工作原理

手动内存管理的机理大家应该已经非常清楚了,简单来说,只要遵循以下三点就可以在手动内存管理中避免绝大部分的麻烦:

如果需要持有一个对象,那么对其发送retain 如果之后不再使用该对象,那么需要对其发送release(或者autorealse) 每一次对retain,alloc或者new的调用,需要对应一次release或autorealse调用

戮克 發表在 痞客邦 留言(0) 人氣()

前言:在表单验证中,我们经常会使用到正则,因为我们需要用它来判断用户输入的字符是否为合法的,如果是不合法的,那么应该提示用户输入错误,并不让提交至服务器。我们也可以通过正则表达式,从用户输入的字符串中过滤并获取我们想要的特定部分。总而言之,正则表达式是非常强大的。

 

 

方法一、谓词(NSPredicate)创建正则表达式

使用它来判断用户输入的字符串是否为合法的:

// 编写正则表达式:只能是数字或英文,或两者都存在
NSString *regex = @"^[a-z0-9A-Z]*$";
// 创建谓词对象并设定条件的表达式
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
// 判断的字符串
NSString *str = @"Hello100";
// 对字符串进行判断
if ([predicate evaluateWithObject:str]) {
    NSLog(@"Match");
}

字符串Hello100是符合规则的,因此此例子会在日志输出"Match"。假如我们把“Hello100”换成其它字符(例如是“-、=”),以上例子将不会输出任何东西。

 

 

方法二、NSRegularExpression类创建正则表达式

戮克 發表在 痞客邦 留言(0) 人氣()

关于UIView的Layer,IOS提供了三个方法:

1、layoutSubviews

在iOS5.1和之前的版本,此方法的缺省实现不会做任何事情(实现为空),iOS5.1之后(iOS6开始)的版本,此方法的缺省实现是使用你设置在此view上面的constraints(Autolayout)去决定subviews的position和size。 UIView的子类如果需要对其subviews进行更精确的布局,则可以重写此方法。只有在autoresizing和constraint-based behaviors of subviews不能提供我们想要的布局结果的时候,我们才应该重写此方法。可以在此方法中直接设置subviews的frame。 我们不应该直接调用此方法,而应当用下面两个方法。

2、setNeedsLayout

此方法会将view当前的layout设置为无效的,并在下一个upadte cycle里去触发layout更新。

3、layoutIfNeeded

使用此方法强制立即进行layout,从当前view开始,此方法会遍历整个view层次(包括superviews)请求layout。因此,调用此方法会强制整个view层次布局。

基于约束的AutoLayer的方法:

1、setNeedsUpdateConstraints

当一个自定义view的某个属性发生改变,并且可能影响到constraint时,需要调用此方法去标记constraints需要在未来的某个点更新,系统然后调用updateConstraints.

2、needsUpdateConstraints

戮克 發表在 痞客邦 留言(0) 人氣()

前言

最近又要做新功能了,虽然没有什么难点,只是获取后端XML数据显示到TableView,但是不是可以更简单快速的完成呢?原来Cell的动态高度一直都是通过sizeWithFont手动计算,潜意识觉得这应该不是最好的实现方式,但由于当时时间紧不允许尝试新技术,所以问题也就遗留了下来,这次又遇到了,时间充裕就解决下吧。

Autolayout是解决自适应frame问题的解决方案(iOS6.0就已经支持了,我现在才用= =#)。通过给视图元素设置合适的约束条件,内部会根据元素内容和限制条件计算出合适的尺寸显示。我们就不用自己手动写这些代码了。

文章步骤看上去有些复杂,真正做起来还是很快的,鼠标拖拽几下就能完成原来的手动计算高度部分代码,减少了很多重复性工作,也让代码看起来更加整洁。

创建Xib文件

首先将Cell做好布局,调整到满意的位置和宽度,然后开始做Autolayout设定。

Autolayout操作方式有两种,一种是选择目标后,使用右下角的工具栏;另一种是直接使用右键拖拽目标,在弹出的菜单中选择限制项。当选择的目标比较小的时候,可以打开左侧的菜单,在这里做拖拽操作一样是可以的。个人感觉后者更方便一些。

开始之前,先来介绍下使用的基本工具吧。

 

第一个按钮是和对齐有关的,就是控制多个元素(Lable, Button等)的统一约束。例如我们需要让标题和内容按照左,就选择标题和内容元素,选择Leading Edges设置为5即可。

Autolayout_Align

第二个按钮是和元素位置固定有关的限制条件,直接看图吧:

戮克 發表在 痞客邦 留言(0) 人氣()

一、关于自动布局(Autolayout)
在Xcode中,自动布局看似是一个很复杂的系统,在真正使用它之前,我也是这么认为的,不过事实并非如此。

我们知道,一款iOS应用,其主要UI组件是由一个个相对独立的可视单元构成,这些可视单元有的主要负责向用户输出有用的信息,有些则负责信息的输入(交互),交互的过程中往往还伴随有动画的效果,已达到整个信息传递的连贯性以及用户体验的细腻感。可视单元,在实际开发中主要是view、button等,那么这些可视单元的关系由两个基本的关系构成:兄弟关系和父子关系,整个视图单元就是一个树形结构:
xcode6中自动布局autolayout和sizeclass的使用 - 第2张 | IT江湖

对于任何一个UI组件,确定了它的(相对于父view)位置、大小也就确定了它在整个UI视图中的展示效果。

Autolayout(以及iOS8中新增的sizeclass)是为了解决这些UI可视单元或者元素是怎样布局、排列的问题。在过去只有iPhone4的时候,我们可以在代码里将没一个可视单元的位置写死,这样是没问题的,但随着iPhone5、6的发布,屏幕尺寸有了越来越多中可能,未来不排除更多尺寸的iPhone发布出来,这就要求我们的APP的UI元素具有在屏幕尺寸不同的设备上具有一定动态的可调性,已实现较好的UI展示效果。从目前苹果提供的技术来看,有下、中、上三种实现方法:

下策是,代码中判断当前设备的尺寸,对UI元素进行手工的调整,其缺点是显而易见的:代码复杂、容易出错、且维护难度大、灵活性极差;

戮克 發表在 痞客邦 留言(0) 人氣()

Autolayout 博大精深,以前转过一篇,可是用的时候还是不会用。没办法只能看苹果官方的文档,发现除了讲基本的使用(XCode5中的一些操作已不太一样)外,还有这么个例子,主要解决了屏幕大小不同适配的问题,真是不错。摘录下来,希望对大家有用。

如果某个地方看不明白可以留言给我,我翻译并给大家讲。

ScrollView这块我暂时没有用,没细看,下面Size适配那个我试了,并且写了Demo,大家感兴趣下文下载研究。

Auto Layout makes it easy to solve many complex layout problems automatically, without the need for manual view manipulation. By creating the right combination of constraints, you can create layouts that are traditionally difficult to manage in code, such as equally spaced views that adjust to changes in orientation or size, elements inside scroll views that affect the size of the scrolling content, or elements inside scroll views that don’t scroll with the rest of the contents.

Using Scroll Views with Auto Layout

When you are creating an app using Auto Layout, scroll views can present a unique challenge. The size of the scrolling content must be set correctly so that the user can scroll through all of the available content, for example, and if you need to lock a contextual view in place on top of a scroll view, such as the scale and legend for a map, it’s difficult to ensure that the element doesn’t scroll with the rest of the content.

Controlling Scroll View Content Size

The size of the content inside of a scroll view is determined by the constraints of its descendants.

To set the size of a scroll view

  • Create the scroll view.
  • Place the UI element inside it.
  • Create constraints that fully define the width and height of the scroll view content.

You must make sure you create constraints for all the subviews inside a scroll view. For example, when defining the constraints for a view that doesn’t have an intrinsic content size, you’ll need more than just a leading edge constraint—you must also create trailing edge, width, and height constraints. There cannot be any missing constraints, starting from one edge of the scroll view to the other.

Creating Anchored Views Inside a Scroll View

You may find you want to create an area inside a scroll view that doesn’t move when a user scrolls the contents of the scroll view. You accomplish this by using a separate container view.

To lock a view inside a scroll view * Create a container view to hold the scroll view. * Create the scroll view and place it in the container view with all edges equal to zero points. * Create and place a subview inside of the scroll view. * Create constraints from the subview to the container view.

戮克 發表在 痞客邦 留言(0) 人氣()

UIWebView has very few instance methods. One of them is stringByEvaluatingJavaScriptFromString, which very powerful and unfortunately poorly documented. (This is literally the extent of Apple’s explanation: “Returns the result of running a script.”)

Let’s explore this mysterious method with a couple of examples.

A trivial example of how to use stringByEvaluatingJavaScriptFromString is to get the title of the HTML document:


view plaincopy to clipboardprint?
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];  

NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];  

You would typically place this line of code in webViewDidFinishLoad.

This technique is not limited to one-liners, or accessing simple properties. Here’s an example of two lines of JavaScript code executed in order, as you would expect:


view plaincopy to clipboardprint?

戮克 發表在 痞客邦 留言(0) 人氣()

http://www.iphoneexamples.com/

iPhone SDK Examples
"Just show me how to do it!" 
This site is meant for the relatively new iPhone Developer who just wants simple examples to common tasks. 
It is meant as a starting point. Please take the time to read the documentation and understand the SDK in depth.

Logging
In Xcode, click Run > Console to see NSLog statements. 
NSLog(@"log: %@ ", myString); NSLog(@"log: %f ", myFloat); NSLog(@"log: %i ", myInt); 
Display Images

戮克 發表在 痞客邦 留言(0) 人氣()

[customSlider addTarget:self action:@selector(sliderDown:) forControlEvents:UIControlEventTouchDown]; 
 
[customSlider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventTouchUpInside]; 
 
 
 
- (void)sliderDown:(id)sender 

 
    sliderused = NO; 

戮克 發表在 痞客邦 留言(0) 人氣()

轉載:http://is00hcw.blog.163.com/blog/static/28263272201082475654385/

 

by Wei-Meng Lee

The iPhone SDK comes with various templates to let developers create different types of applications. Two popular application templates are Tab Bar Application and Navigation-based Application. In reality, it is common to find applications that use a tab bar together with a navigation controller.

One such application is the Phone application that comes with the iPhone. The Phone application has five tab items -- Favorites, Recents, Contacts, Keypad, and Voicemail. Tapping on the Favorites item shows you a list of favorite contacts. Of each contact shown, you can tap on the disclosure button displayed on the right to navigate to the view that shows the details of the contact.

In this article, I will take you through the process of building a Tab Bar application, and combines it with a Navigation controller.


Adding a Navigation Controller

Using Xcode, create a new Tab Bar Application (iPhone) project (see Figure 1) and name it TabBarAndNav.

iPhone Programming: Using a Tab Bar App with a Navigation Controller - is00hcw - is00hcw的博客

戮克 發表在 痞客邦 留言(0) 人氣()

1 234