Make progress on getting Database.framework to build.
This commit is contained in:
parent
f46a3ece48
commit
e3b8e6833b
|
@ -16,7 +16,7 @@ public struct Attachment: Equatable {
|
|||
public let sizeInBytes: Int?
|
||||
public let durationInSeconds: Int?
|
||||
|
||||
init(url: String, mimeType: String?, title: String?, sizeInBytes: Int?, durationInSeconds: Int?) {
|
||||
public init(url: String, mimeType: String?, title: String?, sizeInBytes: Int?, durationInSeconds: Int?) {
|
||||
|
||||
self.url = url
|
||||
self.mimeType = mimeType
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// AccountInfo.swift
|
||||
// Database
|
||||
//
|
||||
// Created by Brent Simmons on 7/3/17.
|
||||
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
import RSDatabase
|
||||
|
||||
// AccountInfo is a plist-compatible dictionary that’s stored as a binary plist in the database.
|
||||
|
||||
func accountInfoWithRow(_ row: FMResultSet) -> AccountInfo? {
|
||||
|
||||
guard let rawAccountInfo = row.data(forColumn: DatabaseKey.accountInfo) else {
|
||||
return nil
|
||||
}
|
||||
return propertyList(withData: rawAccountInfo) as? AccountInfo
|
||||
}
|
|
@ -51,5 +51,10 @@ public struct DatabaseKey {
|
|||
|
||||
// Tag
|
||||
static let tagName = "tagName"
|
||||
|
||||
// Author
|
||||
static let name = "name"
|
||||
static let avatarURL = "avatarURL"
|
||||
static let emailAddress = "emailAddress"
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ CREATE TABLE if not EXISTS tags(tagName TEXT NOT NULL, articleID TEXT NOT NULL,
|
|||
|
||||
CREATE TABLE if not EXISTS attachments(articleID TEXT NOT NULL, url TEXT NOT NULL, mimeType TEXT, title TEXT, sizeInBytes INTEGER, durationInSeconds INTEGER, PRIMARY KEY(articleID, url));
|
||||
|
||||
CREATE INDEX if not EXISTS feedIndex on articles (feedID);
|
||||
CREATE INDEX if not EXISTS articles_feedID_index on articles (feedID);
|
||||
|
||||
CREATE INDEX if not EXISTS tags_tagName_index on tags(tagName COLLATE NOCASE);
|
||||
|
||||
|
|
|
@ -222,16 +222,16 @@ private extension Database {
|
|||
|
||||
let oneArticleDictionary = oneDictionary.mutableCopy() as! NSMutableDictionary
|
||||
let articleID = oneArticleDictionary[DatabaseKey.articleID]!
|
||||
oneArticleDictionary.removeObject(forKey: articleIDKey)
|
||||
oneArticleDictionary.removeObject(forKey: DatabaseKey.articleID)
|
||||
|
||||
let _ = database.rs_updateRows(with: oneArticleDictionary as [NSObject: AnyObject], whereKey: articleIDKey, equalsValue: articleID, tableName: articlesTableName)
|
||||
let _ = database.rs_updateRows(with: oneArticleDictionary as [NSObject: AnyObject], whereKey: DatabaseKey.articleID, equalsValue: articleID, tableName: DatabaseTableName.articles)
|
||||
}
|
||||
|
||||
}
|
||||
if !newArticleDictionaries.isEmpty {
|
||||
|
||||
for oneNewArticleDictionary in newArticleDictionaries {
|
||||
let _ = database.rs_insertRow(with: oneNewArticleDictionary as [NSObject: AnyObject], insertType: RSDatabaseInsertOrReplace, tableName: articlesTableName)
|
||||
let _ = database.rs_insertRow(with: oneNewArticleDictionary as [NSObject: AnyObject], insertType: RSDatabaseInsertOrReplace, tableName: DatabaseTableName.articles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ private extension Database {
|
|||
|
||||
var d = [String: AnyObject]()
|
||||
for oneArticle in articles {
|
||||
let oneArticleID = (oneArticle as AnyObject).value(forKey: articleIDKey) as! String
|
||||
let oneArticleID = (oneArticle as AnyObject).value(forKey: DatabaseKey.articleID) as! String
|
||||
d[oneArticleID] = oneArticle as AnyObject
|
||||
}
|
||||
return d
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE371F0AB3AA004AB7CD /* Database.framework */; };
|
||||
844BEE461F0AB3AB004AB7CD /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */; };
|
||||
845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580661F0AEBCD003CCFA1 /* Constants.swift */; };
|
||||
845580721F0AEE49003CCFA1 /* PropertyListTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580711F0AEE49003CCFA1 /* PropertyListTransformer.swift */; };
|
||||
845580721F0AEE49003CCFA1 /* AccountInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580711F0AEE49003CCFA1 /* AccountInfo.swift */; };
|
||||
845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580751F0AF670003CCFA1 /* Article+Database.swift */; };
|
||||
845580781F0AF678003CCFA1 /* Folder+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580771F0AF678003CCFA1 /* Folder+Database.swift */; };
|
||||
8455807A1F0AF67D003CCFA1 /* ArticleStatus+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */; };
|
||||
|
@ -113,7 +113,7 @@
|
|||
844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseTests.swift; sourceTree = "<group>"; };
|
||||
844BEE471F0AB3AB004AB7CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
845580661F0AEBCD003CCFA1 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||
845580711F0AEE49003CCFA1 /* PropertyListTransformer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PropertyListTransformer.swift; sourceTree = "<group>"; };
|
||||
845580711F0AEE49003CCFA1 /* AccountInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountInfo.swift; sourceTree = "<group>"; };
|
||||
845580751F0AF670003CCFA1 /* Article+Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Article+Database.swift"; path = "Extensions/Article+Database.swift"; sourceTree = "<group>"; };
|
||||
845580771F0AF678003CCFA1 /* Folder+Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Folder+Database.swift"; path = "Extensions/Folder+Database.swift"; sourceTree = "<group>"; };
|
||||
845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "ArticleStatus+Database.swift"; path = "Extensions/ArticleStatus+Database.swift"; sourceTree = "<group>"; };
|
||||
|
@ -206,7 +206,7 @@
|
|||
845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */,
|
||||
8455807B1F0C0DBD003CCFA1 /* Attachment+Database.swift */,
|
||||
84BB4BA31F119D4A00858766 /* Author+Database.swift */,
|
||||
845580711F0AEE49003CCFA1 /* PropertyListTransformer.swift */,
|
||||
845580711F0AEE49003CCFA1 /* AccountInfo.swift */,
|
||||
);
|
||||
name = Extensions;
|
||||
sourceTree = "<group>";
|
||||
|
@ -462,7 +462,7 @@
|
|||
845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */,
|
||||
845580781F0AF678003CCFA1 /* Folder+Database.swift in Sources */,
|
||||
845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */,
|
||||
845580721F0AEE49003CCFA1 /* PropertyListTransformer.swift in Sources */,
|
||||
845580721F0AEE49003CCFA1 /* AccountInfo.swift in Sources */,
|
||||
8455807A1F0AF67D003CCFA1 /* ArticleStatus+Database.swift in Sources */,
|
||||
84BB4BA41F119D4A00858766 /* Author+Database.swift in Sources */,
|
||||
84BB4BA91F11A32800858766 /* TagsManager.swift in Sources */,
|
||||
|
|
|
@ -35,9 +35,9 @@ extension Article {
|
|||
let authors = PropertyListTransformer.authorsWithRow(row)
|
||||
let tags = PropertyListTransformer.tagsWithRow(row)
|
||||
let attachments = PropertyListTransformer.attachmentsWithRow(row)
|
||||
let accountInfo = PropertyListTransformer.accountInfoWithRow(row)
|
||||
let accountInfo = accountInfoWithRow(row)
|
||||
|
||||
self.init(account: account, feedID: feed, uniqueID: uniqueID, title: title, contentHTML: contentHTML, contentText: contentText, url: url, externalURL: externalURL, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments, accountInfo: accountInfo]
|
||||
self.init(account: account, feedID: feed, uniqueID: uniqueID, title: title, contentHTML: contentHTML, contentText: contentText, url: url, externalURL: externalURL, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments, accountInfo: accountInfo)
|
||||
}
|
||||
|
||||
func databaseDictionary() -> NSDictionary {
|
||||
|
|
|
@ -27,7 +27,7 @@ extension ArticleStatus {
|
|||
dateArrived = NSDate.distantPast
|
||||
}
|
||||
|
||||
let accountInfoPlist = PropertyListTransformer.accountInfoWithRow(row)
|
||||
let accountInfoPlist = accountInfoWithRow(row)
|
||||
|
||||
self.init(articleID: articleID!, read: read, starred: starred, userDeleted: userDeleted, dateArrived: dateArrived!, accountInfo: accountInfoPlist)
|
||||
}
|
||||
|
|
|
@ -7,22 +7,24 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import Data
|
||||
|
||||
extension Attachment {
|
||||
|
||||
convenience init?(databaseDictionary d: [String: Any]) {
|
||||
init?(databaseDictionary d: [String: Any]) {
|
||||
|
||||
guard let url = d[DatabaseKey.url] as? String else {
|
||||
return nil
|
||||
}
|
||||
let mimeType = d[DatabaseKey.mimeType] as? String
|
||||
let title = d[DatabaseKey.title] as? String
|
||||
let sizeInBytes = d[DatabaseKey.sizeInBytes] as? Int
|
||||
let durationInSeconds = d[DatabaseKey.durationInSeconds] as? Int
|
||||
|
||||
self.init(url: url, mimeType: mimeType, title: title, durationInSeconds: durationInSeconds)
|
||||
self.init(url: url, mimeType: mimeType, title: title, sizeInBytes: sizeInBytes, durationInSeconds: durationInSeconds)
|
||||
}
|
||||
|
||||
class func attachments(with plist: [Any]) -> [Attachment]? {
|
||||
static func attachments(with plist: [Any]) -> [Attachment]? {
|
||||
|
||||
return plist.flatMap{ (oneDictionary) -> Attachment? in
|
||||
if let d = oneDictionary as? [String: Any] {
|
||||
|
|
|
@ -7,33 +7,18 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import Data
|
||||
import RSDatabase
|
||||
|
||||
extension Author {
|
||||
|
||||
private static let
|
||||
convenience init?(databaseDictionary d: [String: Any]) {
|
||||
|
||||
guard let url = d[DatabaseKey.url] as? String else {
|
||||
return nil
|
||||
}
|
||||
let mimeType = d[DatabaseKey.mimeType] as? String
|
||||
let title = d[DatabaseKey.title] as? String
|
||||
let durationInSeconds = d[DatabaseKey.durationInSeconds] as? Int
|
||||
|
||||
self.init(url: url, mimeType: mimeType, title: title, durationInSeconds: durationInSeconds)
|
||||
|
||||
init?(row: FMResultSet) {
|
||||
|
||||
let name = row.string(forColumn: DatabaseKey.name)
|
||||
let url = row.string(forColumn: DatabaseKey.url)
|
||||
let avatarURL = row.string(forColumn: DatabaseKey.avatarURL)
|
||||
let emailAddress = row.string(forColumn: DatabaseKey.emailAddress)
|
||||
|
||||
self.init(name: name, url: url, avatarURL: avatarURL, emailAddress: emailAddress)
|
||||
}
|
||||
|
||||
class func attachments(with plist: [Any]) -> [Attachment]? {
|
||||
|
||||
return plist.flatMap{ (oneDictionary) -> Attachment? in
|
||||
if let d = oneDictionary as? [String: Any] {
|
||||
return Attachment(databaseDictionary: d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
//
|
||||
// AccountInfo.swift
|
||||
// Database
|
||||
//
|
||||
// Created by Brent Simmons on 7/3/17.
|
||||
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSDatabase
|
||||
import Data
|
||||
|
||||
// This allows for serializing structures such as Author, Attachment, and AccountInfo
|
||||
// without having to create separate tables and lookup tables.
|
||||
// While there are good strong arguments for using separate tables,
|
||||
// we decided that the relative simplicity this allows is worth it.
|
||||
|
||||
struct PropertyListTransformer {
|
||||
|
||||
static func accountInfoWithRow(_ row: FMResultSet) -> AccountInfo? {
|
||||
|
||||
guard let rawAccountInfo = row.data(forColumn: DatabaseKey.accountInfo) else {
|
||||
return nil
|
||||
}
|
||||
return propertyList(withData: rawAccountInfo) as? AccountInfo
|
||||
}
|
||||
|
||||
static func tagsWithRow(_ row: FMResultSet) -> [String]? {
|
||||
|
||||
guard let d = row.data(forColumn: DatabaseKey.tags) else {
|
||||
return nil
|
||||
}
|
||||
return propertyList(withData: d) as? [String]
|
||||
}
|
||||
|
||||
static func attachmentsWithRow(_ row: FMResultSet) -> [Attachment]? {
|
||||
|
||||
guard let d = row.data(forColumn: DatabaseKey.attachments) else {
|
||||
return nil
|
||||
}
|
||||
guard let plist = propertyList(withData: d) as? [Any] else {
|
||||
return nil
|
||||
}
|
||||
return Attachment.attachments(with: plist)
|
||||
}
|
||||
|
||||
static func authorsWithRow(_ row: FMResultSet) -> [Author]? {
|
||||
|
||||
guard let d = row.data(forColumn: DatabaseKey.authors) else {
|
||||
return nil
|
||||
}
|
||||
guard let plist = propertyList(withData: d) as? [Any] else {
|
||||
return nil
|
||||
}
|
||||
return Author.authors(with: plist)
|
||||
}
|
||||
|
||||
static func propertyListWithRow(_ row: FMResultSet, column: String) -> Any? {
|
||||
|
||||
guard let rawData = row.data(forColumn: column) else {
|
||||
return nil
|
||||
}
|
||||
return propertyList(withData: rawData)
|
||||
}
|
||||
|
||||
static func propertyList(withData data: Data) -> Any? {
|
||||
|
||||
do {
|
||||
return try PropertyListSerialization.propertyList(fromData: rawAccountInfo, options: [], format: nil)
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
static func data(withPropertyList plist: Any) -> Data? {
|
||||
|
||||
do {
|
||||
return try PropertyListSerialization.data(from: plist, format: .binary, options: [])
|
||||
}
|
||||
catch {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,15 +8,18 @@
|
|||
|
||||
import Foundation
|
||||
import RSDatabase
|
||||
import Data
|
||||
|
||||
// Tags — and the non-existence of tags — are cached, once fetched, for the lifetime of the run.
|
||||
// This uses some extra memory but cuts way down on the amount of database time spent
|
||||
// maintaining the tags table.
|
||||
|
||||
typealias TagNameSet = Set<String>
|
||||
|
||||
final class TagsManager {
|
||||
|
||||
private var articleIDCache = [String: <String>]() // articleID: tag
|
||||
private var articleIDsWithNoTags = Set<String>()
|
||||
private var articleIDCache = [String: TagNameSet]() // articleID: tags
|
||||
private var articleIDsWithNoTags = TagNameSet()
|
||||
|
||||
private let queue: RSDatabaseQueue
|
||||
|
||||
|
@ -53,8 +56,6 @@ final class TagsManager {
|
|||
}
|
||||
}
|
||||
|
||||
typealias TagNameSet = Set<String>
|
||||
|
||||
private extension TagsManager {
|
||||
|
||||
func cacheTagsForArticle(_ article: Article, tags: TagNameSet) {
|
||||
|
@ -183,7 +184,7 @@ private extension TagsManager {
|
|||
}
|
||||
}
|
||||
|
||||
func fetchTagsForArticleIDs(_ articleIDs: Set<String>, database: FMDatabase) -> TagsTable] {
|
||||
func fetchTagsForArticleIDs(_ articleIDs: Set<String>, database: FMDatabase) -> TagsTable {
|
||||
|
||||
var tagSpecifiers = TagsTable()
|
||||
|
||||
|
@ -193,7 +194,7 @@ private extension TagsManager {
|
|||
|
||||
while rs.next() {
|
||||
|
||||
guard let oneTagName = rs.string(forColumn: DatabaseKey.tagName), oneArticleID = rs.string(forColumn: DatabaseKey.articleID) else {
|
||||
guard let oneTagName = rs.string(forColumn: DatabaseKey.tagName), let oneArticleID = rs.string(forColumn: DatabaseKey.articleID) else {
|
||||
continue
|
||||
}
|
||||
if tagSpecifiers[oneArticleID] == nil {
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
84CFF56A1AC3D1B000CEA6C8 /* RSScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 84CFF5681AC3D1B000CEA6C8 /* RSScaling.m */; };
|
||||
84CFF56D1AC3D20A00CEA6C8 /* NSImage+RSCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 84CFF56B1AC3D20A00CEA6C8 /* NSImage+RSCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84CFF56E1AC3D20A00CEA6C8 /* NSImage+RSCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 84CFF56C1AC3D20A00CEA6C8 /* NSImage+RSCore.m */; };
|
||||
84F20F831F16BA6200D8E682 /* PropertyList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F20F821F16BA6200D8E682 /* PropertyList.swift */; };
|
||||
84FE9FC31C00453900081CE9 /* NSStoryboard+RSCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 84FE9FC11C00453900081CE9 /* NSStoryboard+RSCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84FE9FC41C00453900081CE9 /* NSStoryboard+RSCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 84FE9FC21C00453900081CE9 /* NSStoryboard+RSCore.m */; };
|
||||
84FEB4AC1D19D7F4004727E5 /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FEB4AB1D19D7F4004727E5 /* Date+Extensions.swift */; };
|
||||
|
@ -234,6 +235,7 @@
|
|||
84CFF5681AC3D1B000CEA6C8 /* RSScaling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSScaling.m; sourceTree = "<group>"; };
|
||||
84CFF56B1AC3D20A00CEA6C8 /* NSImage+RSCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+RSCore.h"; sourceTree = "<group>"; };
|
||||
84CFF56C1AC3D20A00CEA6C8 /* NSImage+RSCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSImage+RSCore.m"; sourceTree = "<group>"; };
|
||||
84F20F821F16BA6200D8E682 /* PropertyList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyList.swift; sourceTree = "<group>"; };
|
||||
84FE9FC11C00453900081CE9 /* NSStoryboard+RSCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSStoryboard+RSCore.h"; sourceTree = "<group>"; };
|
||||
84FE9FC21C00453900081CE9 /* NSStoryboard+RSCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSStoryboard+RSCore.m"; sourceTree = "<group>"; };
|
||||
84FEB4AB1D19D7F4004727E5 /* Date+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Extensions.swift"; sourceTree = "<group>"; };
|
||||
|
@ -377,6 +379,7 @@
|
|||
84FEB4AB1D19D7F4004727E5 /* Date+Extensions.swift */,
|
||||
84BB45421D6909C700B48537 /* NSMutableDictionary-Extensions.swift */,
|
||||
8414CBA61C95F2EA00333C12 /* Set+Extensions.swift */,
|
||||
84F20F821F16BA6200D8E682 /* PropertyList.swift */,
|
||||
);
|
||||
name = Foundation;
|
||||
path = RSCore;
|
||||
|
@ -686,6 +689,7 @@
|
|||
8432B1861DACA0E90057D6DF /* NSResponder-Extensions.swift in Sources */,
|
||||
849B08981BF7BCE30090CEE4 /* NSPasteboard+RSCore.m in Sources */,
|
||||
842635571D7FA1C800196285 /* NSTableView+Extensions.swift in Sources */,
|
||||
84F20F831F16BA6200D8E682 /* PropertyList.swift in Sources */,
|
||||
84CFF5611AC3D0CE00CEA6C8 /* RSBinaryCache.m in Sources */,
|
||||
84CFF5301AC3CB1900CEA6C8 /* NSDate+RSCore.m in Sources */,
|
||||
84CFF5281AC3C9A200CEA6C8 /* NSArray+RSCore.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// PropertyList.swift
|
||||
// RSCore
|
||||
//
|
||||
// Created by Brent Simmons on 7/12/17.
|
||||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// These functions eat errors.
|
||||
|
||||
public func propertyList(withData data: Data) -> Any? {
|
||||
|
||||
do {
|
||||
return try PropertyListSerialization.propertyList(from: data, options: [], format: nil)
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Create a binary plist.
|
||||
|
||||
public func data(withPropertyList plist: Any) -> Data? {
|
||||
|
||||
do {
|
||||
return try PropertyListSerialization.data(fromPropertyList: plist, format: .binary, options: 0)
|
||||
}
|
||||
catch {
|
||||
return nil
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue