mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Fetch user collections into CoreData and list from ManagedObjectContext
This commit is contained in:
parent
bac7d9bfb0
commit
8e035a43cb
@ -10,7 +10,7 @@ enum PostStatus {
|
|||||||
class Post: Identifiable, ObservableObject, Hashable {
|
class Post: Identifiable, ObservableObject, Hashable {
|
||||||
@Published var wfPost: WFPost
|
@Published var wfPost: WFPost
|
||||||
@Published var status: PostStatus
|
@Published var status: PostStatus
|
||||||
@Published var collection: PostCollection
|
@Published var collection: PostCollection?
|
||||||
@Published var hasNewerRemoteCopy: Bool = false
|
@Published var hasNewerRemoteCopy: Bool = false
|
||||||
|
|
||||||
let id = UUID()
|
let id = UUID()
|
||||||
@ -19,15 +19,15 @@ class Post: Identifiable, ObservableObject, Hashable {
|
|||||||
title: String = "Title",
|
title: String = "Title",
|
||||||
body: String = "Write your post here...",
|
body: String = "Write your post here...",
|
||||||
createdDate: Date = Date(),
|
createdDate: Date = Date(),
|
||||||
status: PostStatus = .local,
|
status: PostStatus = .draft,
|
||||||
collection: PostCollection = draftsCollection
|
collection: PostCollection? = nil
|
||||||
) {
|
) {
|
||||||
self.wfPost = WFPost(body: body, title: title, createdDate: createdDate)
|
self.wfPost = WFPost(body: body, title: title, createdDate: createdDate)
|
||||||
self.status = status
|
self.status = status
|
||||||
self.collection = collection
|
self.collection = collection
|
||||||
}
|
}
|
||||||
|
|
||||||
convenience init(wfPost: WFPost, in collection: PostCollection = draftsCollection) {
|
convenience init(wfPost: WFPost, in collection: PostCollection? = nil) {
|
||||||
self.init(
|
self.init(
|
||||||
title: wfPost.title ?? "",
|
title: wfPost.title ?? "",
|
||||||
body: wfPost.body,
|
body: wfPost.body,
|
||||||
@ -50,6 +50,10 @@ extension Post {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
let userCollection1 = PostCollection(title: "Collection 1")
|
||||||
|
let userCollection2 = PostCollection(title: "Collection 2")
|
||||||
|
let userCollection3 = PostCollection(title: "Collection 3")
|
||||||
|
|
||||||
let testPost = Post(
|
let testPost = Post(
|
||||||
title: "Test Post Title",
|
title: "Test Post Title",
|
||||||
body: """
|
body: """
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import WriteFreely
|
import WriteFreely
|
||||||
|
|
||||||
struct PostCollection: Identifiable {
|
class PostCollection: Identifiable {
|
||||||
let id = UUID()
|
let id = UUID()
|
||||||
let title: String
|
var title: String
|
||||||
var wfCollection: WFCollection?
|
var wfCollection: WFCollection?
|
||||||
|
|
||||||
|
init(title: String) {
|
||||||
|
self.title = title
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PostCollection {
|
extension PostCollection {
|
||||||
@ -12,12 +16,3 @@ extension PostCollection {
|
|||||||
return lhs.id == rhs.id
|
return lhs.id == rhs.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let allPostsCollection = PostCollection(title: "All Posts")
|
|
||||||
let draftsCollection = PostCollection(title: "Drafts")
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
let userCollection1 = PostCollection(title: "Collection 1")
|
|
||||||
let userCollection2 = PostCollection(title: "Collection 2")
|
|
||||||
let userCollection3 = PostCollection(title: "Collection 3")
|
|
||||||
#endif
|
|
||||||
|
@ -8,7 +8,7 @@ class WriteFreelyModel: ObservableObject {
|
|||||||
@Published var account = AccountModel()
|
@Published var account = AccountModel()
|
||||||
@Published var preferences = PreferencesModel()
|
@Published var preferences = PreferencesModel()
|
||||||
@Published var store = PostStore()
|
@Published var store = PostStore()
|
||||||
@Published var collections = CollectionListModel(with: [])
|
@Published var collections = CollectionListModel()
|
||||||
@Published var isLoggingIn: Bool = false
|
@Published var isLoggingIn: Bool = false
|
||||||
@Published var selectedPost: Post?
|
@Published var selectedPost: Post?
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ extension WriteFreelyModel {
|
|||||||
} else {
|
} else {
|
||||||
// This is a new local draft.
|
// This is a new local draft.
|
||||||
loggedInClient.createPost(
|
loggedInClient.createPost(
|
||||||
post: post.wfPost, in: post.collection.wfCollection?.alias, completion: publishHandler
|
post: post.wfPost, in: post.collection?.wfCollection?.alias, completion: publishHandler
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,12 +190,24 @@ private extension WriteFreelyModel {
|
|||||||
let fetchedCollections = try result.get()
|
let fetchedCollections = try result.get()
|
||||||
var fetchedCollectionsArray: [PostCollection] = []
|
var fetchedCollectionsArray: [PostCollection] = []
|
||||||
for fetchedCollection in fetchedCollections {
|
for fetchedCollection in fetchedCollections {
|
||||||
var postCollection = PostCollection(title: fetchedCollection.title)
|
let postCollection = PostCollection(title: fetchedCollection.title)
|
||||||
postCollection.wfCollection = fetchedCollection
|
postCollection.wfCollection = fetchedCollection
|
||||||
fetchedCollectionsArray.append(postCollection)
|
fetchedCollectionsArray.append(postCollection)
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let localCollection = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
localCollection.alias = fetchedCollection.alias
|
||||||
|
localCollection.blogDescription = fetchedCollection.description
|
||||||
|
localCollection.email = fetchedCollection.email
|
||||||
|
localCollection.isPublic = fetchedCollection.isPublic ?? false
|
||||||
|
localCollection.styleSheet = fetchedCollection.styleSheet
|
||||||
|
localCollection.title = fetchedCollection.title
|
||||||
|
localCollection.url = fetchedCollection.url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.collections = CollectionListModel(with: fetchedCollectionsArray)
|
// self.collections = CollectionListModel(with: fetchedCollectionsArray)
|
||||||
|
PersistenceManager().saveContext()
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
print(error)
|
print(error)
|
||||||
@ -209,10 +221,10 @@ private extension WriteFreelyModel {
|
|||||||
for fetchedPost in fetchedPosts {
|
for fetchedPost in fetchedPosts {
|
||||||
var post: Post
|
var post: Post
|
||||||
if let matchingAlias = fetchedPost.collectionAlias {
|
if let matchingAlias = fetchedPost.collectionAlias {
|
||||||
let postCollection = (
|
let postCollection = PostCollection(title: (
|
||||||
collections.userCollections.filter { $0.wfCollection?.alias == matchingAlias }
|
collections.userCollections.filter { $0.alias == matchingAlias }
|
||||||
).first
|
).first?.title ?? "NO TITLE")
|
||||||
post = Post(wfPost: fetchedPost, in: postCollection ?? draftsCollection)
|
post = Post(wfPost: fetchedPost, in: postCollection)
|
||||||
} else {
|
} else {
|
||||||
post = Post(wfPost: fetchedPost)
|
post = Post(wfPost: fetchedPost)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ struct ContentView: View {
|
|||||||
NavigationView {
|
NavigationView {
|
||||||
SidebarView()
|
SidebarView()
|
||||||
|
|
||||||
PostListView(selectedCollection: allPostsCollection)
|
PostListView(selectedCollection: CollectionListModel.allPostsCollection)
|
||||||
|
|
||||||
Text("Select a post, or create a new local draft.")
|
Text("Select a post, or create a new local draft.")
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
@ -18,12 +18,21 @@ struct ContentView: View {
|
|||||||
|
|
||||||
struct ContentView_Previews: PreviewProvider {
|
struct ContentView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
userCollection1.title = "Collection 1"
|
||||||
|
userCollection2.title = "Collection 2"
|
||||||
|
userCollection3.title = "Collection 3"
|
||||||
|
|
||||||
let model = WriteFreelyModel()
|
let model = WriteFreelyModel()
|
||||||
model.collections = CollectionListModel(with: [userCollection1, userCollection2, userCollection3])
|
model.collections = CollectionListModel()
|
||||||
|
|
||||||
for post in testPostData {
|
for post in testPostData {
|
||||||
model.store.add(post)
|
model.store.add(post)
|
||||||
}
|
}
|
||||||
return ContentView()
|
return ContentView()
|
||||||
.environmentObject(model)
|
.environmentObject(model)
|
||||||
|
.environment(\.managedObjectContext, PersistenceManager.persistentContainer.viewContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,18 @@ struct SidebarView: View {
|
|||||||
|
|
||||||
struct SidebarView_Previews: PreviewProvider {
|
struct SidebarView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
userCollection1.title = "Collection 1"
|
||||||
|
userCollection2.title = "Collection 2"
|
||||||
|
userCollection3.title = "Collection 3"
|
||||||
|
|
||||||
let model = WriteFreelyModel()
|
let model = WriteFreelyModel()
|
||||||
model.collections = CollectionListModel(with: [userCollection1, userCollection2, userCollection3])
|
model.collections = CollectionListModel()
|
||||||
|
|
||||||
return SidebarView()
|
return SidebarView()
|
||||||
.environmentObject(model)
|
.environmentObject(model)
|
||||||
|
.environment(\.managedObjectContext, PersistenceManager.persistentContainer.viewContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,14 @@ import AppKit
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PersistenceManager {
|
class PersistenceManager {
|
||||||
let persistentContainer: NSPersistentContainer = {
|
static let persistentContainer: NSPersistentContainer = {
|
||||||
let container = NSPersistentContainer(name: "LocalStorageModel")
|
let container = NSPersistentContainer(name: "LocalStorageModel")
|
||||||
container.loadPersistentStores(completionHandler: { (_, error) in
|
container.loadPersistentStores { _, error in
|
||||||
|
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
||||||
if let error = error {
|
if let error = error {
|
||||||
fatalError("Unresolved error loading persistent store: \(error)")
|
fatalError("Unresolved error loading persistent store: \(error)")
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
return container
|
return container
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -38,9 +39,9 @@ class PersistenceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func saveContext() {
|
func saveContext() {
|
||||||
if persistentContainer.viewContext.hasChanges {
|
if PersistenceManager.persistentContainer.viewContext.hasChanges {
|
||||||
do {
|
do {
|
||||||
try persistentContainer.viewContext.save()
|
try PersistenceManager.persistentContainer.viewContext.save()
|
||||||
} catch {
|
} catch {
|
||||||
print("Error saving context: \(error)")
|
print("Error saving context: \(error)")
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import CoreData
|
||||||
|
|
||||||
class CollectionListModel: ObservableObject {
|
class CollectionListModel: ObservableObject {
|
||||||
private(set) var userCollections: [PostCollection] = []
|
@Published var userCollections = [WFACollection]()
|
||||||
@Published private(set) var collectionsList: [PostCollection] = [ allPostsCollection, draftsCollection ]
|
|
||||||
|
|
||||||
init(with userCollections: [PostCollection]) {
|
static let allPostsCollection = PostCollection(title: "All Posts")
|
||||||
for userCollection in userCollections {
|
static let draftsCollection = PostCollection(title: "Drafts")
|
||||||
self.userCollections.append(userCollection)
|
|
||||||
}
|
init() {
|
||||||
collectionsList.append(contentsOf: self.userCollections)
|
// let request = WFACollection.createFetchRequest()
|
||||||
|
// request.sortDescriptors = []
|
||||||
|
// do {
|
||||||
|
// userCollections = try PersistenceManager.persistentContainer.viewContext.fetch(request)
|
||||||
|
// } catch {
|
||||||
|
// print("Error: Failed to fetch user collections from local store")
|
||||||
|
// userCollections = []
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearUserCollection() {
|
func clearUserCollection() {
|
||||||
userCollections = []
|
userCollections = []
|
||||||
collectionsList = [ allPostsCollection, draftsCollection ]
|
// Clear collections from CoreData store.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,25 @@ import SwiftUI
|
|||||||
|
|
||||||
struct CollectionListView: View {
|
struct CollectionListView: View {
|
||||||
@EnvironmentObject var model: WriteFreelyModel
|
@EnvironmentObject var model: WriteFreelyModel
|
||||||
|
@Environment(\.managedObjectContext) var moc
|
||||||
|
|
||||||
|
@FetchRequest(entity: WFACollection.entity(), sortDescriptors: []) var collections: FetchedResults<WFACollection>
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
ForEach(model.collections.collectionsList) { collection in
|
NavigationLink(destination: PostListView(selectedCollection: CollectionListModel.allPostsCollection)) {
|
||||||
NavigationLink(
|
Text(CollectionListModel.allPostsCollection.title)
|
||||||
destination: PostListView(selectedCollection: collection)
|
}
|
||||||
) {
|
NavigationLink(destination: PostListView(selectedCollection: CollectionListModel.draftsCollection)) {
|
||||||
Text(collection.title)
|
Text(CollectionListModel.draftsCollection.title)
|
||||||
|
}
|
||||||
|
Section(header: Text("Your Blogs")) {
|
||||||
|
ForEach(collections, id: \.alias) { collection in
|
||||||
|
NavigationLink(
|
||||||
|
destination: PostListView(selectedCollection: PostCollection(title: collection.title))
|
||||||
|
) {
|
||||||
|
Text(collection.title)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,10 +30,21 @@ struct CollectionListView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct CollectionSidebar_Previews: PreviewProvider {
|
struct CollectionSidebar_Previews: PreviewProvider {
|
||||||
|
@Environment(\.managedObjectContext) var moc
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext)
|
||||||
|
userCollection1.title = "Collection 1"
|
||||||
|
userCollection2.title = "Collection 2"
|
||||||
|
userCollection3.title = "Collection 3"
|
||||||
|
|
||||||
let model = WriteFreelyModel()
|
let model = WriteFreelyModel()
|
||||||
model.collections = CollectionListModel(with: [userCollection1, userCollection2, userCollection3])
|
model.collections = CollectionListModel()
|
||||||
|
|
||||||
return CollectionListView()
|
return CollectionListView()
|
||||||
.environmentObject(model)
|
.environmentObject(model)
|
||||||
|
.environment(\.managedObjectContext, PersistenceManager.persistentContainer.viewContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,13 +105,15 @@ struct PostListView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func showPosts(for collection: PostCollection) -> [Post] {
|
private func showPosts(for collection: PostCollection) -> [Post] {
|
||||||
if collection == allPostsCollection {
|
var posts: [Post]
|
||||||
return model.store.posts
|
if collection == CollectionListModel.allPostsCollection {
|
||||||
|
posts = model.store.posts
|
||||||
|
} else if collection == CollectionListModel.draftsCollection {
|
||||||
|
posts = model.store.posts.filter { $0.collection == nil }
|
||||||
} else {
|
} else {
|
||||||
return model.store.posts.filter {
|
posts = model.store.posts.filter { $0.collection?.title == collection.title }
|
||||||
$0.collection.title == collection.title
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return posts
|
||||||
}
|
}
|
||||||
|
|
||||||
private func reloadFromServer() {
|
private func reloadFromServer() {
|
||||||
@ -130,7 +132,7 @@ struct PostList_Previews: PreviewProvider {
|
|||||||
model.store.add(post)
|
model.store.add(post)
|
||||||
}
|
}
|
||||||
return Group {
|
return Group {
|
||||||
PostListView(selectedCollection: allPostsCollection)
|
PostListView(selectedCollection: CollectionListModel.allPostsCollection)
|
||||||
.environmentObject(model)
|
.environmentObject(model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ struct WriteFreely_MultiPlatformApp: App {
|
|||||||
WindowGroup {
|
WindowGroup {
|
||||||
ContentView()
|
ContentView()
|
||||||
.environmentObject(model)
|
.environmentObject(model)
|
||||||
|
.environment(\.managedObjectContext, PersistenceManager.persistentContainer.viewContext)
|
||||||
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
|
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import CoreData
|
|||||||
|
|
||||||
extension WFACollection {
|
extension WFACollection {
|
||||||
|
|
||||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<WFACollection> {
|
@nonobjc public class func createFetchRequest() -> NSFetchRequest<WFACollection> {
|
||||||
return NSFetchRequest<WFACollection>(entityName: "WFACollection")
|
return NSFetchRequest<WFACollection>(entityName: "WFACollection")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ extension WFACollection {
|
|||||||
@NSManaged public var email: String?
|
@NSManaged public var email: String?
|
||||||
@NSManaged public var isPublic: Bool
|
@NSManaged public var isPublic: Bool
|
||||||
@NSManaged public var styleSheet: String?
|
@NSManaged public var styleSheet: String?
|
||||||
@NSManaged public var title: String?
|
@NSManaged public var title: String
|
||||||
@NSManaged public var url: String?
|
@NSManaged public var url: String?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user