How to take screenshots for UITest in Xcodee

Issue #539 XCUIScreenshot extension XCTestCase { func takeScreenshot(name: String) { let screenshot = XCUIScreen.main.screenshot() let attach = XCTAttachment(screenshot: screenshot) attach.lifetime = .keepAlways add(attach) } } Gather screenshot for localization Creating Great Localized Experiences with Xcode 11 xcresult from Xcode 11 https://www.chargepoint.com/engineering/xcparse/ xcparse Command line tool & Swift framework for parsing Xcode 11+ xcresult xcresulttool Testing in Xcode Test plan WWDC19: Getting Started with Test Plan for XCTest

December 12, 2019 · 1 min · 67 words · Khoa

How to fix UIToolbar Auto Layout issues

Issue #538 Hierarchy UIToolbar -> _UIToolbarContentView -> _UIButtonBarStackVie UIToolbarContentView _UIToolbarContentView's width should equal 0 _UIToolbarContentView's height should equal 0 Workaround that fixes 1 warning toolbar.setItems(items, animated: false) toolbar.updateConstraintsIfNeeded() Set frame explicitly Use a non .zero frame that is close to the view bounds width let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 375, height: 30)) DispatchQueue.main.async { self.toolbar.updateConstraintsIfNeeded() }

December 11, 2019 · 1 min · 60 words · Khoa

How to use passed launch arguments in UITests

Issue #537 Specify launch arguments In xcodebuild, specify launch arguments. You can specify this under Launch Arguments in Run action of the app scheme or UITest scheme -AppleLanguages (jp) -AppleLocale (jp_JP) (lldb) po ProcessInfo().arguments ▿ 11 elements - 0 : "/Users/khoa/Library/Developer/CoreSimulator/Devices/561F2B45-26B2-4897-98C4-8A917AEB48D2/data/Containers/Bundle/Application/436E0A43-8323-4F53-BBE0-6F75F674916F/TestAppUITests-Runner.app/TestAppUITests-Runner" - 1 : "-AppleLanguages" - 2 : "(ja)" - 3 : "-AppleTextDirection" - 4 : "NO" - 5 : "-AppleLocale" - 6 : "ja_JP" - 7 : "-NSTreatUnknownArgumentsAsOpen" - 8 : "NO" - 9 : "-ApplePersistenceIgnoreState" - 10 : "YES" In UITests, pass launch arguments from UITest scheme to UITest application...

December 10, 2019 · 1 min · 100 words · Khoa

How to add padding to left right view in UITextField

Issue #536 extension UITextField { func setLeftView(_ view: UIView, padding: CGFloat) { view.translatesAutoresizingMaskIntoConstraints = true let outerView = UIView() outerView.translatesAutoresizingMaskIntoConstraints = false outerView.addSubview(view) outerView.frame = CGRect( origin: .zero, size: CGSize( width: view.frame.size.width + padding, height: view.frame.size.height + padding ) ) view.center = CGPoint( x: outerView.bounds.size.width / 2, y: outerView.bounds.size.height / 2 ) leftView = outerView } }

December 10, 2019 · 1 min · 57 words · Khoa

How to set date color in UIDatePicker in iOS 13

Issue #535 datePicker.setValue(UIColor.green, forKey: "textColor") datePicker.setValue(false, forKey: "highlightsToday") In iOS 14 if #available(iOS 14.0, *) { datePicker.preferredDatePickerStyle = .wheels datePicker.tintColor = UIColor.green } Inspect attributes https://developer.apple.com/documentation/objectivec/nsobject/1415656-attributekeys

December 10, 2019 · 1 min · 26 words · Khoa

How to fix cropped image in UIImageView

Issue #530 Although UIImageView frame is correct, image is still cropped. Watch out for any layer.mask within view

December 6, 2019 · 1 min · 18 words · Khoa

How to use decoration view in UICollectionView

Issue #529 indexPath https://developer.apple.com/documentation/uikit/uicollectionviewlayoutattributes/1617786-layoutattributesfordecorationvie It is up to you to decide how to use the indexPath parameter to identify a given decoration view. Typically, you use the decorationViewKind parameter to identify the type of the decoration view and the indexPath information to distinguish between different instances of that view. Posts Add separator https://gist.github.com/tomaskraina/1eb291e4717f14ad6e0f8e60ffe9b7d3

December 5, 2019 · 1 min · 53 words · Khoa

How to test UserDefaults in iOS

Issue #518 let userDefaults = UserDefaults(suiteName: suiteName) userDefaults.removePersistentDomain(forName: suiteName) https://developer.apple.com/documentation/foundation/userdefaults/1417339-removepersistentdomain Calling this method is equivalent to initializing a user defaults object with init(suiteName:) passing domainName, and calling the removeObject(forKey:) method on each of its keys. Read more https://www.swiftbysundell.com/articles/the-power-of-userdefaults-in-swift/ http://dscoder.com/defaults.html https://medium.com/swift-india/userdefaults-under-the-hood-457461c8d262

November 25, 2019 · 1 min · 40 words · Khoa

How to make Swift Package Manager package for multiple platforms

Issue #504 https://twitter.com/NeoNacho/status/1181245484867801088?s=20 There’s no way to have platform specific sources or targets today, so you’ll have to take a different approach. I would recommend wrapping all OS specific files in #if os and just having one target. For tests, you could do something similar, one test target, but conditional tests Every files are in Sources folder, so we can use platform and version checks. For example Omnia is a Swift Package Manager that supports iOS, tvOS, watchOS, macOS and Catalyst....

November 13, 2019 · 1 min · 119 words · Khoa

How to refresh receipt and restore in app purchase in iOS

