iOS 7中UITableViewCell的变化

iOS 7的UITableViewCell内部与iOS 6有些不同,cell与contentView之间多了一层UITableViewCellScrollView

估计很多人的代码要作些修改了,下面简单作个比较:

iOS 6中UITableViewCell的View层级

1
2
3
(lldb) po [cell recursiveDescription]
<UITableViewCell: 0xba72e50; frame = (0 0; 320 44); layer = <CALayer: 0xba72fd0>>
| <UITableViewCellContentView: 0xba6f980; frame = (0 0; 320 44); gestureRecognizers = <NSArray: 0xba70960>; layer = <CALayer: 0xba6fb70>>

iOS 7中UITableViewCell的View层级

1
2
3
4
(lldb) po [cell recursiveDescription]
<UITableViewCell: 0xd984fc0; frame = (0 0; 320 44); layer = <CALayer: 0xd982750>>
| <UITableViewCellScrollView: 0xcca9790; frame = (0 0; 320 44); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0xcc54ec0>; layer = <CALayer: 0xccac430>; contentOffset: {0, 0}>
| | <UITableViewCellContentView: 0xdb582a0; frame = (0 0; 320 44); gestureRecognizers = <NSArray: 0xdb49c40>; layer = <CALayer: 0xdb54050>>

大家遇到了哪些问题?如何解决的?欢迎留言讨论。

附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog


Xcode磁盘空间大清理

我的设备是Macbook Air 13’ Mid 2011,128G SSD。最近开始有些存储压力了,用Clean My Mac清理一部分旧文件后,决定对Xcode动手。

移除对旧设备的支持

影响:可重新生成;再连接旧设备调试时,会重新自动生成。我移除了4.3.2, 5.0, 5.1等版本的设备支持。

路径:~/Library/Developer/Xcode/iOS DeviceSupport

释放空间:3GB

移除旧版本的模拟器支持

影响:不可恢复;如果需要旧版本的模拟器,就需要重新下载了。我移除了4.3.2, 5.0, 5.1等旧版本的模拟器。

路径:~/Library/Application Support/iPhone Simulator

释放空间:3GB

移除模拟器的临时文件

影响:可重新生成;如果需要保留较新版本的模拟器,但tmp文件夹很大。放心删吧,tmp文件夹里的内容是不重要的。在iOS Device中,存储空间不足时,tmp文件夹是可能被清空的。

路径:~/Library/Application Support/iPhone Simulator/6.1/tmp (以iOS Simulator 6.1为例)

释放空间:2GB

移除模拟器中安装的Apps

影响:不可恢复;对应的模拟器中安装的Apps被清空了,如果不需要就删了吧。

路径:~/Library/Application Support/iPhone Simulator/6.1/Applications (以iOS Simulator 6.1为例)

释放空间:1GB

移除Archives

影响:不可恢复;Adhoc或者App Store版本会被删除。建议备份dSYM文件夹

路径:~/Library/Developer/Xcode/Archives

释放空间:6GB

移除DerivedData

影响:可重新生成;会删除build生成的项目索引、build输出以及日志。重新打开项目时会重新生成,大的项目会耗费一些时间。

路径:~/Library/Developer/Xcode/DerivedData

释放空间:12GB

移除旧的Docsets

影响:不可恢复;将删除旧的Docsets文档

路径:~/Library/Developer/Shared/Documentation/DocSets

释放空间:2GB

友情提示

我一共释放出了30GB左右的磁盘空间,这对128 GB的SSD来说可是不小的数字。如果你的磁盘空间不紧张,或者使用HDD,我建议不要进行这些操作。使用SSD的朋友酌情清理吧。

附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog



CocoaPods进阶:本地包管理

粉笔网的iOS工程师唐巧曾经写过一篇blog《使用CocoaPods来做iOS程序的包依赖管理》介绍了基本的CocoaPods使用方法。本文将另外谈一谈如何使用CocoaPods进行本地的包管理。建议没有接触过CococaPods的朋友先阅读一下唐巧的blog。

为什么要进行本地的包管理

  • 有的时候CocoaPods的spec版本过旧,pull request没有及时merge,导致我们无法利用CocoaPods使用较新的代码版本;
  • 有的时候我们的一些代码不是开源的,或者暂时不想放到Github上。我们更想使用CocoaPods引用本地的代码;

使用CocoaPods里没有的第三方库新版本

