use coredata for newsletter emails

This commit is contained in:
Satindar Dhillon 2022-04-18 15:56:12 -07:00
parent 905e628e5a
commit 05d4107fa9
6 changed files with 80 additions and 16 deletions

View file

@ -97,7 +97,7 @@ struct NewsletterEmailsView: View {
Snackbar.show(message: "Email copied")
},
label: { Text(newsletterEmail.email) }
label: { Text(newsletterEmail.unwrappedEmail) }
)
}
}

View file

@ -1,5 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21A559" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="NewsletterEmail" representedClassName="NewsletterEmail" syncable="YES" codeGenerationType="class">
<attribute name="confirmationCode" optional="YES" attributeType="String"/>
<attribute name="email" attributeType="String"/>
<attribute name="emailId" attributeType="String"/>
<uniquenessConstraints>
<uniquenessConstraint>
<constraint value="emailId"/>
</uniquenessConstraint>
</uniquenessConstraints>
</entity>
<entity name="PersistedArticleContent" representedClassName="PersistedArticleContent" syncable="YES" codeGenerationType="class">
<attribute name="htmlContent" attributeType="String"/>
<attribute name="slug" attributeType="String"/>
@ -81,5 +91,6 @@
<element name="PersistedFeedItemLabel" positionX="-36" positionY="18" width="128" height="104"/>
<element name="PersistedHighlight" positionX="27" positionY="225" width="128" height="209"/>
<element name="Viewer" positionX="45" positionY="234" width="128" height="89"/>
<element name="NewsletterEmail" positionX="0" positionY="180" width="128" height="74"/>
</elements>
</model>

View file

@ -1,14 +1,11 @@
import Foundation
public struct NewsletterEmail: Identifiable {
public let id = UUID()
public let emailId: String
public let email: String
public let confirmationCode: String?
public extension NewsletterEmail {
var unwrappedEmailId: String {
emailId ?? ""
}
public init(emailId: String, email: String, confirmationCode: String?) {
self.emailId = emailId
self.email = email
self.confirmationCode = confirmationCode
var unwrappedEmail: String {
email ?? ""
}
}

View file

@ -1,4 +1,5 @@
import Combine
import CoreData
import Foundation
import Models
import SwiftGraphQL
@ -6,7 +7,7 @@ import SwiftGraphQL
public extension DataService {
func createNewsletterEmailPublisher() -> AnyPublisher<NewsletterEmail, BasicError> {
enum MutationResult {
case saved(newsletterEmail: NewsletterEmail)
case saved(newsletterEmail: InternalNewsletterEmail)
case error(errorCode: Enums.CreateNewsletterEmailErrorCode)
}
@ -14,7 +15,7 @@ public extension DataService {
try $0.on(
createNewsletterEmailSuccess: .init {
.saved(newsletterEmail: try $0.newsletterEmail(selection: Selection.NewsletterEmail {
NewsletterEmail(
InternalNewsletterEmail(
emailId: try $0.id(),
email: try $0.address(),
confirmationCode: try $0.confirmationCode()
@ -44,7 +45,11 @@ public extension DataService {
switch payload.data {
case let .saved(newsletterEmail: newsletterEmail):
promise(.success(newsletterEmail))
if let newsletterEmailObject = newsletterEmail.persist(context: self.persistentContainer.viewContext) {
promise(.success(newsletterEmailObject))
} else {
promise(.failure(.message(messageText: "coredata error")))
}
case let .error(errorCode: errorCode):
promise(.failure(.message(messageText: errorCode.rawValue)))
}

View file

@ -6,12 +6,12 @@ import SwiftGraphQL
public extension DataService {
func newsletterEmailsPublisher() -> AnyPublisher<[NewsletterEmail], ServerError> {
enum QueryResult {
case success(result: [NewsletterEmail])
case success(result: [InternalNewsletterEmail])
case error(error: String)
}
let newsletterEmailSelection = Selection.NewsletterEmail {
NewsletterEmail(
InternalNewsletterEmail(
emailId: try $0.id(),
email: try $0.address(),
confirmationCode: try $0.confirmationCode()
@ -43,7 +43,11 @@ public extension DataService {
case let .success(payload):
switch payload.data {
case let .success(result: result):
promise(.success(result))
if let newsletterEmailObject = result.persist(context: self.persistentContainer.viewContext) {
promise(.success(newsletterEmailObject))
} else {
promise(.failure(.unknown))
}
case .error:
promise(.failure(.unknown))
}

View file

@ -0,0 +1,47 @@
import CoreData
import Foundation
import Models
struct InternalNewsletterEmail {
let emailId: String
let email: String
let confirmationCode: String?
func persist(context: NSManagedObjectContext) -> NewsletterEmail? {
let newsletterEmail = asManagedObject(inContext: context)
do {
try context.save()
DataService.logger.debug("NewsletterEmail saved succesfully")
return newsletterEmail
} catch {
context.rollback()
DataService.logger.debug("Failed to save NewsletterEmail: \(error.localizedDescription)")
return nil
}
}
func asManagedObject(inContext context: NSManagedObjectContext) -> NewsletterEmail {
let newsletterEmail = NewsletterEmail(context: context)
newsletterEmail.emailId = emailId
newsletterEmail.email = email
newsletterEmail.confirmationCode = confirmationCode
return newsletterEmail
}
}
extension Sequence where Element == InternalNewsletterEmail {
func persist(context: NSManagedObjectContext) -> [NewsletterEmail]? {
let newsletterEmails = map { $0.asManagedObject(inContext: context) }
do {
try context.save()
DataService.logger.debug("NewsletterEmail saved succesfully")
return newsletterEmails
} catch {
context.rollback()
DataService.logger.debug("Failed to save NewsletterEmail: \(error.localizedDescription)")
return nil
}
}
}