Skip to content

Commit

Permalink
Merge pull request #2 from developersancho/feature/favorite
Browse files Browse the repository at this point in the history
Feature/favorite
  • Loading branch information
developersancho authored Mar 12, 2022
2 parents 815b3c9 + f367ccc commit 2a426dc
Show file tree
Hide file tree
Showing 31 changed files with 798 additions and 95 deletions.
120 changes: 117 additions & 3 deletions SwiftRorty.iOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,53 @@
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "8EECE4D2-439A-4ABF-9FDA-B9B2B9CF196B"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "SwiftRorty.iOS/data/model/dto/CharacterDto.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "3"
endingLineNumber = "3"
landmarkName = "unknown"
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "550CB415-C295-4483-8D3B-6E67B0CC799C"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "SwiftRorty.iOS/presentation/features/characters/CharactersScreen.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "28"
endingLineNumber = "28"
landmarkName = "body"
landmarkType = "24">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "5A5C66BD-1557-48CA-B681-375330B094C9"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "SwiftRorty.iOS/presentation/features/favorites/FavoritesViewModel.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "20"
endingLineNumber = "20"
landmarkName = "loadFavorites()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
1 change: 1 addition & 0 deletions SwiftRorty.iOS/SwiftRorty_iOSApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct SwiftRorty_iOSApp: App {
var body: some Scene {
WindowGroup {
SplashScreen().preferredColorScheme(isDarkMode ? .dark : .light)
.environment(\.locale, .init(identifier: "en"))
}
}
}
30 changes: 30 additions & 0 deletions SwiftRorty.iOS/component/EmptyStateViewModifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// EmptyStateViewModifier.swift
// SwiftRorty.iOS
//
// Created by developersancho on 12.03.2022.
//

import Foundation
import SwiftUI

struct EmptyStateViewModifier<EmptyContent>: ViewModifier where EmptyContent: View {
var isEmpty: Bool
let emptyContent: () -> EmptyContent

func body(content: Content) -> some View {
if isEmpty {
emptyContent()
}
else {
content
}
}
}

extension View {
func emptyState<EmptyContent>(_ isEmpty: Bool,
emptyContent: @escaping () -> EmptyContent) -> some View where EmptyContent: View {
modifier(EmptyStateViewModifier(isEmpty: isEmpty, emptyContent: emptyContent))
}
}
83 changes: 83 additions & 0 deletions SwiftRorty.iOS/core/log/Logger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// Logger.swift
// SwiftRorty.iOS
//
// Created by developersancho on 9.03.2022.
//

import Foundation
import OSLog


import Foundation
import OSLog

public class Log {

/// Show message while debugging
static func debug(category: String = "MyApp", _ message: String) {

Logger.message().debug("[Debug] \(message)")
}

/// Show message as information
static func info(category: String = "MyApp", _ message: String) {

Logger.message().info("[Info] \(message)")
}

/// Show message when a condition may require special handling
static func notice(category: String = "MyApp", _ message: String) {

Logger.message().notice("[Notice] \(message)")
}

/// Show message when a condition requires special handling
static func warning(category: String = "MyApp", _ message: String) {

Logger.message().warning("[Warning] \(message)")
}

/// Show message as error
static func error(category: String = "MyApp", _ message: String) {

Logger.message().error("[Error] \(message)")
}

/// Show message when require immediate attention
static func critical(category: String = "MyApp", _ message: String) {

Logger.message().critical("[Attention] \(message)")
}
}

extension Logger {

private static var bundleIdentifier = Bundle.main.bundleIdentifier!

static func message(_ category: String = "MyApp") -> Logger {

Logger(subsystem: "\(bundleIdentifier)", category: "MyApp")
}

static func retrieveLogs(interval: Double = -86400) throws -> [OSLogEntryLog] {
// Open the log store.
let logStore = try OSLogStore(scope: .currentProcessIdentifier)

// Get all the logs from the last hour.
let oneDayAgo = logStore.position(date: Date().addingTimeInterval(interval))

// Fetch log objects.
let allEntries = try logStore.getEntries(at: oneDayAgo)

// Filter the log to be relevant for our specific subsystem
// and remove other elements (signposts, etc).
return allEntries
.compactMap {
$0 as? OSLogEntryLog
}
.filter {
$0.subsystem == Bundle.main.bundleIdentifier!
}
}
}
83 changes: 83 additions & 0 deletions SwiftRorty.iOS/data/local/CoreDataManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// CoreDataManager.swift
// SwiftRorty.iOS
//
// Created by developersancho on 7.03.2022.
//

import Foundation
import CoreData

class CoreDataManager {
let persistentContainer: NSPersistentContainer

init() {
persistentContainer = NSPersistentContainer(name: "RortyDatabase")
persistentContainer.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Core Data Store Failed \(error.localizedDescription)")
} else {
print("Successfully Loaded Core Data :)")
}
}
}

func getFavoriteList() -> [FavoriteEntity] {
let fetchRequest: NSFetchRequest<FavoriteEntity> = FavoriteEntity.fetchRequest()
do {
return try persistentContainer.viewContext.fetch(fetchRequest)
} catch {
return []
}
}

func getFavorite(id: Int) -> FavoriteEntity? {
let fetchRequest: NSFetchRequest<FavoriteEntity> = FavoriteEntity.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "id = %@", "\(id)")
fetchRequest.fetchLimit = 1

let context = persistentContainer.viewContext

do {
return try context.fetch(fetchRequest).first
} catch {
return nil
}
}

func saveFavorite(id: Int, status: String?, gender: String?, name: String?, imageUrl: String?, species: String?) {
let favorite = FavoriteEntity(context: persistentContainer.viewContext)
favorite.id = Int32(id)
favorite.status = status
favorite.gender = gender
favorite.name = name
favorite.imageUrl = imageUrl
favorite.species = species

do {
try persistentContainer.viewContext.save()
} catch {
print("Failed to save favorite \(error)")
}
}

func deleteFavorite(id: Int) {
let fetchRequest: NSFetchRequest<FavoriteEntity> = FavoriteEntity.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "id = %@", "\(id)")
fetchRequest.includesPropertyValues = false
// Get a reference to a managed object context
let context = persistentContainer.viewContext

do {
let objects = try context.fetch(fetchRequest)
// Delete the objects
for object in objects {
context.delete(object)
}
try context.save()
} catch {
persistentContainer.viewContext.rollback()
print("Failed to save favorite \(error)")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21D62" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="FavoriteEntity" representedClassName="FavoriteEntity" syncable="YES" codeGenerationType="class">
<attribute name="gender" optional="YES" attributeType="String"/>
<attribute name="id" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="imageUrl" optional="YES" attributeType="String"/>
<attribute name="name" optional="YES" attributeType="String"/>
<attribute name="species" optional="YES" attributeType="String"/>
<attribute name="status" optional="YES" attributeType="String"/>
</entity>
<elements>
<element name="FavoriteEntity" positionX="-63" positionY="-18" width="128" height="133"/>
</elements>
</model>
44 changes: 32 additions & 12 deletions SwiftRorty.iOS/data/model/dto/CharacterDto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,39 @@
import Foundation
import UIKit

//struct CharacterDto: Identifiable {
// let created: String?
// let episode: [String]?
// let gender: String?
// let id: Int
// let image: String?
// let location: Location?
// let name: String?
// let origin: Origin?
// let species: String?
// let status: Status?
// let type: String?
// let url: String?
// var isFavorite: Bool = false
//
// static func defaultDto() -> CharacterDto {
// return CharacterDto(created: nil, episode: nil, gender: nil, id: 1, image: nil, location: nil, name: "Rick Sanchez", origin: nil, species: "Human", status: Status.alive, type: nil, url: nil)
// }
//}

struct CharacterDto: Identifiable {
let created: String?
let episode: [String]?
let gender: String?
let id: Int?
let image: String?
let location: Location?
let name: String?
let origin: Origin?
let species: String?
let status: Status?
let type: String?
let url: String?
var created: String? = nil
var episode: [String]? = nil
var gender: String? = nil
var id: Int = 0
var image: String? = nil
var location: Location? = nil
var name: String? = nil
var origin: Origin? = nil
var species: String? = nil
var status: Status? = nil
var type: String? = nil
var url: String? = nil
var isFavorite: Bool = false

static func defaultDto() -> CharacterDto {
Expand Down
8 changes: 7 additions & 1 deletion SwiftRorty.iOS/data/model/dto/DtoExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension CharacterResponse {

extension CharacterInfo {
func toCharacterDto() -> CharacterDto {
return .init(created: created, episode: episode, gender: gender, id: id, image: image, location: location, name: name, origin: origin, species: species, status: status, type: type, url: url)
return .init(created: created, episode: episode, gender: gender, id: id!, image: image, location: location, name: name, origin: origin, species: species, status: status, type: type, url: url)
}
}

Expand All @@ -31,3 +31,9 @@ extension Origin {
return .init(locationId: 0, name: name, url: url)
}
}

extension FavoriteEntity {
func toCharacterDto() -> CharacterDto {
return .init(created: nil, episode: nil, gender: gender, id: Int(id), image: imageUrl, location: nil, name: name, origin: nil, species: species, status: Status.init(rawValue: status!), type: nil, url: nil)
}
}
30 changes: 30 additions & 0 deletions SwiftRorty.iOS/data/repository/FavoriteRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// FavoriteRepository.swift
// SwiftRorty.iOS
//
// Created by developersancho on 9.03.2022.
//

import Foundation
import Resolver

class FavoriteRepository {
@Injected
private var coreDataManager: CoreDataManager

func saveFavorite(id: Int, status: String?, gender: String?, name: String?, imageUrl: String?, species: String?) {
coreDataManager.saveFavorite(id: id, status: status, gender: gender, name: name, imageUrl: imageUrl, species: species)
}

func deleteFavorite(id: Int) {
coreDataManager.deleteFavorite(id: id)
}

func getFavoriteList() -> [FavoriteEntity] {
return coreDataManager.getFavoriteList()
}

func getFavorite(id: Int) -> FavoriteEntity? {
return coreDataManager.getFavorite(id: id)
}
}
Loading

0 comments on commit 2a426dc

Please sign in to comment.