All Projects → gonzalezreal → NetworkImage

gonzalezreal / NetworkImage

Licence: MIT license
Asynchronous image loading in SwiftUI

Programming Languages

swift
15916 projects
Makefile
30231 projects

Projects that are alternatives of or similar to NetworkImage

SwiftReactor
A protocol which should help structure your data flow in SwiftUI (and UIKit).
Stars: ✭ 57 (+46.15%)
Mutual labels:  combine, swiftui
Surround
A modern iOS app for playing Go on the Online Go Server (OGS)
Stars: ✭ 29 (-25.64%)
Mutual labels:  combine, swiftui
99StocksSwiftUI
SwiftUI app that fetches a list of companies, sort them by their share price and can show its details on a separate view
Stars: ✭ 34 (-12.82%)
Mutual labels:  combine, swiftui
Weather
A simple SwiftUI weather app using MVVM.
Stars: ✭ 23 (-41.03%)
Mutual labels:  combine, swiftui
LongWeekend-iOS
🏖📱 LongWeekend is iOS Application that supports checking long weekends when taking a vacation in Japan
Stars: ✭ 19 (-51.28%)
Mutual labels:  combine, swiftui
Swiftui Tutorials
A code example and translation project of SwiftUI. / 一个 SwiftUI 的示例、翻译的教程项目。
Stars: ✭ 1,992 (+5007.69%)
Mutual labels:  combine, swiftui
JewelCase
This is the source code for JewelCase, a sample app demonstrating how to use SwiftUI and Firebase together. This slide deck discusses the architecture of the app: https://www.slideshare.net/peterfriese/building-swiftui-apps-with-firebase
Stars: ✭ 42 (+7.69%)
Mutual labels:  combine, swiftui
Easify-iOS
An iOS application to test out Spotify API. It uses SwiftUI and Combine.
Stars: ✭ 15 (-61.54%)
Mutual labels:  combine, swiftui
RealmTaskTracker
SwiftUI version of the MongoDB Realm iOS tutorial
Stars: ✭ 24 (-38.46%)
Mutual labels:  combine, swiftui
Simple-Login-iOS
iOS client for SimpleLogin
Stars: ✭ 62 (+58.97%)
Mutual labels:  combine, swiftui
E-Rezept-App-iOS
https://gematik.github.io/E-Rezept-App-iOS/
Stars: ✭ 76 (+94.87%)
Mutual labels:  combine, swiftui
swiftui-mapkit
SwiftUI meets MapKit
Stars: ✭ 17 (-56.41%)
Mutual labels:  combine, swiftui
NetworkAgent
This package is meant to make http request of an easy way inspiren in the architecture of Moya package. This package is 100% free of dependencies and works with Combine api + Codable
Stars: ✭ 16 (-58.97%)
Mutual labels:  combine, swiftui
clouds
🌦 A weather app for iOS, written in SwiftUI.
Stars: ✭ 26 (-33.33%)
Mutual labels:  combine, swiftui
Notflix
📱Netflix like application using SwiftUI and Combine
Stars: ✭ 76 (+94.87%)
Mutual labels:  combine, swiftui
iOS-App
🕹️ iOS application of HardcoreTap game
Stars: ✭ 17 (-56.41%)
Mutual labels:  combine, swiftui
mocka
Mocka — A Mock Server Made for Developers by Developers, made in Swift ❤️
Stars: ✭ 56 (+43.59%)
Mutual labels:  combine, swiftui
GITGET
GitHub의 Contributions를 iOS의 Widget으로 보여주는 App
Stars: ✭ 101 (+158.97%)
Mutual labels:  combine, swiftui
Observable
A generic ObservableObject for every property!
Stars: ✭ 41 (+5.13%)
Mutual labels:  combine, swiftui
CombineUnsplash
A sample project exploring MVVM pattern with SwiftUI/Combine, using Unsplash API (via Picsum.photos API)
Stars: ✭ 25 (-35.9%)
Mutual labels:  combine, swiftui

NetworkImage

CI contact: @gonzalezreal

