blog
blog copied to clipboard
swift 常用算法小记
计算还有多少天生日
// 计算距离生日的天数
private func daysToBirthday(birthday: Date) -> Int {
// 今天生日的情况(不然后面的计算会误把下个生日算到明年,也就是返回365)
if (Calendar.current.dateComponents([.year, .month, .day], from: Date()).month == Calendar.current.dateComponents([.year, .month, .day], from: birthday).month
&& Calendar.current.dateComponents([.year, .month, .day], from: Date()).day == Calendar.current.dateComponents([.year, .month, .day], from: birthday).day) {
return 0
}
let today = Calendar.current.startOfDay(for: Date())
let date = Calendar.current.startOfDay(for: birthday)
let components = Calendar.current.dateComponents([.day, .month], from: date)
let nextDate = Calendar.current.nextDate(after: today, matching: components, matchingPolicy: .nextTimePreservingSmallerComponents)
return Calendar.current.dateComponents([.day], from: today, to: nextDate ?? today).day ?? 0
}
计算某个时间到今天的天数
// 计算某个时间到今天的天数
private func daysToNow(from: Date) -> Int {
let date1 = Calendar.current.startOfDay(for: from)
let date2 = Calendar.current.startOfDay(for: Date())
// 不能直接用 date 进行 Calendar.current.dateComponents([.day], from: from, to: Date()) 计算,这样不超过24小时的都算是返回0,比如昨天会返回0而前天会返回1
let components = Calendar.current.dateComponents([.day], from: date1, to: date2)
return components.day ?? 0
}
获取时间戳
extension Date {
/// 获取当前 秒级 时间戳 - 10位
var timeStamp : String {
let timeInterval: TimeInterval = self.timeIntervalSince1970
let timestamp = Int(timeInterval)
return "\(timestamp)"
}
/// 获取当前 毫秒级 时间戳 - 13位
var milliStamp : String {
let timeInterval : TimeInterval = self.timeIntervalSince1970
let millisecond = CLongLong(round(timeInterval*1000))
return "\(millisecond)"
}
}
FaceID人脸识别封装
import Foundation
import LocalAuthentication // 生物特征识别
class Authentication: ObservableObject{
@Published var hasAuthenticate: Bool = false // 是否已鉴权
/*
* 鉴权函数,调起 FACE ID 生物识别
* 用法:
* 1)引入鉴权环境对象 @EnvironmentObject var authenticateObj : Authentication
* 2)需要的时候,调用函数进行鉴权 authenticateObj.authenticate()
* 3)判断是否已鉴权 if authenticateObj.hasAuthenticate { }
*/
func authenticate() {
let context = LAContext()
var error: NSError?
// 如果已经鉴权,则不用再调起
if self.hasAuthenticate {
return
}
// 检查是否可以进行生物特征识别
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// 如果可以,执行识别
let reason = "We need to unlock your data."
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
// 鉴权完成
DispatchQueue.main.async {
if success {
// 鉴权成功
self.hasAuthenticate = true
} else {
// 鉴权失败
self.hasAuthenticate = false
}
}
}
} else {
// 没有生物特征识别功能
}
}
}
获取APP名称
extension Bundle {
var releaseVersionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0"
}
var buildVersionNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String ?? "1"
}
var displayName: String? {
return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
object(forInfoDictionaryKey: "CFBundleName") as? String ?? "Unknown"
}
}
Double取N位小数
// double取多少位小数
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
获取屏幕宽高
注意:iPad 下屏幕宽度跟可页面可视宽度不一致,要使用
GeometryReader
// 屏幕宽度
class SGConvenience{
#if os(watchOS)
static var deviceWidth:CGFloat = WKInterfaceDevice.current().screenBounds.size.width
static var deviceHeight:CGFloat = WKInterfaceDevice.current().screenBounds.size.height
#elseif os(iOS)
static var deviceWidth:CGFloat = UIScreen.main.bounds.size.width
static var deviceHeight:CGFloat = UIScreen.main.bounds.size.height
#elseif os(macOS)
static var deviceWidth:CGFloat? = NSScreen.main?.visibleFrame.size.width // You could implement this to force a CGFloat and get the full device screen size width regardless of the window size with .frame.size.width
static var deviceHeight:CGFloat? = NSScreen.main?.visibleFrame.size.height
#endif
}
解决中文问题
extension String {
// base64(可用于解决中文问题)
func fromBase64() -> String? {
guard let data = Data(base64Encoded: self) else {
return nil
}
return String(data: data, encoding: .utf8)
}
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}
打开AppStore评分
// 打开评分
if let scene = UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive })
as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
}