Files
SideStore/AltStoreCore/Model/NewsItem.swift

121 lines
4.1 KiB
Swift

//
// NewsItem.swift
// AltStore
//
// Created by Riley Testut on 8/29/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import UIKit
import CoreData
@objc(NewsItem)
public class NewsItem: BaseEntity, Decodable
{
/* Properties */
@NSManaged public var identifier: String
@NSManaged public var date: Date
@NSManaged public var title: String
@NSManaged public var caption: String
@NSManaged public var tintColor: UIColor
@NSManaged public var sortIndex: Int32
@NSManaged public var isSilent: Bool
@NSManaged public var imageURL: URL?
@NSManaged public var externalURL: URL?
@NSManaged public var appID: String?
@NSManaged public var sourceIdentifier: String?
/* Relationships */
@NSManaged public var storeApp: StoreApp?
@NSManaged public var source: Source?
private enum CodingKeys: String, CodingKey
{
case identifier
case date
case title
case caption
case tintColor
case imageURL
case externalURL = "url"
case appID
case notify
}
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
{
super.init(entity: entity, insertInto: context)
}
public required init(from decoder: Decoder) throws
{
guard let context = decoder.managedObjectContext else { preconditionFailure("Decoder must have non-nil NSManagedObjectContext.") }
super.init(entity: NewsItem.entity(), insertInto: context)
let container = try decoder.container(keyedBy: CodingKeys.self)
self.identifier = try container.decode(String.self, forKey: .identifier)
self.date = try container.decode(Date.self, forKey: .date)
self.title = try container.decode(String.self, forKey: .title)
self.caption = try container.decode(String.self, forKey: .caption)
if let tintColorHex = try container.decodeIfPresent(String.self, forKey: .tintColor)
{
guard let tintColor = UIColor(hexString: tintColorHex) else {
throw DecodingError.dataCorruptedError(forKey: .tintColor, in: container, debugDescription: "Hex code is invalid.")
}
self.tintColor = tintColor
}
self.imageURL = try container.decodeIfPresent(URL.self, forKey: .imageURL)
self.externalURL = try container.decodeIfPresent(URL.self, forKey: .externalURL)
// TODO: app specific news should be moved to appEntity (via refactoring)
// This can be done by: 1. having two newsItem schema, one for source and one for StoreApp
// 2. move this appID field into the newItem schema which is under StoreApp.
self.appID = try container.decodeIfPresent(String.self, forKey: .appID)
let notify = try container.decodeIfPresent(Bool.self, forKey: .notify) ?? false
self.isSilent = !notify
}
}
public extension NewsItem
{
var globallyUniqueID: String? {
guard let sourceIdentifier = self.sourceIdentifier else { return nil }
let globallyUniqueID = self.identifier + "|" + sourceIdentifier
return globallyUniqueID
}
}
public extension NewsItem
{
@nonobjc class func fetchRequest() -> NSFetchRequest<NewsItem>
{
return NSFetchRequest<NewsItem>(entityName: "NewsItem")
}
class func sortedFetchRequest(for source: Source?) -> NSFetchRequest<NewsItem>
{
let fetchRequest = NewsItem.fetchRequest() as NSFetchRequest<NewsItem>
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \NewsItem.date, ascending: false),
NSSortDescriptor(keyPath: \NewsItem.sortIndex, ascending: true),
NSSortDescriptor(keyPath: \NewsItem.sourceIdentifier, ascending: true)]
if let source
{
fetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(NewsItem.source), source)
}
return fetchRequest
}
}