这里我们以PlayHavenSDK为例介绍一下。我们在CocoaPods / Spec这个repository里面可以看到,PlayHavenSDK的版本是1.11.0。而playhaven / sdk-ios里面的tag,已经有了1.12.1这个版本。CocoaPods的Spec repository已经落后了两个版本。这时我们想使用最新版,需要的就是一个更新的spec。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Pod::Spec.new do |s|
s.name = 'PlayHavenSDK'
s.version = '1.12.1'
s.license = 'MIT'
s.summary = 'PlayHaven is a real-time mobile game marketing platform to help you take control of the business of your games.'
s.homepage = 'http://playhaven.com'
s.author = { 'Sam Stewart' => 'sam@playhaven.com' }
s.source = { :git => 'https://github.com/playhaven/sdk-ios.git', :tag => '1.12.1' }
s.description = "PlayHaven is a real-time mobile game marketing platform to help you take control of the business of your games. Acquire, retain, re-engage, and monetize your players with the help of PlayHaven's powerful marketing platform. Integrate once and embrace the flexibility of the web as you build, schedule, deploy, and analyze your in-game promotions and monetization in real-time through PlayHaven's easy-to-use, web-based dashboard. An API token and secret is required to use this SDK. These tokens uniquely identify your app to PlayHaven and prevent others from making requests to the API on your behalf. To get a token and secret, please visit the PlayHaven developer dashboard at https://dashboard.playhaven.com."
s.platform = :ios
# PlayHaven includes prefixed versions of SBJson and OpenUDID
s.source_files = 'Cache', 'src', 'WaterWorks', 'JSON', 'OpenUDID'
s.frameworks = 'SystemConfiguration', 'CFNetwork', 'StoreKit', 'CoreGraphics', 'QuartzCore'
s.weak_frameworks = 'AdSupport'
end

这里我们注意到s.source这一行配置,指向了playhaven/sdk-ios.git仓库的1.12.1这个tag,表示这个spec将使用这个tag的代码。我们将它保存到本地的一个目录中,如~/Desktop/PlayHavenSDK/PlayHavenSDK.podspec

我们回到Xcode project目录中,打开Podfile,添加pod 'PlayHavenSDK', :podspec => '~/Desktop/PlayHavenSDK/PlayHavenSDK.podspec',接着运行pod update即可。

PS: 当然这个podspec也可以不放在本地,比如放在gist上。

使用CocoaPods管理本地代码

这种情况稍微复杂一步,除了指定podspec,还需要准备一个本地要使用的git repository。我们以Chartboost为例来进行说明。

首先我们新建一个名为~/Desktop/ChartboostSDK/的目录,然后执行git init初始化这个git repository。

接着我们去Chartboost官方网站下载最早新的SDK。将它放进这个目录中,然后执行git add . && git commit -m"Add new SDK"

这样我们这个目录已经成为一个git repository,里面是最新的Chartboost SDK。

这时我们仍然需要一个podspec文件,来说明我们从哪个仓库来获取代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Pod::Spec.new do |s|
s.name = 'ChartboostSDK'
s.version = '3.1.1'
s.license = 'Commercial'
s.summary = 'ChartboostSDK for showing ads and more apps pages, and tracking analytics and in-app purchase revenue.'
s.homepage = 'https://chartboost.com/'
s.author = { 'Chartboost' => 'https://chartboost.com/' }
s.source = { :git => '~/Desktop/ChartboostSDK' }
s.platform = :ios
s.source_files = '**/*.h'
s.preserve_paths = '**/*.a'
s.library = 'Chartboost'
s.xcconfig = { 'LIBRARY_SEARCH_PATHS' => '"$(PODS_ROOT)/ChartboostSDK/Chartboost"' }
s.weak_frameworks = 'AdSupport', 'StoreKit'
s.frameworks = 'QuartzCore', 'SystemConfiguration', 'CoreGraphics'
end

我们运行ls -lh | awk '{print $9}',ChartboostSDK目录的结构显示如下:

1
2
3
4
CBAnalytics.h
Chartboost.h
ChartboostSDK.podspec
libChartboost.a

除了两个.h,一个.a,还有一个podspec文件。

接着我们回到Xcode proj所在的文件夹中,编辑Podfile,添加pod 'ChartboostSDK', :local => '~/Desktop/ChartboostSDK'。这里的local表明从本地的git仓库里获取代码。

最后我们运行pod update,大功告成。

CocoaPods小结

上面的两种情况,简单来说:

  • 需要使用最新的开源代码/库,但没最新的spec
  • 需要使用私有代码/库,需要对应的私有的spec

对于第一种情况,建议大家可以给CocoaPods / Specs提交一个pull request。

使用CocoaPods只需要知道两件事情:

  • podspec:一个pod的配置是什么,pod的代码放在哪里
  • Podfile:项目依赖哪个pod,以何种方式依赖,它的podspec放在哪里

这里podspec和git repository都非常灵活,可以放在本地,也可以放到github/gist上。代码仓库甚至可以不使用git而直接使用一个zip压缩包。

使用CocoaPods可以把多们从繁重的配置和代码管理中解脱出来,而且可以少犯错误。比如Deployment Target设置为5.0,但App中需要使用AdSupport.framework,如果忘记设置为optional则所有5.x的设备运行时都会crash。对于这种情况CocoaPods在spec提供了weak_frameworks的配置选项。同时CocoaPods能够保证库的依赖关系,而不会出现几个项目依赖版本不一致的情况。

PS: 最近为了UDID更新的同学们可别犯AdSupport.framework这个错误,后果很严重。

希望这个blog对大家使用CocoaPods有所帮助。

赶个时髦,祝大家一帆风顺

一帆风顺

附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog