394 lines
12 KiB
Swift
394 lines
12 KiB
Swift
//
|
|
// Example
|
|
// man
|
|
//
|
|
// Created by man 11/11/2018.
|
|
// Copyright © 2020 man. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
extension Dictionary {
|
|
///JSON/Form format conversion
|
|
func dictionaryToFormString() -> String? {
|
|
var array = [String]()
|
|
|
|
for (key, value) in self {
|
|
array.append(String(describing: key) + "=" + String(describing: value))
|
|
}
|
|
if array.count > 0 {
|
|
return array.joined(separator: "&")
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
///JSON/Form format conversion
|
|
func formStringToDictionary() -> [String: Any]? {
|
|
var dictionary = [String: Any]()
|
|
let array = self.components(separatedBy: "&")
|
|
|
|
for str in array {
|
|
let arr = str.components(separatedBy: "=")
|
|
if arr.count == 2 {
|
|
dictionary.updateValue(arr[1], forKey: arr[0])
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
if dictionary.count > 0 {
|
|
return dictionary
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
//MARK: - *********************************************************************
|
|
|
|
extension Data {
|
|
func dataToDictionary() -> [String: Any]? {
|
|
do {
|
|
return try JSONSerialization.jsonObject(with: self, options: []) as? [String : Any]
|
|
} catch {
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
extension Dictionary {
|
|
func dictionaryToData() -> Data? {
|
|
do {
|
|
return try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
|
|
} catch {
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
extension Data {
|
|
func dataToString() -> String? {
|
|
return String(bytes: self, encoding: .utf8)
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func stringToData() -> Data? {
|
|
return self.data(using: .utf8)
|
|
}
|
|
}
|
|
|
|
//MARK: - *********************************************************************
|
|
|
|
extension String {
|
|
func stringToDictionary() -> [String: Any]? {
|
|
return self.stringToData()?.dataToDictionary()
|
|
}
|
|
}
|
|
|
|
extension Dictionary {
|
|
func dictionaryToString() -> String? {
|
|
return self.dictionaryToData()?.dataToString()
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func jsonStringToPrettyJsonString() -> String? {
|
|
return self.stringToDictionary()?.dictionaryToString()
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func isValidURL() -> Bool {
|
|
if let url = URL(string: self) {
|
|
return UIApplication.shared.canOpenURL(url)
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func isValidJsonString() -> Bool {
|
|
if let _ = self.stringToDictionary() {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func isValidFormString() -> Bool {
|
|
if let _ = self.formStringToDictionary() {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func jsonStringToFormString() -> String? {
|
|
return self.stringToDictionary()?.dictionaryToFormString()
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func formStringToJsonString() -> String? {
|
|
return self.formStringToDictionary()?.dictionaryToString()
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func formStringToData() -> Data? {
|
|
return self.formStringToDictionary()?.dictionaryToData()
|
|
}
|
|
}
|
|
|
|
extension Data {
|
|
func formDataToDictionary() -> [String: Any]? {
|
|
return self.dataToString()?.formStringToDictionary()
|
|
}
|
|
}
|
|
|
|
extension Data {
|
|
func dataToPrettyPrintString() -> String? {
|
|
//1.pretty json
|
|
if let str = self.dataToDictionary()?.dictionaryToString() {
|
|
return str
|
|
} else {
|
|
//2.protobuf
|
|
// if let message = try? GPBMessage.parse(from: self) {
|
|
// if message.serializedSize() > 0 {
|
|
// return message.description
|
|
// } else {
|
|
// //3.utf-8 string
|
|
// return String(data: self, encoding: .utf8)
|
|
// }
|
|
// } else {
|
|
//3.utf-8 string
|
|
return String(data: self, encoding: .utf8)
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
//MARK: - *********************************************************************
|
|
|
|
//https://gist.github.com/arshad/de147c42d7b3063ef7bc
|
|
///Color
|
|
extension String {
|
|
var hexColor: UIColor {
|
|
let hex = trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
|
|
var int = UInt32()
|
|
Scanner(string: hex).scanHexInt32(&int)
|
|
var a, r, g, b: UInt32
|
|
switch hex.count {
|
|
case 3: // RGB (12-bit)
|
|
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
|
|
case 6: // RGB (24-bit)
|
|
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
|
|
case 8: // ARGB (32-bit)
|
|
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
|
|
default:
|
|
return .clear
|
|
}
|
|
return UIColor(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
|
|
}
|
|
}
|
|
|
|
extension UIView {
|
|
func addCorner(roundingCorners: UIRectCorner, cornerSize: CGSize) {
|
|
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: roundingCorners, cornerRadii: cornerSize)
|
|
let cornerLayer = CAShapeLayer()
|
|
cornerLayer.frame = bounds
|
|
cornerLayer.path = path.cgPath
|
|
self.layer.mask = cornerLayer
|
|
}
|
|
}
|
|
|
|
//extension NSObject {
|
|
// func dispatch_main_async_safe(callback: @escaping ()->Void ) {
|
|
// if Thread.isMainThread {
|
|
// callback()
|
|
// } else {
|
|
// DispatchQueue.main.async( execute: {
|
|
// callback()
|
|
// })
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//https://stackoverflow.com/questions/26244293/scrolltorowatindexpath-with-uitableview-does-not-work
|
|
///tableView
|
|
extension UITableView {
|
|
func tableViewScrollToBottom(animated: Bool) {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) {
|
|
let numberOfSections = self.numberOfSections
|
|
let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
|
|
|
|
if numberOfRows > 0 {
|
|
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
|
|
self.scrollToRow(at: indexPath, at: .bottom, animated: animated)
|
|
}
|
|
}
|
|
}
|
|
|
|
func tableViewScrollToIndex(index: Int, animated: Bool) {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) {
|
|
self.scrollToRow(at: IndexPath(row: index, section: 0), at: .middle, animated: animated)
|
|
}
|
|
}
|
|
|
|
func tableViewScrollToHeader(animated: Bool) {
|
|
self.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: animated)
|
|
}
|
|
|
|
func reloadData(completion: @escaping () -> ()) {
|
|
UIView.animate(withDuration: 0, animations: { self.reloadData()})
|
|
{_ in completion() }
|
|
}
|
|
}
|
|
|
|
///shake
|
|
extension UIWindow {
|
|
|
|
private static var _cocoadebugShakeProperty = [String:Bool]()
|
|
|
|
var cocoadebugShakeProperty:Bool {
|
|
get {
|
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
|
return UIWindow._cocoadebugShakeProperty[tmpAddress] ?? false
|
|
}
|
|
set(newValue) {
|
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
|
UIWindow._cocoadebugShakeProperty[tmpAddress] = newValue
|
|
}
|
|
}
|
|
|
|
|
|
open override var canBecomeFirstResponder: Bool {
|
|
return true
|
|
}
|
|
|
|
open override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
|
|
super.motionBegan(motion, with: event)
|
|
|
|
self.cocoadebugShakeProperty = true
|
|
|
|
if CocoaDebugSettings.shared.responseShake == false {return}
|
|
if motion == .motionShake {
|
|
if CocoaDebugSettings.shared.visible == true { return }
|
|
CocoaDebugSettings.shared.showBubbleAndWindow = !CocoaDebugSettings.shared.showBubbleAndWindow
|
|
}
|
|
}
|
|
|
|
open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
|
|
super.motionEnded(motion, with: event)
|
|
|
|
if self.cocoadebugShakeProperty == true {
|
|
self.cocoadebugShakeProperty = false
|
|
return
|
|
}
|
|
|
|
if CocoaDebugSettings.shared.responseShake == false {return}
|
|
if motion == .motionShake {
|
|
if CocoaDebugSettings.shared.visible == true { return }
|
|
CocoaDebugSettings.shared.showBubbleAndWindow = !CocoaDebugSettings.shared.showBubbleAndWindow
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
///CocoaDebug
|
|
extension CocoaDebug {
|
|
|
|
///init
|
|
static func initializationMethod(serverURL: String? = nil, ignoredURLs: [String]? = nil, onlyURLs: [String]? = nil, ignoredPrefixLogs: [String]? = nil, onlyPrefixLogs: [String]? = nil, additionalViewController: UIViewController? = nil, emailToRecipients: [String]? = nil, emailCcRecipients: [String]? = nil, mainColor: String? = nil, protobufTransferMap: [String: [String]]? = nil)
|
|
{
|
|
if serverURL == nil {
|
|
CocoaDebugSettings.shared.serverURL = ""
|
|
} else {
|
|
CocoaDebugSettings.shared.serverURL = serverURL
|
|
}
|
|
|
|
if ignoredURLs == nil {
|
|
CocoaDebugSettings.shared.ignoredURLs = []
|
|
} else {
|
|
CocoaDebugSettings.shared.ignoredURLs = ignoredURLs
|
|
}
|
|
if onlyURLs == nil {
|
|
CocoaDebugSettings.shared.onlyURLs = []
|
|
} else {
|
|
CocoaDebugSettings.shared.onlyURLs = onlyURLs
|
|
}
|
|
|
|
if ignoredPrefixLogs == nil {
|
|
CocoaDebugSettings.shared.ignoredPrefixLogs = []
|
|
} else {
|
|
CocoaDebugSettings.shared.ignoredPrefixLogs = ignoredPrefixLogs
|
|
}
|
|
if onlyPrefixLogs == nil {
|
|
CocoaDebugSettings.shared.onlyPrefixLogs = []
|
|
} else {
|
|
CocoaDebugSettings.shared.onlyPrefixLogs = onlyPrefixLogs
|
|
}
|
|
|
|
if CocoaDebugSettings.shared.firstIn == nil {//first launch
|
|
CocoaDebugSettings.shared.firstIn = ""
|
|
CocoaDebugSettings.shared.showBubbleAndWindow = true
|
|
} else {//not first launch
|
|
CocoaDebugSettings.shared.showBubbleAndWindow = CocoaDebugSettings.shared.showBubbleAndWindow
|
|
}
|
|
|
|
CocoaDebugSettings.shared.visible = false
|
|
CocoaDebugSettings.shared.logSearchWordNormal = nil
|
|
CocoaDebugSettings.shared.logSearchWordRN = nil
|
|
CocoaDebugSettings.shared.logSearchWordWeb = nil
|
|
CocoaDebugSettings.shared.networkSearchWord = nil
|
|
CocoaDebugSettings.shared.protobufTransferMap = protobufTransferMap
|
|
CocoaDebugSettings.shared.additionalViewController = additionalViewController
|
|
|
|
var _ = _OCLogStoreManager.shared()
|
|
CocoaDebugSettings.shared.responseShake = true
|
|
|
|
//share via email
|
|
CocoaDebugSettings.shared.emailToRecipients = emailToRecipients
|
|
CocoaDebugSettings.shared.emailCcRecipients = emailCcRecipients
|
|
|
|
//color
|
|
CocoaDebugSettings.shared.mainColor = mainColor ?? "#42d459"
|
|
|
|
//slow animations
|
|
CocoaDebugSettings.shared.slowAnimations = false
|
|
|
|
//log
|
|
let enableLogMonitoring = UserDefaults.standard.bool(forKey: "enableLogMonitoring_CocoaDebug")
|
|
if enableLogMonitoring == false {
|
|
_SwiftLogHelper.shared.enable = false
|
|
// _OCLogHelper.shared()?.enable = false
|
|
} else {
|
|
_SwiftLogHelper.shared.enable = true
|
|
// _OCLogHelper.shared()?.enable = true
|
|
}
|
|
|
|
//network
|
|
let disableNetworkMonitoring = UserDefaults.standard.bool(forKey: "disableNetworkMonitoring_CocoaDebug")
|
|
if disableNetworkMonitoring == true {
|
|
_NetworkHelper.shared().disable()
|
|
} else {
|
|
_NetworkHelper.shared().enable()
|
|
}
|
|
}
|
|
|
|
///deinit
|
|
static func deinitializationMethod() {
|
|
WindowHelper.shared.disable()
|
|
_NetworkHelper.shared().disable()
|
|
_SwiftLogHelper.shared.enable = false
|
|
// _OCLogHelper.shared()?.enable = false
|
|
CrashLogger.shared.enable = false
|
|
CocoaDebugSettings.shared.responseShake = false
|
|
}
|
|
}
|
|
|
|
|