详细的英文配置
https://blog.frd.mn/install-nginx-php-fpm-mysql-and-phpmyadmin-on-os-x-mavericks-using-homebrew/
xcode-select --install
| package com.viorsan.test.android.Utils; | |
| /** | |
| * The MIT License (MIT) | |
| * | |
| * Copyright (c) 2015 Circle Internet Financial | |
| * | |
| * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| * of this software and associated documentation files (the "Software"), to deal | |
| * in the Software without restriction, including without limitation the rights | |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
详细的英文配置
https://blog.frd.mn/install-nginx-php-fpm-mysql-and-phpmyadmin-on-os-x-mavericks-using-homebrew/
xcode-select --install
| // Since the WKWebView has no sizeToFit() method, increase the frame height of the webView to | |
| // match the height of the content's scrollHeight | |
| // | |
| // The WKWebView's `navigationDelegate` property needs to be set for the delegate method to be called | |
| func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | |
| if webView.isLoading == false { | |
| webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { [weak self] (result, error) in | |
| if let height = result as? CGFloat { |
| - (CGFloat)collectionViewCellWidth:(UICollectionView *)collectionView itemCountPerRow:(NSInteger)count indexPath:(NSIndexPath *)indexPath { | |
| // 处理collectionView小数点bug,因为collectView是智能布局,当出现小数点时会随机分配宽度 | |
| NSInteger columnCount = count; | |
| NSInteger cellWidth = round(collectionView.width / columnCount); // 四舍五入 | |
| if (indexPath.row % columnCount == 0 ) { | |
| if (cellWidth * columnCount > collectionView.width) { | |
| return cellWidth - (cellWidth * columnCount - collectionView.width); | |
| } else { | |
| return collectionView.width - cellWidth * (columnCount - 1); |
| import Foundation | |
| import UIKit | |
| import WebKit | |
| class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate { | |
| var webView: WKWebView! | |
| var activityIndicator: UIActivityIndicatorView! | |
| @IBOutlet var webViewContainer: UIView! | |
| import UIKit | |
| private let reuseIdentifier = "Cell" | |
| class CollectionViewController: UICollectionViewController { | |
| /* Custom scrollView for paging */ | |
| let pagingScrollView = UIScrollView() | |
| /* Return item size */ |
Code is clean if it can be understood easily – by everyone on the team. Clean code can be read and enhanced by a developer other than its original author. With understandability comes readability, changeability, extensibility and maintainability.
| android.permission.ACCESS_ALL_DOWNLOADS | |
| android.permission.ACCESS_BLUETOOTH_SHARE | |
| android.permission.ACCESS_CACHE_FILESYSTEM | |
| android.permission.ACCESS_CHECKIN_PROPERTIES | |
| android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY | |
| android.permission.ACCESS_DOWNLOAD_MANAGER | |
| android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED | |
| android.permission.ACCESS_DRM_CERTIFICATES | |
| android.permission.ACCESS_EPHEMERAL_APPS | |
| android.permission.ACCESS_FM_RADIO |
| extension DispatchQueue { | |
| class func mainSyncSafe(execute work: () -> Void) { | |
| if Thread.isMainThread { | |
| work() | |
| } else { | |
| DispatchQueue.main.sync(execute: work) | |
| } | |
| } | |
| class func mainSyncSafe<T>(execute work: () throws -> T) rethrows -> T { |
| import Foundation | |
| import WebKit | |
| final class WebCacheCleaner { | |
| class func clean() { | |
| HTTPCookieStorage.shared.removeCookies(since: Date.distantPast) | |
| print("[WebCacheCleaner] All cookies deleted") | |
| WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in |