Skip to content

EmojiArt. A multi-platform app based on Stanford's CS193p course on SwiftUI (Spring 2021)

Notifications You must be signed in to change notification settings

vveidi/emoji-art

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EmojiArt 🎨

A multi-platform app based on Stanford's CS193p course on SwiftUI (Spring 2021)

About the App

Drag various backgrounds and emojis on to the canvas to create artworks. Available on three platforms: iPad, iPhone and Mac.

Technologies

  • Swift
  • SwiftUI
  • MVVM
  • SwiftUI's integration with UIKit
  • Multiplatform: iPhone, iPad, Mac
  • Gestures
  • Drag&Drop
  • UndoManager
  • URLSession and Combine
  • GCD

Screenshots

document-view image-picker palette-manager
main-screen-editor main-screen

Sample Code

class EmojiArtDocument: ReferenceFileDocument
{
    static var readableContentTypes = [UTType.emojiart]
    static var writeableContentTypes = [UTType.emojiart]
    
    required init(configuration: ReadConfiguration) throws {
        if let data = configuration.file.regularFileContents {
            emojiArt = try EmojiArtModel(json: data)
            fetchBackgroundImageDataIfNecessary()
        } else {
            throw CocoaError(.fileReadCorruptFile)
        }
    }
    
    func snapshot(contentType: UTType) throws -> Data {
        return try emojiArt.json()
    }
    
    func fileWrapper(snapshot: Data, configuration: WriteConfiguration) throws -> FileWrapper {
        FileWrapper(regularFileWithContents: snapshot)
    }
    
    @Published private(set) var emojiArt: EmojiArtModel {
        didSet {
            if emojiArt.background != oldValue.background {
                fetchBackgroundImageDataIfNecessary()
            }
        }
    }
    
    init() {
        emojiArt = EmojiArtModel()
    }
    
    var emojis: [EmojiArtModel.Emoji] { emojiArt.emojis }
    var background: EmojiArtModel.Background { emojiArt.background }
    
    @Published var backgroundImage: UIImage?
    @Published var backgroundImageFetchStatus = BackgroundImageFetchStatus.idle
    
    enum BackgroundImageFetchStatus: Equatable {
        case idle
        case fetching
        case failed(URL)
    }
    
    private var backgroundImageFetchCancellable: AnyCancellable?
    
    private func fetchBackgroundImageDataIfNecessary() {
        backgroundImage = nil
        switch emojiArt.background {
        case .url(let url):
            // fetch the url
            backgroundImageFetchStatus = .fetching
            backgroundImageFetchCancellable?.cancel()
            let session = URLSession.shared
            let publisher = session.dataTaskPublisher(for: url)
                .map { (data, urlResponse) in UIImage(data: data) }
                .replaceError(with: nil)
                .receive(on: DispatchQueue.main)
            backgroundImageFetchCancellable = publisher
                .sink { [weak self] image in
                    self?.backgroundImage = image
                    self?.backgroundImageFetchStatus = (image != nil) ? .idle : .failed(url)
                }
        case .imageData(let data):
            backgroundImage = UIImage(data: data)
        case .blank:
            break
        }
    }
}

Credits

About

EmojiArt. A multi-platform app based on Stanford's CS193p course on SwiftUI (Spring 2021)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages