9 Notes Desember 2020
1. Add Filter Parameters For Url String
var url = URLComponents(string: "http://myapi.com/api/customer")!
print(url) // http://myapi.com/api/customer
url.queryItems = [
URLQueryItem(name: "filter", value: "{\"where\":{\"name\":\"myName\"}}")
]
print(url) // http://myapi.com/api/customer?filter=%7B%22where%22:%7B%22name%22:%22myName%22%7D%7D
2. Navigation back to root (and Chnage root)
- use normal change
self.view.window?.rootViewController = UINavigationController(rootViewController: ViewController())
protocol IRouter {
var module: UIViewController? { get }
}
extension UIViewController {
func navigate(module: IRouter, completion: ((_ module: UIViewController) -> Void)? = nil) {
guard let _module = module.module else { fatalError() }
if _module is UITabBarController {
UIApplication.shared.delegate?.window??.setRootViewController(_module, options: .init(direction: .fade, style: .easeInOut))
} else {
UIApplication.shared.delegate?.window??.setRootViewController(
UINavigationController(rootViewController: _module),
options: .init(
direction: .fade,
style: .easeInOut
)
)
}
completion?(_module)
}
}
public extension UIWindow {
/// Transition Options
struct TransitionOptions {
/// Curve of animation
///
/// - linear: linear
/// - easeIn: ease in
/// - easeOut: ease out
/// - easeInOut: ease in - ease out
public enum Curve {
case linear
case easeIn
case easeOut
case easeInOut
/// Return the media timing function associated with curve
internal var function: CAMediaTimingFunction {
let key: String!
switch self {
case .linear: key = CAMediaTimingFunctionName.linear.rawValue
case .easeIn: key = CAMediaTimingFunctionName.easeIn.rawValue
case .easeOut: key = CAMediaTimingFunctionName.easeOut.rawValue
case .easeInOut: key = CAMediaTimingFunctionName.easeInEaseOut.rawValue
}
return CAMediaTimingFunction(name: CAMediaTimingFunctionName(rawValue: key!))
}
}
/// Direction of the animation
///
/// - fade: fade to new controller
/// - toTop: slide from bottom to top
/// - toBottom: slide from top to bottom
/// - toLeft: pop to left
/// - toRight: push to right
public enum Direction {
case fade
case toTop
case toBottom
case toLeft
case toRight
/// Return the associated transition
///
/// - Returns: transition
internal func transition() -> CATransition {
let transition = CATransition()
transition.type = CATransitionType.push
switch self {
case .fade:
transition.type = CATransitionType.fade
transition.subtype = nil
case .toLeft:
transition.subtype = CATransitionSubtype.fromLeft
case .toRight:
transition.subtype = CATransitionSubtype.fromRight
case .toTop:
transition.subtype = CATransitionSubtype.fromTop
case .toBottom:
transition.subtype = CATransitionSubtype.fromBottom
}
return transition
}
}
/// Background of the transition
///
/// - solidColor: solid color
/// - customView: custom view
public enum Background {
case solidColor(_: UIColor)
case customView(_: UIView)
}
/// Duration of the animation (default is 0.20s)
public var duration: TimeInterval = 0.20
/// Direction of the transition (default is `toRight`)
public var direction: TransitionOptions.Direction = .toRight
/// Style of the transition (default is `linear`)
public var style: TransitionOptions.Curve = .linear
/// Background of the transition (default is `nil`)
public var background: TransitionOptions.Background?
/// Initialize a new options object with given direction and curve
///
/// - Parameters:
/// - direction: direction
/// - style: style
public init(direction: TransitionOptions.Direction = .toRight, style: TransitionOptions.Curve = .linear) {
self.direction = direction
self.style = style
}
public init() {}
/// Return the animation to perform for given options object
internal var animation: CATransition {
let transition = self.direction.transition()
transition.duration = self.duration
transition.timingFunction = self.style.function
return transition
}
}
/// Change the root view controller of the window
///
/// - Parameters:
/// - controller: controller to set
/// - options: options of the transition
func setRootViewController(_ controller: UIViewController, options: TransitionOptions = TransitionOptions()) {
var transitionWnd: UIWindow?
if let background = options.background {
transitionWnd = UIWindow(frame: UIScreen.main.bounds)
switch background {
case .customView(let view):
transitionWnd?.rootViewController = UIViewController.newController(withView: view, frame: transitionWnd!.bounds)
case .solidColor(let color):
transitionWnd?.backgroundColor = color
}
transitionWnd?.makeKeyAndVisible()
}
// Make animation
self.layer.add(options.animation, forKey: kCATransition)
self.rootViewController = controller
self.makeKeyAndVisible()
if let wnd = transitionWnd {
DispatchQueue.main.asyncAfter(deadline: .now() + 1 + options.duration) {
wnd.removeFromSuperview()
}
}
}
}
3. Error Jenkins ITMS-90206
Xcode 8 and lastest
Looks like this has been renamed to Always Embed Swift Standard Libraries in Xcode So, for the app:
Always Embed Swift Standard Libraries: YES
and for the extension:
Always Embed Swift Standard Libraries: NO
source: https://stackoverflow.com/questions/25777958/validation-error-invalid-bundle-the-bundle-at-contains-disallowed-file-fr?lq=1
4. Reject Apple ITMS-90433
Set in Project and Target build option
Always Embed Swift Standard Libraries: YES
Source: https://medium.com/@tomlarge/apple-itms-90424-invalid-swift-support-ios-d8fd0d446d6c
5. Crash while running scroll to bottom
In my case, I fixing with remove (- 1)
func scrollToBottom() {
DispatchQueue.main.async {
if self.showCount > 1 {
let row = self.showCount - 1
let indexPath = IndexPath(row: row, section: 1)
self.commentListTableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
}
}
}
to like this
func scrollToBottom() {
DispatchQueue.main.async {
if self.showCount > 1 {
let row = self.showCount
let indexPath = IndexPath(row: row, section: 1)
self.commentListTableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
}
}
}
6. Firebase Crashlytic cannot connect with a project
- The problem always show this prosses in firebase crashlytic, while running app.
To test this you can force a crash..
- after set fatalError() where you want run your app and click on that button.(You app will crash here so it will be close)
- Now open app again(Do not run app. Just open it by taping on app icon)
Note: for testing crash don't running app use xcode, must running just in simulator or running on IPhone
source: https://stackoverflow.com/a/64366045/8366535
7. Error FirebaseCrashlytic
I try to migrate fabric to Crashlytic and have some bugs, by following instruction firebase but didn't work so I get an answer from StackOverflow
this my solution, follow a step in firebase to fixing if not working you can use this
- Set Crashlytic
// after set that you must running interminal $ /Users/uerry/Backup/MyApp/MyApp_ios/myappmeios/Pods/FirebaseCrashlytics/upload-symbols -gsp /Users/uerry/Backup/MyApp/MyApp_ios/myappmeios/MyApp/Firebase/folder/GoogleService-Info.plist -p ios /Users/uerry/Library/Developer/Xcode/DerivedData/MyApp-bcqxgotqjcqzvpgrbcuhkalogezi/Build/Products/Production-iphoneos/MyApp.app.dSYM // if I split looks like this // part 1 path file pods firebase crashlytic /Users/uerry/Backup/MyApp/MyApp_ios/myappmeios/Pods/FirebaseCrashlytics/upload-symbols -gsp// part 2 path file google service
/Users/uerry/Backup/MyApp/MyApp_ios/myappmeios/MyApp/Firebase/folder/GoogleService-Info.plist -p ios// part 3 path file dSYM
/Users/uerry/Library/Developer/Xcode/DerivedData/MyApp-bcqxgotqjcqzvpgrbcuhkalogezi/Build/Products/Production-iphoneos/MyApp.app.dSYM
this a best answer I found in stackoverflow
source: https://stackoverflow.com/a/62063145/8366535
8. Upload dSYM files automatically
I have a bug again in firebase, dSYMs not auto upload to firebase still use terminal
so I add new run script
/path/to/pods/directory/FirebaseCrashlytics/upload-symbols -gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs
In my new script look like this, add "PATH_ENV" because I use multiple environments for firebase
$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" -gsp
\"${SRCROOT}/myapp/Firebase/${PATH_ENV}/${FIREBASE}.plist\" -p ios
\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}\
source: https://medium.com/macoclock/get-started-with-firebase-crashlytics-2789b6ee2507
9. Round if after a comma is just "0"
if you want after the comma there is only 0 for the round, look at this example below, this was fixing my bug 😏 :
extension Double {
func isInteger() -> Any {
let check = floor(self) == self
if check {
return Int(self)
} else {
return self
}
}
}
let toInt: Double = 10.0
let stillDouble: Double = 9.12
print(toInt.isInteger) // 10
print(stillDouble.isInteger) // 9.12
my answer in stackOverflow : https://stackoverflow.com/a/65402900/8366535
No comments: