Skip to content

BAEKYUJEONG/ios-wanted-Picterest

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

62 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ“ธ Picterest

๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ ํŒ€์› ์†Œ๊ฐœ

์—๋ฆฌ์–ผ

๐Ÿ–ฅ ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

๋ฉ”์ธ ํ™”๋ฉด์—์„œ ์‚ฌ์ง„์„ ํ™•์ธํ•˜๊ณ , ๋ฉ”๋ชจ์™€ ํ•จ๊ป˜ ์‚ฌ์ง„์„ ์ €์žฅํ•˜๋Š” APP

  • Tab Bar๋ฅผ ์ด์šฉํ•ด ๋ฉ”์ธ ํŽ˜์ด์ง€์™€ ์ €์žฅ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„ API๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ›์•„์™€, ๊ฐ€๋ณ€ ์„ธ๋กœ ๊ธธ์ด์˜ ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • ์›ํ•˜๋Š” ์‚ฌ์ง„์„ ์„ ํƒํ•ด ๋ฉ”๋ชจ์™€ ํ•จ๊ป˜ ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.
  • ๋ณ„ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ €์žฅ์ด ๋˜๊ณ , ๋‹ค์‹œ ๋ฉ”์ธ์—์„œ ์ฑ„์›Œ์ ธ ์žˆ๋Š” ๋ณ„์„ ๋ˆ„๋ฅด๋ฉด ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.
  • ์ €์žฅ๋œ ์‚ฌ์ง„์€ Long Press๋ฅผ ์ด์šฉํ•ด ์‚ฌ์ง„์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โฑ๏ธ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„ ๋ฐ ์‚ฌ์šฉ ๊ธฐ์ˆ 

  • ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„: 2022.07.25 ~ 2022.07.29 (1์ฃผ)
  • ์‚ฌ์šฉ ๊ธฐ์ˆ : UIKit, URLSession, TabBarController, NSCache, CoreData, FileManager, UICollectionViewFlowLayout, MVVM

โœ๏ธ ์ฃผ์š” ๋กœ์ง

FileManager

  • ์‚ฌ์ง„ ์ €์žฅ ์‹œ image data๋ฅผ File Path์— FileManager๋ฅผ ์ด์šฉํ•ด ์ €์žฅ

  • ์‚ฌ์ง„ ์‚ญ์ œ ์‹œ ๊ด€๋ จ ๋ฐ์ดํ„ฐ ์‚ญ์ œ

class PhotoFileManager {
  // ...
    func createPhotoFile(_ image: UIImage, _ fileName: String) -> URL {
        let path = directoryPath.appendingPathComponent(fileName)

        if let data = image.jpegData(compressionQuality: 1) ?? image.pngData() {
            do {
                try data.write(to: path)
            } catch let error {
                print(error.localizedDescription)
            }
        }
        return path
    }
  // ...
}
class PhotoFileManager {
  // ...
    func deletePhotoFile(_ filePath: String) {
        guard let url = URL(string: filePath) else { return }
        
        do {
            try fileManager.removeItem(at: url)
        } catch let error {
            delegate?.fileManager(fileManager, error: FileError.canNotCreateDic, desc: error)
        }
    }
  // ...
}

CoreData

CoreData๋ฅผ ์ด์šฉํ•œ ์‚ฌ์ง„ ์ •๋ณด ์ €์žฅ ๋ฐ ์‚ญ์ œ ๋กœ์ง

class CoreDataManager {
  // ...
    func createSavePhoto(_ id: String, _ memo: String, _ originUrl: String, _ location: String, _ ratio: Double) {
        let entity = NSEntityDescription.entity(forEntityName: "SavePhoto", in: context)

        if let entity = entity {
            let savePhoto = NSManagedObject(entity: entity, insertInto: context)
            savePhoto.setValue(id, forKey: "id")
            savePhoto.setValue(memo, forKey: "memo")
            savePhoto.setValue(originUrl, forKey: "originUrl")
            savePhoto.setValue(location, forKey: "location")
            savePhoto.setValue(ratio, forKey: "ratio")

            saveContext()
        }
    }

