Lightweight and customisable async image loading in SwiftUI. Supports on-disk storage, placeholders and more!

Overview

SwURL

Build Status License: MIT contributions welcome

Asyncrounously download and display images in Swift UI. Supports progress indicators, placeholders and image transitions.

RemoteImageView

Asyncrounously download and display images declaratively. Supports progress indicators, placeholders and image transitions. Flexible caching options.

Flexible caching and image fetching done in background. Currently tested with basic List as seen in Example

This is an evolving project, if you have any ideas or feedback - feel free to create an issue or get in touch.

Fading Transition!

"But, AsyncImage"

It's great that Apple now has official support for async images, however:

Unlike AsyncImage, RemoteImageView

  • Is supported from iOS 13
  • Supports caching (in memory, on disk, and custom)
  • Supports progress indicators (including download fraction) and custom transitions
  • Has in depth, customisable logging

Configuration

Enable or disable debug logging

SwURLDebug.loggingEnabled = true

Choose between global persistent or in-memory (default) caching

SwURL.setImageCache(type: .inMemory)
SwURL.setImageCache(type: .persistent)

... or provide your own caching implementation by using ImageCacheType

SwURL.setImageCache(type: .custom(ImageCacheType))

Usage

RemoteImageView is initialised with a URL, placeholder Image (default nil) and a .custom ImageTransitionType (default .none).

Upon initialisation, a resized image will be downloaded in the background and placeholder displayed as the image is loading, transitioning to the downloaded image when complete.

LandmarkRow is used in a List

Example

struct LandmarkRow: View {
	var landmark: Landmark
	
	var body: some View {
		HStack {
			RemoteImageView(
				url: landmark.imageURL,
				placeholderImage: Image.init("placeholder_avatar"),
				transition: .custom(transition: .opacity, animation: .easeOut(duration: 0.5))
			).imageProcessing({ image in
				return image
					.resizable()
					.renderingMode(.template)
					.aspectRatio(contentMode: .fit)
			}).progress({ progress in    
    				return MyProgressBarView(progress: progress)
			})
			Text(verbatim: landmark.name)
			Spacer()
		}
	}
}

Available Parameters

Name Description Default
url URL of the remote source image. none
placeholderImage (optional)
Image to display whilst remote image data is being fetched and decoded.
nil
transition (optional)
transition to occur when showing the loaded image.
nil

Progress / Loading Indicators

Using function .progress . Display a loading indicator on top of the placeholder as the image loads. Once the image has finished downloading, the supplied loading indicator will hide Call progress on your RemoteImageView and return some View

Example

).progress({ progress in    
    return MyProgressBarView(progress: progress)
})

Image Processing

Using function .imageProcessing . Process your placeholder and loaded images once they've been loaded. Apply resizing, aspect ratio, clipping and more! Call imageProcessing on your RemoteImageView and return some View

Example

).imageProcessing({ image in    
    return image
        .resizable()
        .renderingMode(.template)
        .aspectRatio(contentMode: .fit)
})

This gives you the power to return any View you want. RemoteImageView applies resizable() on all images by default.

Get it