NetworkImage is a Swift package that provides image downloading, caching, and displaying for your SwiftUI apps. It leverages the foundation URLCache, providing persistent and in-memory caches.

You can explore all the capabilities of this package in the companion demo project.

Supported Platforms

You can use NetworkImage in the following platforms:

  • macOS 11.0+
  • iOS 14.0+
  • tvOS 14.0+
  • watchOS 7.0+

Usage

A network image downloads and displays an image from a given URL; the download is asynchronous, and the result is cached both in disk and memory.

You create a network image, in its simplest form, by providing the image URL.

NetworkImage(url: URL(string: "https://picsum.photos/id/237/300/200"))
  .frame(width: 300, height: 200)

To manipulate the loaded image, use the content parameter.

NetworkImage(url: URL(string: "https://picsum.photos/id/237/300/200")) { image in
  image.resizable().scaledToFill()
}
.frame(width: 150, height: 150)
.clipped()

The view displays a standard placeholder that fills the available space until the image loads. You can specify a custom placeholder by using the placeholder parameter.

NetworkImage(url: URL(string: "https://picsum.photos/id/237/300/200")) { image in
  image.resizable().scaledToFill()
} placeholder: {
  Color.yellow // Shown while the image is loaded or an error occurs
}
.frame(width: 150, height: 150)
.clipped()

It is also possible to specify a custom fallback placeholder that the view will display if there is an error or the URL is nil.

NetworkImage(url: URL(string: "https://picsum.photos/id/237/300/200")) { image in
  image.resizable().scaledToFill()
} placeholder: {
  ProgressView() // Shown while the image is loaded
} fallback: {
  Image(systemName: "photo") // Shown when an error occurs or the URL is nil
}
.frame(width: 150, height: 150)
.clipped()
.background(Color.yellow)

Using NetworkImageLoader

For other use cases outside the scope of SwiftUI, you can download images directly using the shared NetworkImageLoader. In the following example, a view controller downloads an image and applies a transformation to it.

class MyViewController: UIViewController {
    private lazy var imageView = UIImageView()
    private var cancellables: Set<AnyCancellable> = []

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .systemBackground

        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .secondarySystemBackground
        view.addSubview(imageView)

        NSLayoutConstraint.activate([
            imageView.widthAnchor.constraint(equalToConstant: 300),
            imageView.heightAnchor.constraint(equalToConstant: 200),
            imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        ])

        self.view = view
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        NetworkImageLoader.shared.image(for: URL(string: "https://picsum.photos/id/237/300/200")!)
            .map { image in
                // tint the image with a yellow color
                UIGraphicsImageRenderer(size: image.size).image { _ in
                    image.draw(at: .zero)
                    UIColor.systemYellow.setFill()
                    UIRectFillUsingBlendMode(CGRect(origin: .zero, size: image.size), .multiply)
                }
            }
            .replaceError(with: UIImage(systemName: "photo.fill")!)
            .receive(on: DispatchQueue.main)
            .sink(receiveValue: { [imageView] image in
                imageView.image = image
            })
            .store(in: &cancellables)
    }
}

NetworkImage and Testing

NetworkImage is implemented with testing in mind and provides view modifiers to stub image responses. This allows you to write synchronous tests, avoiding the use of expectations or waits. The following example shows how to use this feature with Point-Free's SnapshotTesting library.

final class MyTests: XCTestCase {
    func testImage() {
        let view = NetworkImage(url: URL(string: "https://picsum.photos/id/237/300/200")!)
            .scaledToFill()
            .frame(width: 300, height: 300)
            .clipShape(RoundedRectangle(cornerRadius: 8))
            // Stub a badServerResponse error
            .networkImageLoader(
                .mock(response: Fail(error: URLError(.badServerResponse) as Error))
            )

        assertSnapshot(matching: view, as: .image(layout: .device(config: .iPhoneSe)))
    }
}

Installation

You can add NetworkImage to an Xcode project by adding it as a package dependency.

  1. From the File menu, select Swift Packages › Add Package Dependency…
  2. Enter https://github.com/gonzalezreal/NetworkImage into the package repository URL text field
  3. Link NetworkImage to your application target

Other Libraries

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].