CocoaPodsでライブラリのアップデートをおこなっていたら、ある時から突然、iOS 8で下記の実行時エラーが発生するようになりました。
dyld: Symbol not found: _NSURLSessionTaskPriorityDefault
Referenced from: /Users/user/Library/Developer/CoreSimulator/Devices/6FA85157-45BD-429C-9B17-EC25662F3346/data/Containers/Bundle/Application/38194C23-0361-4C13-8661-7D6443D5A633/MyApp.app/MyApp
Expected in: /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 8.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework/Foundation
in /Users/user/Library/Developer/CoreSimulator/Devices/6FA85157-45BD-429C-9B17-EC25662F3346/data/Containers/Bundle/Application/38194C23-0361-4C13-8661-7D6443D5A633/MyApp.app/MyApp
あるライブラリをアップデートしたら、CFNetwork.framework
が不要になったらしく、その時から CFNetwork.framework
がlinkされなくなったため発生しました。
環境
- Xcode Version 7.3.1 (7D1014)
- Deployment Target 8.3
調査
いろいろ参考サイトを探していたのですが、 CFNetwork.framework
を手動で追加しろということらしいです。
しかし、CocoaPodsを使用している場合、本当に手動でXcodeの Linked Frameworks and Libraries
に追加しても解消されません。
Foundation.framework
より前に CFNetwork.framework
をlinkしないといけないらしいですが、順番を入れ替えても、エラーが解消できません。
解決方法
答えは、CocoaPodsが生成しているxcconfigにありました。
OTHER_LDFLAGS
に Foundation.framework がすでに入っているため、これより前に、 CFNetwork.framework
を挿入する必要があります。
// ↓ | の位置より前に追加
OTHER_LDFLAGS = $(inherited) -ObjC... | -framework "Foundation" ...
pod install
時に、 xcconfigファイルを書き換えたいため、 post_install
フックに処理を追加します。
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
case target.name
when /App$/, /App-Release$/
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
build_settings = Hash[*File.read(xcconfig_path).lines.map {|l| l.split(/\s*=\s*/, 2) }.flatten]
other_ldflags = build_settings['OTHER_LDFLAGS']
# see: Quickfix on iOS 8 crashes, https://openradar.appspot.com/23956486
if idx = other_ldflags =~ /-framework \"Foundation\"/
other_ldflags.insert(idx, '-framework "CFNetwork" ')
build_settings['OTHER_LDFLAGS'] = other_ldflags
end
File.open(xcconfig_path, "w") {|f| f.puts build_settings.map {|k, v| "#{k} = #{v}" } }
end
end
end
end
複数ターゲットがある場合(Podsでインストールするライブラリ用のターゲットもあるため)、必要なターゲットのみ変更するようにした方が良いでしょう。