SwURL is available only through Swift Package Manager

  • Open Xcode
  • Go to File > Swift Packages > Add Package Dependency...
  • Paste this Github Repo URL ( https://github.com/cmtrounce/SwURL ) into the search bar.
  • Select the SwURL repo from the search results.
  • Choose the branch/version you want to clone. The most recent release is the most stable but you can choose branches master and develop for the most up to date changes.
  • Confirm and enjoy!

Contact

Join the SwURL Gitter community at https://gitter.im/SwURL-package/community and message me directly. Recommended for quicker response time.

You can also follow/message me on Twitter at https://twitter.com/ctrounce94

Comments
  • Result url not present in handleDownload

    Result url not present in handleDownload

    Here is the view:

    var body: some View { VStack(alignment: .center, spacing: 16, content: { Spacer() HStack { Spacer() RemoteImageView(url: contact.iconUrl(), placeholderImage: Image.init("ministry_logo"), transition: .custom(transition: .opacity, animation: .easeOut(duration: 0.5))).frame(width: 100, height: 100, alignment: .center) Spacer() } }) }

    When enabling logging, this is the message I get: "Result url not present in handleDownload" which obviously is not obvious at all. What I am missing here?

    opened by a-shatou 8
  • Loading 100+ images causes exc_bad_access sometimes

    Loading 100+ images causes exc_bad_access sometimes

    I'm showing 100 + images in a List and sometimes getting this error. What could be the problem? Can you help me please? Tested on simulator iPhone 12 (iOS 14.5) and device iPhone 12 Mini (iOS 14.6).

    Screen Shot 2021-07-29 at 11 35 30

    image

    Code is similar to this format

    List{
                    ForEach((0..<500), id: \.self) {
                      index in
                      HStack{
                        RemoteImageView(url: URL(string:"https://picsum.photos/200/300")!)
                        RemoteImageView(url: URL(string:"https://picsum.photos/200/300")!)
    
                      }
    
                    }
                  }
    
    bug resolved 
    opened by ozgurshn 3
  • tvOS support proposal

    tvOS support proposal

    Hi. I tried your library for a tvOS + SwiftUI project i was working on. It works (did not install it through the SPM, as tvOS is not a supported platform), but the ImageLoader causes a crash, because it wants to use the userDirectory which does not exist on tvOS. So I changed it to the caches directory. What i propose is to use the userDirectory if you are on iOS, and the cachesDirectory when you are on tvOS.

    • added tvOS as a suported platform
    • changed what folder to use in case of tvOS for the ImageLoader, since there is no user directory on tvOS.
    opened by narciszait 2
  • Crash in RemoteImage.swift

    Crash in RemoteImage.swift

    I've got around 100 crashed last week on: Fatal error: Attempted to read an unowned reference but object 0x281a63d90 was already deallocated2019-09-09 12:53:13.434243+0300[14534:1447031] Fatal error: Attempted to read an unowned reference but object on 34 String in RemoteImage.string crash

    resolved 
    opened by Exey 2
  • Image not displaying correctly inside a Navigation item

    Image not displaying correctly inside a Navigation item

    If you use the image inside a navigation item it displays as a blue rectangle. The following modifier is required on the image to prevent this issue .renderingMode(.original),

    An example is shown below

    TransitioningImage.init(placeholder: placeholderImage?.resizable().renderingMode(.original), finalImage: remoteImage.load(url: url).image?.resizable().renderingMode(.original), transitionType: transitionType) }

    resolved 
    opened by peter-w-williams 2
  • Image not loading on beta 5

    Image not loading on beta 5

    Hi,

    here's pretty much how I use your lib: https://gist.github.com/benclanet/a5a02e613c344d0af888859c42a16001

    What happens is a blank view. When I activate the logs, I do see Image successfully retrieved from url:...

    Any idea what could be wrong?

    Thank you!

    opened by benclanet 2
  • Problem of : Argument labels '(_:)' do not match any available overloads

    Problem of : Argument labels '(_:)' do not match any available overloads

    Hello ! I just installed the library and created an image but i received this error : Argument labels '(_:)' do not match any available overloads This is my code :

    import SwiftUI
    import SwURL
    
    struct ContentView: View {
        var body: some View {
            VStack {
                Text("Hello World")
                RemoteImageView(url: URL("https://placeholder.com/150")) // the error appears here
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    
    opened by NoobiCodi 1
  • Persistent storage restricted to URL lastPathComponent only

    Persistent storage restricted to URL lastPathComponent only

    Hi,

    Thanks for the project. this is not a bug but since i have the same name of images from the network from difference server locations, persistent storage seems to show the same image over. If there can be a way to specify the directory also, it would be helpful.

    Like in the file Cache ->PersistentImageCache.swift

       private extension PersistentImageCache {  
           func storageURL(for imageURL: URL) throws -> URL {
               return FileManager
                   .cachesDir()
                   .appendingPathComponent(imageURL.lastPathComponent)
           }
       }
    

    to include the directory component also from the URL.

    opened by husninazer 0
  • copy task within run loop of delegate method

    copy task within run loop of delegate method

    The delegate method urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) requires that the file be copied before the end of the method is reached. The file at the given location URL is deleted immediately after. Therefore an async execution of the task change does not copy the file in time leading to empty files.

    opened by Ryce 0
  • RemoteImageView Bug in 0.4.1

    RemoteImageView Bug in 0.4.1

    When attempting to use RemoteImageView with 0.4.1 I got the following error, “Static method 'buildBlock' requires that 'SwURL' conform to 'View'”. When I changed to 0.4.0 the error message went away.

    opened by ddunne6 3
  • Prefetch images?

    Prefetch images?

    It’s often the case that in the case of a long list we want to start pre-fetching images so users don’t have to see the placeholder view. It would be great to have an imperative way to do that and cache them to the configured cache.

    enhancement 
    opened by nmn 1
Releases(0.4.1)
  • 0.4.1(Aug 18, 2021)

    • Added internal support and usage for StateObject for iOS 14.
    • Provides backwards compatibility to iOS13.
    • Improves thread safety in downloader.
    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Sep 28, 2020)

    This release allows you to add support for loading indicators. The README has been updated with the required functionality. Some redundant code has been cleaned / removed.

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Jul 26, 2020)

    This release has some enhancements and some breaking changes.

    • Network requests and loading from cache are now always performed on a background thread.
    • Image Processing: You can now apply modifiers to the images before they are presented via imageProcessing(_ :)
    • Improved debugging messages.
    • Further performance improvements and implementation tweaks.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.3(Apr 14, 2020)

    • Network request is now deferred, so now additional network requests will only be made if they are needed.
    • Added tvOS support.
    • Groundwork laid for progress indicator.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Aug 14, 2019)

