We using below command to run unit test and collect coverage:
xcodebuild -workspace Demo.xcworkspace -scheme VideoTests -configuration Debug -derivedDataPath ../build/derivedData -destination 'platform=iOS Simulator,id=E6630007-570B-4DEB-A023-2BCE91116A8D' -resultBundlePath './fastlane/test_output/VideoTests.xcresult' -enableCodeCoverage YES -testPlan 'Video' test-without-building | tee '/Users/rcadmin/Library/Logs/scan/VideoTests.log' | xcbeautify -q --is-ci
and using xcrun llvm-cov show command to generate coverage report:
xcrun llvm-cov show /build/unit-test/coverage/libraries/merged/video.o -instr-profile=/app/ios/build/derivedData/Build//ProfileData/E6630007-570B-4DEB-A023-2BCE91116A8D/video.profdata -show-branches count -show-expansions -show-line-counts -use-color -format=html -output-dir coverage
and the html report does not include branch coverage:
how to generate the branch coverage?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
When using UITabBarController and set a custom tabbar:
TabBarViewController.swift
import UIKit
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
class HomeViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
navigationItem.title = "Home"
tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0)
}
}
class PhoneViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .purple
navigationItem.title = "Phone"
tabBarItem = UITabBarItem(title: "Phone", image: UIImage(systemName: "phone"), tag: 1)
}
}
class PhotoViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
navigationItem.title = "Photo"
tabBarItem = UITabBarItem(title: "Photo", image: UIImage(systemName: "photo"), tag: 1)
}
}
class SettingViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
navigationItem.title = "Setting"
tabBarItem = UITabBarItem(title: "Setting", image: UIImage(systemName: "gear"), tag: 1)
}
}
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let homeVC = HomeViewController()
let homeNav = NavigationController(rootViewController: homeVC)
let phoneVC = PhoneViewController()
let phoneNav = NavigationController(rootViewController: phoneVC)
let photoVC = PhotoViewController()
let photoNav = NavigationController(rootViewController: photoVC)
let settingVC = SettingViewController()
let settingNav = NavigationController(rootViewController: settingVC)
viewControllers = [homeNav]
let dataSource = [
CustomTabBar.TabBarModel(title: "Home", icon: UIImage(systemName: "house")),
CustomTabBar.TabBarModel(title: "Phone", icon: UIImage(systemName: "phone")),
CustomTabBar.TabBarModel(title: "Photo", icon: UIImage(systemName: "photo")),
CustomTabBar.TabBarModel(title: "Setting", icon: UIImage(systemName: "gear"))
]
let customTabBar = CustomTabBar(with: dataSource)
setValue(customTabBar, forKey: "tabBar")
}
}
CustomTabBar.swift:
import UIKit
class CustomTabBar: UITabBar {
class TabBarModel {
let title: String
let icon: UIImage?
init(title: String, icon: UIImage?) {
self.title = title
self.icon = icon
}
}
class TabBarItemView: UIView {
lazy var titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = .systemFont(ofSize: 14)
titleLabel.textColor = .black
titleLabel.textAlignment = .center
return titleLabel
}()
lazy var iconView: UIImageView = {
let iconView = UIImageView()
iconView.translatesAutoresizingMaskIntoConstraints = false
iconView.contentMode = .center
return iconView
}()
private var model: TabBarModel
init(model: TabBarModel) {
self.model = model
super.init(frame: .zero)
setupSubViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupSubViews() {
addSubview(iconView)
iconView.topAnchor.constraint(equalTo: topAnchor).isActive = true
iconView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
iconView.widthAnchor.constraint(equalToConstant: 34).isActive = true
iconView.heightAnchor.constraint(equalToConstant: 34).isActive = true
iconView.image = model.icon
addSubview(titleLabel)
titleLabel.topAnchor.constraint(equalTo: iconView.bottomAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
titleLabel.heightAnchor.constraint(equalToConstant: 16).isActive = true
titleLabel.text = model.title
}
}
private var dataSource: [TabBarModel]
init(with dataSource: [TabBarModel]) {
self.dataSource = dataSource
super.init(frame: .zero)
setupTabBars()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
var sizeThatFits = super.sizeThatFits(size)
let safeAreaBottomHeight: CGFloat = safeAreaInsets.bottom
sizeThatFits.height = 52 + safeAreaBottomHeight
return sizeThatFits
}
private func setupTabBars() {
backgroundColor = .orange
let multiplier = 1.0 / Double(dataSource.count)
var lastItemView: TabBarItemView?
for model in dataSource {
let tabBarItemView = TabBarItemView(model: model)
addSubview(tabBarItemView)
tabBarItemView.translatesAutoresizingMaskIntoConstraints = false
tabBarItemView.topAnchor.constraint(equalTo: topAnchor).isActive = true
tabBarItemView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
if let lastItemView = lastItemView {
tabBarItemView.leadingAnchor.constraint(equalTo: lastItemView.trailingAnchor).isActive = true
} else {
tabBarItemView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
tabBarItemView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: multiplier).isActive = true
lastItemView = tabBarItemView
}
}
}
UIKit show both custom tabbar and system tabbar:
the Xcode version is: Version 26.0 beta 2 (17A5241o)
and the iOS version is: iOS 26 (23A5276f)
In our app, there is a UIWindow makeKeyAndVisible crash, and for now, it appears once, crash stack:
the crash detail:
crash.txt
in the RCWindowSceneManager class's makeWindowKeyAndVisible method, we check and set a window's windowScene and makeKeyAndVisible:
public func makeWindowKeyAndVisible(_ window: UIWindow?) {
guard let window else {
return
}
if let currentWindowScene {
if window.windowScene == nil || window.windowScene != currentWindowScene {
window.windowScene = currentWindowScene
}
window.makeKeyAndVisible()
}
}
and I set a break point at a normal no crash flow, the stack is:
why it crash? and how we avoid this, thank you.