summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift2
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift2
-rw-r--r--ios/MullvadVPN/AppStoreReceipt.swift74
-rw-r--r--ios/MullvadVPN/ConsolidatedApplicationLog.swift34
-rw-r--r--ios/MullvadVPN/DisplayChainedError.swift26
-rw-r--r--ios/MullvadVPN/ProblemReportViewController.swift3
6 files changed, 52 insertions, 89 deletions
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift
index 5e1be9b6fc..ad29ef3929 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerError.swift
@@ -21,7 +21,7 @@ extension AppStorePaymentManager {
case storePayment(Swift.Error)
/// Failure to read the AppStore receipt.
- case readReceipt(AppStoreReceipt.Error)
+ case readReceipt(Swift.Error)
/// Failure to send the AppStore receipt to backend.
case sendReceipt(REST.Error)
diff --git a/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift b/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
index 04a7813d4a..32295d4350 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
@@ -60,7 +60,7 @@ class SendAppStoreReceiptOperation: ResultOperation<
case let .failure(error):
self.logger.error(
- chainedError: error,
+ chainedError: AnyChainedError(error),
message: "Failed to fetch the AppStore receipt."
)
self.finish(completion: .failure(.readReceipt(error)))
diff --git a/ios/MullvadVPN/AppStoreReceipt.swift b/ios/MullvadVPN/AppStoreReceipt.swift
index c4bb18060c..ee1186b9b9 100644
--- a/ios/MullvadVPN/AppStoreReceipt.swift
+++ b/ios/MullvadVPN/AppStoreReceipt.swift
@@ -9,29 +9,13 @@
import Foundation
import StoreKit
-enum AppStoreReceipt {
- enum Error: ChainedError {
- /// AppStore receipt file does not exist or file URL is not available.
- case doesNotExist
-
- /// IO error.
- case io(Swift.Error)
-
- /// Failure to refresh the receipt from AppStore.
- case refresh(Swift.Error)
-
- var errorDescription: String? {
- switch self {
- case .doesNotExist:
- return "AppStore receipt file does not exist on disk."
- case .io:
- return "Read error."
- case .refresh:
- return "Receipt refresh error."
- }
- }
+struct AppStoreReceiptNotFound: LocalizedError {
+ var errorDescription: String? {
+ return "AppStore receipt file does not exist on disk."
}
+}
+enum AppStoreReceipt {
/// Internal operation queue.
private static let operationQueue: OperationQueue = {
let queue = AsyncOperationQueue()
@@ -63,9 +47,7 @@ enum AppStoreReceipt {
}
}
-private class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreReceipt.Error>,
- SKRequestDelegate
-{
+private class FetchAppStoreReceiptOperation: ResultOperation<Data, Error>, SKRequestDelegate {
private var request: SKReceiptRefreshRequest?
private let receiptProperties: [String: Any]?
private let forceRefresh: Bool
@@ -93,13 +75,15 @@ private class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreRecei
}
// Read AppStore receipt from disk.
- let result = readReceiptFromDisk()
+ do {
+ let data = try readReceiptFromDisk()
- // Pull receipt from AppStore if it's not cached locally.
- if case .failure(.doesNotExist) = result {
+ finish(completion: .success(data))
+ } catch is AppStoreReceiptNotFound {
+ // Pull receipt from AppStore if it's not cached locally.
startRefreshRequest()
- } else {
- finish(completion: OperationCompletion(result: result))
+ } catch {
+ finish(completion: .failure(error))
}
}
@@ -137,32 +121,28 @@ private class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreRecei
return
}
- let result: Result<Data, AppStoreReceipt.Error>
-
if let error = error {
- result = .failure(.refresh(error))
+ finish(completion: .failure(error))
} else {
- result = readReceiptFromDisk()
- }
+ let result = Result { try readReceiptFromDisk() }
- finish(completion: OperationCompletion(result: result))
+ finish(completion: OperationCompletion(result: result))
+ }
}
- private func readReceiptFromDisk() -> Result<Data, AppStoreReceipt.Error> {
+ private func readReceiptFromDisk() throws -> Data {
guard let appStoreReceiptURL = Bundle.main.appStoreReceiptURL else {
- return .failure(.doesNotExist)
+ throw AppStoreReceiptNotFound()
}
- let readResult = Result { try Data(contentsOf: appStoreReceiptURL) }
-
- return readResult.mapError { error -> AppStoreReceipt.Error in
- if let cocoaError = error as? CocoaError,
- cocoaError.code == .fileReadNoSuchFile || cocoaError.code == .fileNoSuchFile
- {
- return .doesNotExist
- } else {
- return .io(error)
- }
+ do {
+ return try Data(contentsOf: appStoreReceiptURL)
+ } catch let error as CocoaError
+ where error.code == .fileReadNoSuchFile || error.code == .fileNoSuchFile
+ {
+ throw AppStoreReceiptNotFound()
+ } catch {
+ throw error
}
}
}
diff --git a/ios/MullvadVPN/ConsolidatedApplicationLog.swift b/ios/MullvadVPN/ConsolidatedApplicationLog.swift
index b7e00b2ea9..ad5f53eda0 100644
--- a/ios/MullvadVPN/ConsolidatedApplicationLog.swift
+++ b/ios/MullvadVPN/ConsolidatedApplicationLog.swift
@@ -27,20 +27,6 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
let content: String
}
- enum Error: ChainedError {
- case logFileDoesNotExist(String)
- case invalidLogFileURL(URL)
-
- var errorDescription: String? {
- switch self {
- case let .logFileDoesNotExist(path):
- return "Log file does not exist: \(path)."
- case let .invalidLogFileURL(url):
- return "Invalid log file URL: \(url.absoluteString)."
- }
- }
- }
-
let redactCustomStrings: [String]
let applicationGroupContainers: [URL]
let metadata: Metadata
@@ -75,8 +61,8 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
}
}
- func addError<ErrorType: ChainedError>(message: String, error: ErrorType) {
- let redactedError = redact(string: error.displayChain())
+ func addError(message: String, error: String) {
+ let redactedError = redact(string: error)
logs.append(LogAttachment(label: message, content: redactedError))
}
@@ -105,20 +91,22 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
private func addSingleLogFile(_ fileURL: URL) {
guard fileURL.isFileURL else {
- addError(message: fileURL.absoluteString, error: Error.invalidLogFileURL(fileURL))
+ addError(
+ message: fileURL.absoluteString,
+ error: "Invalid log file URL: \(fileURL.absoluteString)."
+ )
return
}
let path = fileURL.path
let redactedPath = redact(string: path)
- do {
- let lossyString = try Self.readFileLossy(path: path, maxBytes: kLogMaxReadBytes)
+ if let lossyString = Self.readFileLossy(path: path, maxBytes: kLogMaxReadBytes) {
let redactedString = redact(string: lossyString)
logs.append(LogAttachment(label: redactedPath, content: redactedString))
- } catch {
- addError(message: redactedPath, error: AnyChainedError(error))
+ } else {
+ addError(message: redactedPath, error: "Log file does not exist: \(path).")
}
}
@@ -134,9 +122,9 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
]
}
- private static func readFileLossy(path: String, maxBytes: UInt64) throws -> String {
+ private static func readFileLossy(path: String, maxBytes: UInt64) -> String? {
guard let fileHandle = FileHandle(forReadingAtPath: path) else {
- throw Error.logFileDoesNotExist(path)
+ return nil
}
let endOfFileOffset = fileHandle.seekToEndOfFile()
diff --git a/ios/MullvadVPN/DisplayChainedError.swift b/ios/MullvadVPN/DisplayChainedError.swift
index 15dcf930ce..f0e8efee4c 100644
--- a/ios/MullvadVPN/DisplayChainedError.swift
+++ b/ios/MullvadVPN/DisplayChainedError.swift
@@ -136,11 +136,14 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
}
case let .readReceipt(readReceiptError):
- switch readReceiptError {
- case let .refresh(storeError):
- let skErrorMessage = (storeError as? SKError)?.errorDescription ?? storeError
- .localizedDescription
-
+ if readReceiptError is AppStoreReceiptNotFound {
+ return NSLocalizedString(
+ "RECEIPT_NOT_FOUND_ERROR",
+ tableName: "AppStorePaymentManager",
+ value: "AppStore receipt is not found on disk.",
+ comment: ""
+ )
+ } else if let storeError = readReceiptError as? SKError {
return String(
format: NSLocalizedString(
"REFRESH_RECEIPT_ERROR",
@@ -148,9 +151,9 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
value: "Cannot refresh the AppStore receipt: %@",
comment: ""
),
- skErrorMessage
+ storeError.localizedDescription
)
- case let .io(ioError):
+ } else {
return String(
format: NSLocalizedString(
"READ_RECEIPT_ERROR",
@@ -158,14 +161,7 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
value: "Cannot read the AppStore receipt from disk: %@",
comment: ""
),
- ioError.localizedDescription
- )
- case .doesNotExist:
- return NSLocalizedString(
- "RECEIPT_NOT_FOUND_ERROR",
- tableName: "AppStorePaymentManager",
- value: "AppStore receipt is not found on disk.",
- comment: ""
+ readReceiptError.localizedDescription
)
}
diff --git a/ios/MullvadVPN/ProblemReportViewController.swift b/ios/MullvadVPN/ProblemReportViewController.swift
index a48da7ba24..1c20ddedc0 100644
--- a/ios/MullvadVPN/ProblemReportViewController.swift
+++ b/ios/MullvadVPN/ProblemReportViewController.swift
@@ -283,8 +283,7 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
@objc func handleViewLogsButtonTap() {
let reviewController = ProblemReportReviewViewController(
- reportString: consolidatedLog
- .string
+ reportString: consolidatedLog.string
)
let navigationController = UINavigationController(rootViewController: reviewController)