Owner
Callum Trounce
London-based iOS developer
Callum Trounce
Async image downloader with Mem&Disk cached as a UIImageView extension

HBWebImage Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements Installation HBWebIm

haoboxuxu 1 Oct 22, 2022
🚀SwiftUI Image downloader with performant LRU mem/disk cache.

Progressive concurrent image downloader for SwiftUI, with neat API and performant LRU mem/disk cache.

Cheng Zhang 42 Sep 24, 2022
AYImageKit is a Swift Library for Async Image Downloading, Show Name's Initials and Can View image in Separate Screen.

AYImageKit AYImageKit is a Swift Library for Async Image Downloading. Features Async Image Downloading. Can Show Text Initials. Can have Custom Styles

Adnan Yousaf 11 Jan 10, 2022
Twitter Image Pipeline is a robust and performant image loading and caching framework for iOS clients

Twitter Image Pipeline (a.k.a. TIP) Background The Twitter Image Pipeline is a streamlined framework for fetching and storing images in an application

Twitter 1.8k Dec 17, 2022
📦 An extension that generates letter-based avatars/placeholders

LetterAvatarKit LetterAvatarKit provides an UIImage extension for generating letter-based avatars/placeholders. There are a few images showing what yo

Victor Peschenkov 215 Dec 21, 2022
AsyncImage before iOS 15. Lightweight, pure SwiftUI Image view, that displays an image downloaded from URL, with auxiliary views and local cache.

URLImage URLImage is a SwiftUI view that displays an image downloaded from provided URL. URLImage manages downloading remote image and caching it loca

Dmytro Anokhin 1k Jan 4, 2023
SwiftUI view that download and display image from URL and displaying Activity Indicator while loading .

ViewWithActivityIndicator ViewWithActivityIndicator is a SwiftUI view that download and display image from URL and displaying Activity Indicator while

Ali Adam 28 Feb 3, 2022
SwiftUI Image loading and Animation framework powered by SDWebImage

SDWebImageSwiftUI What's for SDWebImageSwiftUI is a SwiftUI image loading framework, which based on SDWebImage. It brings all your favorite features f

null 1.6k Jan 6, 2023
Lazy image loading for SwiftUI

A missing piece in SwiftUI that provides lazy image loading.

Alexander Grebenyuk 9 Dec 26, 2022
A pure Swift high-performance asynchronous image loading framework. SwiftUI supported.

Longinus Longinus is a pure-Swift high-performance asynchronous web image loading,caching,editing framework. It was learned from Objective-C web image

Qitao Yang 290 Dec 17, 2022
EbImagesSwiftUI - SDWebImageSwiftUI - a SwiftUI image loading framework, which based on SDWebImage

SDWebImageSwiftUI What's for SDWebImageSwiftUI is a SwiftUI image loading framew

An Tran 1 Jan 6, 2022
SwiftUI project to show ActivityIndicator above Image while loading

ImageWithActivityIndicatorDemo SwiftUI project to show ActivityIndicator above Image while loading ImageWithActivityIndicatorDemo is a demo app that s

Ali Adam 4 May 27, 2021
DGImageView - Asynchronous image downloader with cache. Supports gif too

DGImageView Installation Usage DGImageView Asynchronous image downloader with cache. Supports gif, memory cache, disk cache features. Installation Xco

donggyu 1 Jan 1, 2022
Image loading system

Image Loading System Nuke ILS provides an efficient way to download and display images in your app. It's easy to learn and use thanks to a clear and c

Alexander Grebenyuk 7k Dec 31, 2022
Asynchronous image loading framework.

YYWebImage YYWebImage is an asynchronous image loading framework (a component of YYKit). It was created as an improved replacement for SDWebImage, PIN

null 3.5k Dec 27, 2022
LCWebImage - An asynchronous image loading framework based on AFNetworking.

LCWebImage is an asynchronous image loading framework based on AFNetworking, which supports memory and disk caching, and provides functions such as custom caching, custom image decoding, and custom network configuration.

LiuChang 27 Jul 23, 2022
Photo Browser / Viewer inspired by Facebook's and Tweetbot's with ARC support, swipe-to-dismiss, image progress and more

IDMPhotoBrowser IDMPhotoBrowser is a new implementation based on MWPhotoBrowser. We've added both user experience and technical features inspired by F

Thiago Peres 2.7k Dec 21, 2022
TripUp is an open source, photo storage and sharing app made for privacy conscious users.

TripUp is an open source, photo storage and sharing app made for privacy conscious users.

TripUp 19 Aug 26, 2022
🖼 Gallery App for Actomaton (async/await + Elm Architecture) + SwiftUI.

?? Actomaton-Gallery Gallery App for Actomaton (async/await + Elm Architecture) + SwiftUI. NOTE: Most of the code are reused from Harvest-SwiftUI-Gall

Yasuhiro Inami 44 Dec 20, 2022