  // ...
}
class CoreDataManager {
  // ...
    func deleteSavePhoto(_ entity: SavePhoto) {
        context.delete(entity)
        
        saveContext()
    }
  // ...
}

  • ๋ฉ”์ธ์—์„œ์˜ ์‚ฌ์ง„ ์ €์žฅ, ์‚ญ์ œ
    func savePhoto(_ photoData: Photo, _ memo: String) {
        let id = photoData.id
        let originUrl = photoData.urls.small
        let location = PhotoFileManager.shared.createPhotoFile(loadImage(originUrl), id).absoluteString
        let ratio = photoData.height / photoData.width
        
        CoreDataManager.shared.createSavePhoto(id, memo, originUrl, location, ratio)
    }
    func deletePhoto(_ photoData: Photo) {
        PhotoFileManager.shared.deletePhotoFile(photoData.urls.small)
        guard let entity = CoreDataManager.shared.searchSavePhoto(photoData.id) else { return }
        CoreDataManager.shared.deleteSavePhoto(entity)
    }
  • ์ €์žฅ ํŽ˜์ด์ง€์—์„œ์˜ ์‚ฌ์ง„ ์‚ญ์ œ
    func deleteSavePhoto(_ savePhotoData: SavePhoto) {
        guard let location = savePhotoData.location else { return }
        PhotoFileManager.shared.deletePhotoFile(location)
        CoreDataManager.shared.deleteSavePhoto(savePhotoData)
    }

  • searchSavePhoto ์ด์šฉ

    • Key Value๋ฅผ ์ด์šฉํ•œ Dictionary ํ˜•์‹์œผ๋กœ photoSet ๊ตฌ์„ฑ

    • ์‚ฌ์ง„ ์ €์žฅ ์œ ๋ฌด์— ๋”ฐ๋ฅธ ๋ณ„ ๋ฒ„ํŠผ isSelected ์œ ๋ฌด ์ฒ˜๋ฆฌ

    • ์ €์žฅ๋œ ์‚ฌ์ง„์ผ ๊ฒฝ์šฐ, ์ฐพ์•„์„œ delete ์ฒ˜๋ฆฌ

     func searchSavePhoto(_ id: String) -> SavePhoto? {
        var photoSet: [String: SavePhoto] = [String: SavePhoto]()
        let request: NSFetchRequest<SavePhoto> = SavePhoto.fetchRequest()
        do {
            let photos = try context.fetch(request)
            photos.forEach { savePhoto in
                if let id = savePhoto.id {
                    photoSet[id] = savePhoto
                }
            }
        } catch let error {
            print(error.localizedDescription)
        }
        
        return photoSet[id]
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = imageCollectionView.dequeueReusableCell(cellType: ImageCollectionViewCell.self, indexPath: indexPath)
        
        var isStarButtonSelected: Bool = false
        if CoreDataManager.shared.searchSavePhoto(photoList[indexPath.row].id) != nil {
            isStarButtonSelected = true
        }
      // ...
    }
    func deletePhoto(_ photoData: Photo) {
        PhotoFileManager.shared.deletePhotoFile(photoData.urls.small)
        guard let entity = CoreDataManager.shared.searchSavePhoto(photoData.id) else { return }
        CoreDataManager.shared.deleteSavePhoto(entity)
    }

๐Ÿ“ฑ UI

์‚ฌ์ง„ ๋ฆฌ์ŠคํŠธ ์‚ฌ์ง„ ์ €์žฅ ๋ฐ ๋ฉ”๋ชจ ์ž…๋ ฅ ์‚ฌ์ง„ ์‚ญ์ œ ๋ฉ”์ธ์—์„œ์˜ ์‚ฌ์ง„ ์‚ญ์ œ
Simulator Screen Recording - iPhone 11 - 2022-07-29 at 16 51 22 Simulator Screen Recording - iPhone 11 - 2022-07-29 at 17 12 59 Simulator Screen Recording - iPhone 11 - 2022-07-29 at 17 08 27 Simulator Screen Recording - iPhone 11 - 2022-07-29 at 17 28 19

About

๐Ÿ“ธ Customized Layout Picterest ๐Ÿ“ธ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%