Issue #496 Read this Restoring Purchased Products to understand the purposes between the 2. From iOS 7, every app downloaded from the store has a receipt (for downloading/buying the app) at appStoreReceiptURL. When users purchases something via In App Purchase, the content at appStoreReceiptURL is updated with purchases information. Most of the cases, you just need to refresh the receipt (at appStoreReceiptURL) so that you know which transactions users have made....

November 10, 2019 · 2 min · 324 words · Khoa

How to add monkey test to iOS apps

Issue #484 Use SwiftMonkey which adds random UITests gestures Add to UITests target target 'MyAppUITests' do pod 'R.swift', '~> 5.0' pod 'SwiftMonkey', '~> 2.1.0' end Troubleshooting Failed to determine hittability of Button Failed to determine hittability of Button: Unable to fetch parameterized attribute XC_kAXXCParameterizedAttributeConvertHostedViewPositionFromContext, remote interface does not have this capability. This happens when using SwiftMonkey and somewhere in our code uses isHittable, so best to avoid that by having isolated monkey test only...

November 1, 2019 · 1 min · 155 words · Khoa

How to use CommonCrypto in iOS

Issue #480 Use modulemap modulemap approach I use modulemap in my wrapper around CommonCrypto https://github.com/onmyway133/arcane, https://github.com/onmyway133/Reindeer For those getting header not found, please take a look https://github.com/onmyway133/Arcane/issues/4 or run xcode-select --install Make a folder CCommonCrypto containing module.modulemap module CCommonCrypto { header "/usr/include/CommonCrypto/CommonCrypto.h" export * } Go to Built Settings -> Import Paths ${SRCROOT}/Sources/CCommonCrypto Cocoapods with modulemap approach Here is the podspec https://github.com/onmyway133/Arcane/blob/master/Arcane.podspec s.source_files = 'Sources/**/*.swift' s.xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCrypto' } s....

October 29, 2019 · 2 min · 217 words · Khoa

How to configure test target in Xcode

Issue #478 This applies to Main targets App Framework Test targets Unit tests UI tests Examples Dependencies used Main target: Sugar Test target: Nimble, Quick Examples Cocoapods Carthage Notes Make sure test target can link to all the frameworks it needs. This includes frameworks that Test targets use, and possibly frameworks that Main target uses ! Remember to “Clean Build Folder” and “Clear Derived Data” so that you’re sure it works....

October 29, 2019 · 2 min · 394 words · Khoa

How to use external display in iOS

Issue #473 Before iOS 13 Use UIScreen.didConnectNotification NotificationCenter.default.addObserver(forName: UIScreen.didConnectNotification, object: nil, queue: nil) { (notification) in // Get the new screen information. let newScreen = notification.object as! UIScreen let screenDimensions = newScreen.bounds // Configure a window for the screen. let newWindow = UIWindow(frame: screenDimensions) newWindow.screen = newScreen // Install a custom root view controller in the window. self.configureAuxilliaryInterface(with: newWindow) // You must show the window explicitly. newWindow.isHidden = false // Save a reference to the window in a local array....

October 22, 2019 · 2 min · 291 words · Khoa

How to show error message like Snack Bar in iOS

Issue #472 Build error view Use convenient code from Omnia To make view height dynamic, pin UILabel to edges and center import UIKit final class ErrorMessageView: UIView { let box: UIView = { let view = UIView() view.backgroundColor = R.color.primary view.layer.cornerRadius = 6 return view }() let label: UILabel = { let label = UILabel() label.styleAsText() label.textColor = R.color.darkText label.numberOfLines = 0 return label }() override init(frame: CGRect) { super.init(frame: frame) setup() } required init?...

October 21, 2019 · 3 min · 459 words · Khoa

How to hide tab bar when push in iOS

Issue #471 let navigationController = UINavigationController(rootViewController: viewControllerA) navigationController.pushViewController(viewControllerB, animated: true) In view controller B, need to set hidesBottomBarWhenPushed in init final class ViewControllerB: UIViewController { let mainView = EditPaymentMethodView() var scenario: PaymentMethodScenario! init() { super.init(nibName: nil, bundle: nil) hidesBottomBarWhenPushed = true } required init?(coder: NSCoder) { fatalError() } }

October 18, 2019 · 1 min · 49 words · Khoa

How to add trailing image to UILabel in iOS

Issue #470 Use NSTextAttachment inside NSAttributedString extension UILabel { func addTrailing(image: UIImage) { let attachment = NSTextAttachment() attachment.image = image let attachmentString = NSAttributedString(attachment: attachment) let string = NSMutableAttributedString(string: self.text!, attributes: [:]) string.append(attachmentString) self.attributedText = string } }

October 17, 2019 · 1 min · 38 words · Khoa

How to handle different states in a screen in iOS

Issue #469 If there are lots of logics and states inside a screen, it is best to introduce parent and child container, and switch child depends on state. Each child acts as a State handler. In less logic case, we can introduce a Scenario class that holds the state. So the ViewController can be very slim. The thing with State is that all possible scenarios are clear and required to be handled...

October 17, 2019 · 1 min · 132 words · Khoa

How to structure classes

Issue #466 iOS View Controller -> View Model | Logic Handler -> Data Handler -> Repo Android Activity -> Fragment -> View Model | Logic Handler -> Data Handler -> Repo

October 16, 2019 · 1 min · 31 words · Khoa

How to zoom to fit many coordinates in Google Maps in iOS

Issue #463 func zoom(location1: CLLocation, location2: CLLocation) { let bounds = GMSCoordinateBounds(coordinate: location1.coordinate, coordinate: location2.coordinate) let update = GMSCameraUpdate.fit(bounds, withPadding: 16) mapView.animate(with: update) }

October 14, 2019 · 1 min · 24 words · Khoa