NCAPISessionManager.swift 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //
  2. // SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  3. // SPDX-License-Identifier: GPL-3.0-or-later
  4. //
  5. import Foundation
  6. @objcMembers public class NCAPISessionManager: NCBaseSessionManager {
  7. init(configuration: URLSessionConfiguration) {
  8. super.init(configuration: configuration, responseSerializer: AFJSONResponseSerializer(), requestSerializer: AFHTTPRequestSerializer())
  9. self.requestSerializer.setValue("application/json", forHTTPHeaderField: "Accept")
  10. self.requestSerializer.setValue("true", forHTTPHeaderField: "OCS-APIRequest")
  11. }
  12. private func checkHeaders(for task: URLSessionDataTask, for account: TalkAccount) {
  13. guard let response = task.response as? HTTPURLResponse else { return }
  14. if let modifiedSince = response.allHeaderFields["x-nextcloud-talk-modified-before"] as? String, !modifiedSince.isEmpty {
  15. NCDatabaseManager.sharedInstance().updateLastModifiedSince(forAccountId: account.accountId, with: modifiedSince)
  16. }
  17. if let configurationHash = response.allHeaderFields["x-nextcloud-talk-hash"] as? String, configurationHash != account.lastReceivedConfigurationHash {
  18. if account.lastReceivedConfigurationHash != nil {
  19. // We previously stored a configuration hash which now changed -> Update settings and capabilities
  20. let userInfo: [AnyHashable: Any] = [
  21. "accountId": account.accountId,
  22. "configurationHash": configurationHash
  23. ]
  24. NotificationCenter.default.post(name: .NCTalkConfigurationHashChanged, object: self, userInfo: userInfo)
  25. } else {
  26. NCDatabaseManager.sharedInstance().updateTalkConfigurationHash(forAccountId: account.accountId, withHash: configurationHash)
  27. }
  28. }
  29. }
  30. private func checkStatusCode(for task: URLSessionDataTask, for account: TalkAccount) {
  31. guard let response = task.response as? HTTPURLResponse else { return }
  32. let statusCode = response.statusCode
  33. let userInfo: [AnyHashable: Any] = ["accountId": account.accountId]
  34. switch statusCode {
  35. case 401:
  36. NotificationCenter.default.post(name: .NCTokenRevokedResponseReceived, object: self, userInfo: userInfo)
  37. case 426:
  38. NotificationCenter.default.post(name: .NCUpgradeRequiredResponseReceived, object: self, userInfo: userInfo)
  39. case 503:
  40. NotificationCenter.default.post(name: .NCServerMaintenanceMode, object: self, userInfo: userInfo)
  41. default:
  42. break
  43. }
  44. }
  45. @discardableResult
  46. public func getOcs(_ URLString: String, account: TalkAccount, parameters: Any? = nil, progress downloadProgress: ((Progress) -> Void)? = nil, checkResponseHeaders: Bool = true, checkResponseStatusCode: Bool = true, completion: ((OcsResponse?, (any Error)?) -> Void)?) -> URLSessionDataTask? {
  47. return self.get(URLString, parameters: parameters, progress: downloadProgress) { task, data in
  48. if checkResponseHeaders {
  49. self.checkHeaders(for: task, for: account)
  50. }
  51. completion?(OcsResponse(withData: data, withTask: task), nil)
  52. } failure: { task, error in
  53. if checkResponseStatusCode, let task {
  54. self.checkStatusCode(for: task, for: account)
  55. }
  56. completion?(nil, error)
  57. }
  58. }
  59. @discardableResult
  60. public func postOcs(_ URLString: String, account: TalkAccount, parameters: Any? = nil, progress downloadProgress: ((Progress) -> Void)? = nil, checkResponseStatusCode: Bool = true, completion: ((OcsResponse?, (any Error)?) -> Void)?) -> URLSessionDataTask? {
  61. return self.post(URLString, parameters: parameters, progress: downloadProgress) { task, data in
  62. completion?(OcsResponse(withData: data, withTask: task), nil)
  63. } failure: { task, error in
  64. if checkResponseStatusCode, let task {
  65. self.checkStatusCode(for: task, for: account)
  66. }
  67. completion?(nil, error)
  68. }
  69. }
  70. @discardableResult
  71. public func putOcs(_ URLString: String, account: TalkAccount, parameters: Any? = nil, checkResponseStatusCode: Bool = true, completion: ((OcsResponse?, (any Error)?) -> Void)?) -> URLSessionDataTask? {
  72. return self.put(URLString, parameters: parameters) { task, data in
  73. completion?(OcsResponse(withData: data, withTask: task), nil)
  74. } failure: { task, error in
  75. if checkResponseStatusCode, let task {
  76. self.checkStatusCode(for: task, for: account)
  77. }
  78. completion?(nil, error)
  79. }
  80. }
  81. @discardableResult
  82. public func deleteOcs(_ URLString: String, account: TalkAccount, parameters: Any? = nil, checkResponseStatusCode: Bool = true, completion: ((OcsResponse?, (any Error)?) -> Void)?) -> URLSessionDataTask? {
  83. return self.delete(URLString, parameters: parameters) { task, data in
  84. completion?(OcsResponse(withData: data, withTask: task), nil)
  85. } failure: { task, error in
  86. if checkResponseStatusCode, let task {
  87. self.checkStatusCode(for: task, for: account)
  88. }
  89. completion?(nil, error)
  90. }
  91. }
  92. }