91 lines
3.7 KiB
Swift
Raw Permalink Normal View History

import Foundation
@objc(RemoteNotificationLinks)
public class RemoteNotificationLinks: NSObject, NSSecureCoding, Codable {
public static var supportsSecureCoding: Bool = true
let primary: RemoteNotificationLink?
let secondary: [RemoteNotificationLink]?
let legacyPrimary: RemoteNotificationLink?
init(primary: RemoteNotificationLink?, secondary: [RemoteNotificationLink]?, legacyPrimary: RemoteNotificationLink?) {
self.primary = primary
self.secondary = secondary
self.legacyPrimary = legacyPrimary
}
public required convenience init(coder decoder: NSCoder) {
let primary = decoder.decodeObject(of: RemoteNotificationLink.self, forKey: "primary")
let classes = [NSArray.classForCoder(), RemoteNotificationLink.classForCoder()]
let secondary = decoder.decodeObject(of: classes, forKey: "secondary") as? [RemoteNotificationLink]
let legacyPrimary = decoder.decodeObject(of: RemoteNotificationLink.self, forKey: "legacyPrimary")
self.init(primary: primary, secondary: secondary, legacyPrimary: legacyPrimary)
}
public func encode(with coder: NSCoder) {
coder.encode(primary, forKey: "primary")
coder.encode(secondary, forKey: "secondary")
coder.encode(legacyPrimary, forKey: "legacyPrimary")
}
}
@objc(RemoteNotificationLink)
public final class RemoteNotificationLink: NSObject, NSSecureCoding, Codable {
public static var supportsSecureCoding: Bool = true
let type: String?
public let url: URL?
public let label: String?
init(type: NSString?, url: URL?, label: NSString?) {
self.type = type as String?
self.url = url
self.label = label as String?
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
type = try? values.decode(String.self, forKey: .type)
let urlString = try? values.decode(String.self, forKey: .url)
if var urlString = urlString {
// If there's a fragment, it may not be encoded from the API, thus URLs and URLComponents won't instantiate.
// Manually encoding it here.
// https://phabricator.wikimedia.org/T307604
if let firstHashIndex = urlString.firstIndex(of: "#") {
let preFragment = urlString.prefix(upTo: firstHashIndex)
let nextIndex = urlString.index(firstHashIndex, offsetBy: 1)
let fragment = urlString.suffix(from: nextIndex)
let unallowedFragmentCharacters = CharacterSet.urlFragmentAllowed.inverted
if fragment.rangeOfCharacter(from: unallowedFragmentCharacters) != nil {
urlString = preFragment + "#" + (fragment.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed) ?? "")
}
}
url = URL(string: urlString)
} else {
url = nil
}
label = try? values.decode(String.self, forKey: .label)
}
public required convenience init(coder decoder: NSCoder) {
let type = decoder.decodeObject(of: NSString.self, forKey: "type")
let urlString = decoder.decodeObject(of: NSString.self, forKey: "url")
let label = decoder.decodeObject(of: NSString.self, forKey: "label")
let url = URL(string: urlString as String? ?? "")
self.init(type: type, url: url, label: label)
}
public func encode(with coder: NSCoder) {
coder.encode(type, forKey: "type")
let urlString = url?.absoluteString
coder.encode(urlString, forKey: "url")
coder.encode(label, forKey: "label")
}
}