はじめに
まずはじめに結論を言うと、 Timer
の使い方の一つを紹介するという内容になります。
トークンの更新処理などは SDK などに委ねるのが一般的なので、処理方法の参考としてご覧ください。
自動更新処理
final class NetworkManager {
private enum Const {
/// 10 minutes ago
static let timeGap: TimeInterval = -60 * 10
}
public var token: String {
_token
}
private var _token = ""
private var timer: Timer?
private var expiration: Date = Date() {
didSet {
timer?.invalidate()
// 期限の10分前にトークンの更新をリクエスト
timer = Timer(fire: Date(timeInterval: Const.timeGap, since: expiration), interval: .zero, repeats: false) { [weak self] _ in
self?.updateToken()
}
if let timer = timer {
// Timer を init して生成している関係で必要になる処理
RunLoop.main.add(timer, forMode: .default)
}
}
}
deinit {
// Class が破棄される時に Timer も無効にする
timer?.invalidate()
}
private func updateToken() {
createToken(
success: { [weak self] info in
self?.expiration = info.expiration
self?._token = info.token
},
failure: { error in
debugPrint(error)
}
)
}
}
extension NetworkManager {
public struct AuthInfo {
let token: String
let expiration: Date
}
// サーバとの通信処理を再現
public func createToken(success: @escaping (AuthInfo) -> Void, failure: @escaping (Error) -> Void) {
let token = "E9rF7M3xgCE1taG6Qz7t" // SAMPLE
let tomorrow = Date(timeIntervalSinceNow: 60 * 60 * 24) // SAMPLE
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
success(AuthInfo(token: token, expiration: tomorrow))
}
}
}
さいごに
「SDKから常に期限が切れていない Token を取得できるから便利!」という処理の裏の実装方法として、このようなパターンも考えられます。
ただ、端末の時間が間違っていると、正常に動作しない問題を抱えていることに気がつくと思います。
はじめにも書きましたが、処理手法の参考としてみていただければと思います。