Giter Site home page Giter Site logo

alamofireimage's Introduction

AlamofireImage

Build Status CocoaPods Compatible Carthage Compatible Platform Twitter Gitter

AlamofireImage is an image component library for Alamofire.

Features

  • Image Response Serializers
  • UIImage Extensions for Inflation / Scaling / Rounding / CoreImage
  • Single and Multi-Pass Image Filters
  • Auto-Purging In-Memory Image Cache
  • Prioritized Queue Order Image Downloading
  • Authentication with URLCredential
  • UIImageView Async Remote Downloads with Placeholders
  • UIImageView Filters and Transitions
  • Comprehensive Test Coverage
  • Complete Documentation

Requirements

  • iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ / vision OS 1.0+
  • Xcode 13+
  • Swift 5.5+

Migration Guides

Dependencies

Communication

  • If you need to find or understand an API, check our documentation.
  • If you need help with an AlamofireImage feature, use our forum on swift.org.
  • If you'd like to discuss AlamofireImage best practices, use our forum on swift.org.
  • If you'd like to discuss a feature request, use our forum on swift.org.
  • If you found a bug, open an issue and follow the guide. The more detail the better!
  • If you want to contribute, submit a pull request.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate AlamofireImage into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'AlamofireImage', '~> 4.3'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate AlamofireImage into your Xcode project using Carthage, specify it in your Cartfile:

github "Alamofire/AlamofireImage" ~> 4.3

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler. It is in early development, but AlamofireImage does support its use on supported platforms.

Once you have your Swift package set up, adding AlamofireImage as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [
    .package(url: "https://github.com/Alamofire/AlamofireImage.git", .upToNextMajor(from: "4.3.0"))
]

Manually

If you prefer not to use either of the aforementioned dependency managers, you can integrate AlamofireImage into your project manually.

Embedded Framework

  • Open up Terminal, cd into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
$ git init
  • Add AlamofireImage as a git submodule by running the following command:
$ git submodule add https://github.com/Alamofire/AlamofireImage.git
  • Open the new AlamofireImage folder, and drag the AlamofireImage.xcodeproj into the Project Navigator of your application's Xcode project.

    It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.

  • Select the AlamofireImage.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.

  • Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.

  • In the tab bar at the top of that window, open the "General" panel.

  • Click on the + button under the "Embedded Binaries" section.

  • You will see two different AlamofireImage.xcodeproj folders each with two different versions of the AlamofireImage.framework nested inside a Products folder.

    It does not matter which Products folder you choose from, but it does matter whether you choose the top or bottom AlamofireImage.framework.

  • Select the top AlamofireImage.framework for iOS and the bottom one for OS X.

    You can verify which one you selected by inspecting the build log for your project. The build target for AlamofireImage will be listed as either AlamofireImage iOS, AlamofireImage macOS, AlamofireImage tvOS or AlamofireImage watchOS.

  • And that's it!

    The AlamofireImage.framework is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.


Usage

Image Response Serializers

import Alamofire
import AlamofireImage

AF.request("https://httpbin.org/image/png").responseImage { response in
  debugPrint(response)

  print(response.request)
  print(response.response)
  debugPrint(response.result)

  if case .success(let image) = response.result {
    print("image downloaded: \(image)")
  }
}

The AlamofireImage response image serializers support a wide range of image types including:

  • application/octet-stream - As a fallback for things like AWS which provide no real type.
  • image/avif - On 2022 OS versions and later, except watchOS.
  • image/bmp
  • image/gif
  • image/heic, image/heif - On 2017 OS versions and later.
  • image/ico
  • image/jp2
  • image/jpeg
  • image/jpg
  • image/jxl - On 2023 OS versions and later.
  • image/png
  • image/tiff
  • image/webp - On 2020 OS versions and later, except tvOS and watchOS.
  • image/x-bmp
  • image/x-icon
  • image/x-ms-bmp
  • image/x-win-bitmap
  • image/x-xbitmap

If the image you are attempting to download is an invalid MIME type not in the list, you can add custom acceptable content types using the addAcceptableImageContentTypes extension on the DataRequest type.

UIImage Extensions

There are several UIImage extensions designed to make the common image manipulation operations as simple as possible.

Inflation

let url = Bundle.main.url(forResource: "unicorn", withExtension: "png")!
let data = try! Data(contentsOf: url)
let image = UIImage(data: data, scale: UIScreen.main.scale)!

image.af.inflate()

Inflating compressed image formats (such as PNG or JPEG) in a background queue can significantly improve drawing performance on the main thread.

Scaling

let image = UIImage(named: "unicorn")!
let size = CGSize(width: 100.0, height: 100.0)

// Scale image to size disregarding aspect ratio
let scaledImage = image.af.imageScaled(to: size)

// Scale image to fit within specified size while maintaining aspect ratio
let aspectScaledToFitImage = image.af.imageAspectScaled(toFit: size)

// Scale image to fill specified size while maintaining aspect ratio
let aspectScaledToFillImage = image.af.imageAspectScaled(toFill: size)

Rounded Corners

let image = UIImage(named: "unicorn")!
let radius: CGFloat = 20.0

let roundedImage = image.af.imageRounded(withCornerRadius: radius)
let circularImage = image.af.imageRoundedIntoCircle()

Core Image Filters

let image = UIImage(named: "unicorn")!

let sepiaImage = image.af.imageFiltered(withCoreImageFilter: "CISepiaTone")

let blurredImage = image.af.imageFiltered(
    withCoreImageFilter: "CIGaussianBlur",
    parameters: ["inputRadius": 25]
)

Image Filters

The ImageFilter protocol was designed to make it easy to apply a filter operation and cache the result after an image finished downloading. It defines two properties to facilitate this functionality.

public protocol ImageFilter {
    var filter: Image -> Image { get }
    var identifier: String { get }
}

The filter closure contains the operation used to create a modified version of the specified image. The identifier property is a string used to uniquely identify the filter operation. This is useful when adding filtered versions of an image to a cache. All identifier properties inside AlamofireImage are implemented using protocol extensions.

Single Pass

The single pass image filters only perform a single operation on the specified image.

let image = UIImage(named: "unicorn")!
let imageFilter = RoundedCornersFilter(radius: 10.0)

let roundedImage = imageFilter.filter(image)

The current list of single pass image filters includes:

  • ScaledToSizeFilter - Scales an image to a specified size.
  • AspectScaledToFitSizeFilter - Scales an image from the center while maintaining the aspect ratio to fit within a specified size.
  • AspectScaledToFillSizeFilter - Scales an image from the center while maintaining the aspect ratio to fill a specified size. Any pixels that fall outside the specified size are clipped.
  • RoundedCornersFilter - Rounds the corners of an image to the specified radius.
  • CircleFilter - Rounds the corners of an image into a circle.
  • BlurFilter - Blurs an image using a CIGaussianBlur filter with the specified blur radius.

Each image filter is built ontop of the UIImage extensions.

Multi-Pass

The multi-pass image filters perform multiple operations on the specified image.

let image = UIImage(named: "avatar")!
let size = CGSize(width: 100.0, height: 100.0)
let imageFilter = AspectScaledToFillSizeCircleFilter(size: size)

let avatarImage = imageFilter.filter(image)

The current list of multi-pass image filters includes:

  • ScaledToSizeWithRoundedCornersFilter - Scales an image to a specified size, then rounds the corners to the specified radius.
  • AspectScaledToFillSizeWithRoundedCornersFilter - Scales an image from the center while maintaining the aspect ratio to fit within a specified size, then rounds the corners to the specified radius.
  • ScaledToSizeCircleFilter - Scales an image to a specified size, then rounds the corners into a circle.
  • AspectScaledToFillSizeCircleFilter - Scales an image from the center while maintaining the aspect ratio to fit within a specified size, then rounds the corners into a circle.

Image Cache

Image caching can become complicated when it comes to network images. URLCache is quite powerful and does a great job reasoning through the various cache policies and Cache-Control headers. However, it is not equipped to handle caching multiple modified versions of those images.

For example, let's say you need to download an album of images. Your app needs to display both the thumbnail version as well as the full size version at various times. Due to performance issues, you want to scale down the thumbnails to a reasonable size before rendering them on-screen. You also need to apply a global CoreImage filter to the full size images when displayed. While URLCache can easily handle storing the original downloaded image, it cannot store these different variants. What you really need is another caching layer designed to handle these different variants.

let imageCache = AutoPurgingImageCache(
    memoryCapacity: 100_000_000,
    preferredMemoryUsageAfterPurge: 60_000_000
)

The AutoPurgingImageCache in AlamofireImage fills the role of that additional caching layer. It is an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated.

Add / Remove / Fetch Images

Interacting with the ImageCache protocol APIs is very straightforward.

let imageCache = AutoPurgingImageCache()
let avatarImage = UIImage(data: data)!

// Add
imageCache.add(avatarImage, withIdentifier: "avatar")

// Fetch
let cachedAvatar = imageCache.image(withIdentifier: "avatar")

// Remove
imageCache.removeImage(withIdentifier: "avatar")

URL Requests

The ImageRequestCache protocol extends the ImageCache protocol by adding support for URLRequest caching. This allows a URLRequest and an additional identifier to generate the unique identifier for the image in the cache.

let imageCache = AutoPurgingImageCache()

let urlRequest = URLRequest(url: URL(string: "https://httpbin.org/image/png")!)
let avatarImage = UIImage(named: "avatar")!.af.imageRoundedIntoCircle()

// Add
imageCache.add(avatarImage, for: urlRequest, withIdentifier: "circle")

// Fetch
let cachedAvatarImage = imageCache.image(for: urlRequest, withIdentifier: "circle")

// Remove
imageCache.removeImage(for: urlRequest, withIdentifier: "circle")

Auto-Purging

Each time an image is fetched from the cache, the cache internally updates the last access date for that image.

let avatar = imageCache.image(withIdentifier: "avatar")
let circularAvatar = imageCache.image(for: urlRequest, withIdentifier: "circle")

By updating the last access date for each image, the image cache can make more informed decisions about which images to purge when the memory capacity is reached. The AutoPurgingImageCache automatically evicts images from the cache in order from oldest last access date to newest until the memory capacity drops below the preferredMemoryCapacityAfterPurge.

It is important to set reasonable default values for the memoryCapacity and preferredMemoryCapacityAfterPurge when you are initializing your image cache. By default, the memoryCapacity equals 100 MB and the preferredMemoryCapacityAfterPurge equals 60 MB.

Memory Warnings

The AutoPurgingImageCache also listens for memory warnings from your application and will purge all images from the cache if a memory warning is observed.

Image Downloader

The ImageDownloader class is responsible for downloading images in parallel on a prioritized queue. It uses an internal Alamofire SessionManager instance to handle all the downloading and response image serialization. By default, the initialization of an ImageDownloader uses a default URLSessionConfiguration with the most common parameter values.

let imageDownloader = ImageDownloader(
    configuration: ImageDownloader.defaultURLSessionConfiguration(),
    downloadPrioritization: .fifo,
    maximumActiveDownloads: 4,
    imageCache: AutoPurgingImageCache()
)

If you need to customize the URLSessionConfiguration type or parameters, then simply provide your own rather than using the default.

Downloading an Image

let downloader = ImageDownloader()
let urlRequest = URLRequest(url: URL(string: "https://httpbin.org/image/jpeg")!)

downloader.download(urlRequest) { response in
    print(response.request)
    print(response.response)
    debugPrint(response.result)

    if case .success(let image) = response.result {
        print(image)
    }
}

Make sure to keep a strong reference to the ImageDownloader instance, otherwise the completion closure will not be called because the downloader reference will go out of scope before the completion closure can be called.

Applying an ImageFilter

let downloader = ImageDownloader()
let urlRequest = URLRequest(url: URL(string: "https://httpbin.org/image/jpeg")!)
let filter = AspectScaledToFillSizeCircleFilter(size: CGSize(width: 100.0, height: 100.0))

downloader.download(urlRequest, filter: filter) { response in
    print(response.request)
    print(response.response)
    debugPrint(response.result)

    if case .success(let image) = response.result {
        print(image)
    }
}

Authentication

If your images are behind HTTP Basic Auth, you can append the user:password: or the credential to the ImageDownloader instance. The credentials will be applied to all future download requests.

let downloader = ImageDownloader()
downloader.addAuthentication(user: "username", password: "password")

Download Prioritization

The ImageDownloader maintains an internal queue of pending download requests. Depending on your situation, you may want incoming downloads to be inserted at the front or the back of the queue. The DownloadPrioritization enumeration allows you to specify which behavior you would prefer.

public enum DownloadPrioritization {
    case fifo, lifo
}

The ImageDownloader is initialized with a .fifo queue by default.

Image Caching

The ImageDownloader uses a combination of an URLCache and AutoPurgingImageCache to create a very robust, high performance image caching system.

URLCache

The URLCache is used to cache all the original image content downloaded from the server. By default, it is initialized with a memory capacity of 20 MB and a disk capacity of 150 MB. This allows up to 150 MB of original image data to be stored on disk at any given time. While these defaults have been carefully set, it is very important to consider your application's needs and performance requirements and whether these values are right for you.

If you wish to disable this caching layer, create a custom URLSessionConfiguration with the urlCache property set to nil and use that configuration when initializing the ImageDownloader.

Image Cache

The ImageCache is used to cache all the potentially filtered image content after it has been downloaded from the server. This allows multiple variants of the same image to also be cached, rather than having to re-apply the image filters to the original image each time it is required. By default, an AutoPurgingImageCache is initialized with a memory capacity of 100 MB and a preferred memory usage after purge limit of 60 MB. This allows up to 100 MB of most recently accessed filtered image content to be stored in-memory at a given time.

Setting Ideal Capacity Limits

Determining the ideal the in-memory and on-disk capacity limits of the URLCache and AutoPurgingImageCache requires a bit of forethought. You must carefully consider your application's needs, and tailor the limits accordingly. By default, the combination of caches offers the following storage capacities:

  • 150 MB of on-disk storage (original image only)
  • 20 MB of in-memory original image data storage (original image only)
  • 100 MB of in-memory storage of filtered image content (filtered image if using filters, otherwise original image)
  • 60 MB preferred memory capacity after purge of filtered image content

If you do not use image filters, it is advised to set the memory capacity of the URLCache to zero. Otherwise, you will be storing the original image data in both the URLCache's in-memory store as well as the AlamofireImage in-memory store.

Duplicate Downloads

Sometimes application logic can end up attempting to download an image more than once before the initial download request is complete. Most often, this results in the image being downloaded more than once. AlamofireImage handles this case elegantly by merging the duplicate downloads. The image will only be downloaded once, yet both completion handlers will be called.

Image Filter Reuse

In addition to merging duplicate downloads, AlamofireImage can also merge duplicate image filters. If two image filters with the same identifier are attached to the same download, the image filter is only executed once and both completion handlers are called with the same resulting image. This can save large amounts of time and resources for computationally expensive filters such as ones leveraging CoreImage.

Request Receipts

Sometimes it is necessary to cancel an image download for various reasons. AlamofireImage can intelligently handle cancellation logic in the ImageDownloader by leveraging the RequestReceipt type along with the cancelRequestForRequestReceipt method. Each download request vends a RequestReceipt which can be later used to cancel the request.

By cancelling the request through the ImageDownloader using the RequestReceipt, AlamofireImage is able to determine how to best handle the cancellation. The cancelled download will always receive a cancellation error, while duplicate downloads are allowed to complete. If the download is already active, it is allowed to complete even though the completion handler will be called with a cancellation error. This greatly improves performance of table and collection views displaying large amounts of images.

It is NOT recommended to directly call cancel on the request in the RequestReceipt. Doing so can lead to issues such as duplicate downloads never being allowed to complete.

UIImageView Extension

The UIImage Extensions, Image Filters, Image Cache and Image Downloader were all designed to be flexible and standalone, yet also to provide the foundation of the UIImageView extension. Due to the powerful support of these classes, protocols and extensions, the UIImageView APIs are concise, easy to use and contain a large amount of functionality.

Setting Image with URL

Setting the image with a URL will asynchronously download the image and set it once the request is finished.

let imageView = UIImageView(frame: frame)
let url = URL(string: "https://httpbin.org/image/png")!

imageView.af.setImage(withURL: url)

If the image is cached locally, the image is set immediately.

Placeholder Images

By specifying a placeholder image, the image view uses the placeholder image until the remote image is downloaded.

let imageView = UIImageView(frame: frame)
let url = URL(string: "https://httpbin.org/image/png")!
let placeholderImage = UIImage(named: "placeholder")!

imageView.af.setImage(withURL: url, placeholderImage: placeholderImage)

If the remote image is cached locally, the placeholder image is never set.

Image Filters

If an image filter is specified, it is applied asynchronously after the remote image is downloaded. Once the filter execution is complete, the resulting image is set on the image view.

let imageView = UIImageView(frame: frame)

let url = URL(string: "https://httpbin.org/image/png")!
let placeholderImage = UIImage(named: "placeholder")!

let filter = AspectScaledToFillSizeWithRoundedCornersFilter(
    size: imageView.frame.size,
    radius: 20.0
)

imageView.af.setImage(
    withURL: url,
    placeholderImage: placeholderImage,
    filter: filter
)

If the remote image with the applied filter is cached locally, the image is set immediately.

Image Transitions

By default, there is no image transition animation when setting the image on the image view. If you wish to add a cross dissolve or flip-from-bottom animation, then specify an ImageTransition with the preferred duration.

let imageView = UIImageView(frame: frame)

let url = URL(string: "https://httpbin.org/image/png")!
let placeholderImage = UIImage(named: "placeholder")!

let filter = AspectScaledToFillSizeWithRoundedCornersFilter(
    size: imageView.frame.size,
    radius: 20.0
)

imageView.af.setImage(
    withURL: url,
    placeholderImage: placeholderImage,
    filter: filter,
    imageTransition: .crossDissolve(0.2)
)

If the remote image is cached locally, the image transition is ignored.

Image Downloader

The UIImageView extension is powered by the default ImageDownloader instance. To customize cache capacities, download priorities, request cache policies, timeout durations, etc., please refer to the Image Downloader documentation.

Authentication

If an image requires and authentication credential from the UIImageView extension, it can be provided as follows:

ImageDownloader.default.addAuthentication(user: "user", password: "password")

Credits

Alamofire is owned and maintained by the Alamofire Software Foundation. You can follow them on Twitter at @AlamofireSF for project updates and releases.

Security Disclosure

If you believe you have identified a security vulnerability with AlamofireImage, you should report it as soon as possible via email to [email protected]. Please do not post it to a public issue tracker.

Donations

The ASF is looking to raise money to officially stay registered as a federal non-profit organization. Registering will allow us members to gain some legal protections and also allow us to put donations to use, tax free. Donating to the ASF will enable us to:

  • Pay our yearly legal fees to keep the non-profit in good status
  • Pay for our mail servers to help us stay on top of all questions and security issues
  • Potentially fund test servers to make it easier for us to test the edge cases
  • Potentially fund developers to work on one of our projects full-time

The community adoption of the ASF libraries has been amazing. We are greatly humbled by your enthusiasm around the projects, and want to continue to do everything we can to move the needle forward. With your continued support, the ASF will be able to improve its reach and also provide better legal safety for the core members. If you use any of our libraries for work, see if your employers would be interested in donating. Any amount you can donate today to help us reach our goal would be greatly appreciated.

paypal

License

AlamofireImage is released under the MIT license. See LICENSE for details.

alamofireimage's People

Contributors

alexanderedge avatar arsonik avatar banannzza avatar baza207 avatar bradleybernard avatar brandenr avatar cnoon avatar cschep avatar djk12587 avatar erulezz avatar fsaint avatar graphiclife avatar hybridcattt avatar ishaq avatar jarrodrobins avatar jksy avatar jorjuela33 avatar jrgoodle avatar jshier avatar justinjiadev avatar kcharwood avatar kimdv avatar klaas avatar kylef avatar larsacus avatar lickel avatar mathiasnagler avatar natecook1000 avatar slaunchaman avatar xsdlr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alamofireimage's Issues

on disk caching weird behavior

Hello, I just encountered an issue will using the pod. First of all, some images are fetched then written to disk at the correct path which is {app_identifier}/com.alamofire.imagedownloader/NsCachedData which is perfect as these images are not even downloaded again when the app is in offline mode. But the issue is that sometimes images are written to {app_identifier}/NsCachedData which I believe is the path for NSURLCache.sharedURLCache and not the path specified in the cache used by alamofireImage so these images are not seen by ImageDownloader and are re downloaded if they are not found in-memory. Also sometimes images are not even written to the disk which is weird.

All these Images where fetched using the same method with the same approach tried removing their filters and nothing happened still the same behavior. I used ImageDownloader.defaultInstance.downloadImage method to fetch these Images.

Any help will be appreciated, thanks In advance!

Framework not safe for use in app extensions

I'm looking at using AlamofireImage in an app that I'm building though when I link against it in an application extension I get the warning "Linking against dylib not safe for use in application extensions".

Is that something which has been done on purpose?

Happy to provide a pull request if required.

Thanks,
Matt.

Cannot load images from file URL

Hi there,

Firstly, fantastic work so far, I'm really looking forward to working with AlamofireImage and contributing where I can.

I've noticed that loading from an image file to a UIImageView from the application bundle (and, presumably, a location on disk) doesn't work. I haven't yet had time to look into why, but I thought I should bring it to your attention.

An example file URL:

file:///Users/alexanderedge/Library/Developer/CoreSimulator/Devices/B0CBC833-1F6C-4099-9B19-258DFE22AC89/data/Containers/Bundle/Application/388B99E5-E443-4C87-A22B-EB41BC192044/MyApp.app/image_06.1.png

An example call:

imageView.af_setImageWithURL(NSBundle.mainBundle().URLForResource(name: "image_06.1", withExtension: "png"))

Feature request: Image download progress information

As stated in this Stack Overflow question, I'd like to show some kind of progress indicator when downloading images in lists (tableviews…) or in —big— image viewers. I know I can achieve this by using regular Alamofire.request + responseImage but I'd like to keep things simple and make use of the UIImageView Extension and the extra features it provides (cache, filters…).

I'm currently working on an app that shows a news feed view controller which shows one highlighted news with a big photo followed by a list of "smaller" views with their own smaller photos. Each news detail view controller shows a gallery of related photos (1 to 50 or even more) and when the user taps one of them we load the big version of the photo in a custom photo viewer.

It'd nice to show some kind of progress indicator to the user. Or perhaps I'm mistaken and its better to use the image-placeholder-only approach followed by the current implementation of AlamofireImage.

Either way, thank you for your hard work ;-)

ImageView on TableViewCell changes size on tap or reload of cell

I'm trying to set the image view on a UITableViewCell subclass using the helper with a placeholder.

It works fine, and when the image is loaded the placeholder is replaced with the correct image. However, upon tapping on the cell (or forcing the cell to reload by scrolling it out of view and then bringing it back in) the image view snaps to a smaller version of the image.

self.imageView?.af_setImageWithURL(categoryImageUrl, placeholderImage: UIImage(named: "DefaultCategory"))

For example, here is how the cell appears after the initial load:

image

Then, once the cell has been tapped/reloaded it appears as this:

image

How can I have the image set at the right size initially, or prevent a resize from occurring upon reload?

On disk cache instead of in memory cache

I'm wondering if it would be at all possible to create an on disk cache rather than an in memory cache for handling images.

The use case I'm thinking of is small custom images (emoji) that don't change regularly but are often used throughout an app.

What would be the best approach of extending the current image caching to allow for an on disk cache?

Effect applying callback

I'm getting remotely displaying pretty large images on the screen (tvOS) - about 1920x1080.
The downloading process is pretty seamless (around 1 sec), but when I'm trying to apply a filter on top of it (BlurFilter in my case), the time to actually display image on the screen multiplies by a factor of 6! And thats just on my mac. On actual Apple TV this will probably be longer. Well, I could just block the screen at this point and display a spinner, but is there a way to know when the filter is actually applied and the image is presented on the screen?

Default closure based ImageFilter struct

I think many people will like to create filters on the fly with something like that:

let filter = ImageFilter("MyFilter") { image in
    // Do something the image
   return image.someTransformation()
}

It would be really convenient in some cases to avoid creating many files for isolated cases. In this example, the filter would have "MyFilter" as its identifier. (I don't think we can automatically generate a same unique identifier for this on-the-fly filter every time it is created / copied)

This would require to rename the protocol ImageFilter into ImageFilterType.


The same could be applied to (to be announced) CompositeImageFilter type. It could be created with a variadic array of ImageFilterType or a variadic array of Image -> Image closures / functions.

let composite = CompositeImageFilter(filters: SizeToFillFilter(size: size), CircleFilter(), BlackAndWhiteFilter())

CompositeImageFilter protocol would be renamed CompositeImageFilterType.

AspectScaledToFillSizeFilter

Hi,

im getting a little problem with AspectScaledToFillSizeFilter.

when i use this

cell.eventImageView!.image = image!.af_imageAspectScaledToFillSize(cell.eventImageView!.bounds.size)

i get a result that next what i want.

but when i use

let imgFilter = AspectScaledToFillSizeFilter(size: cell.eventImageView!.bounds.size)
cell.eventImageView!.af_setImageWithURL(NSURL(string: url!)!, placeholderImage: nil, filter: imgFilter, imageTransition: UIImageView.ImageTransition.CrossDissolve(0.5))

i get a different thing. Looks like that my filter is not being applied to my UIImageView.

Does anyone know about it?

UICollectionView multiple cells and images

I am downloading multiple images in UICollectionView. There are about 30 cells on the screen.
When I scroll to down and scroll to top back all images look like downloading again. They are slowly loading one by one.

Also I am getting this warning.

[/BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreUI/CoreUI-371.4/Bom/Storage/BOMStorage.c:522] <memory> is not a BOMStorage file.

My Code:
In UICollectionViewCell

func loadImage(urlString: String) {
    CircleImageView.af_setImageWithURL(NSURL(string: urlString)!, 
     placeholderImage: UIImage(named: "holderImage"), 
     filter: CircleFilter())
}

What am I missing?

Note: I am using different Image/Cache library and it's working without any of these things.

Thanks

Image does not load after being cancelled and instantly reloaded

imageView.af_setImageWithURL(url)
imageView.af_cancelImageRequest()
imageView.af_setImageWithURL(url)

The real world case we were having was:

  1. in a collectionview, a cell calls af_setImageWithURL.
  2. The collectionview is reloaded, then in the prepareForReuse() the request is cancelled.
  3. If the same cell makes the same image url request the image does not load

Testing on iOS 8 & iOS 9 this fails on simulator and device

how to queue image using Alamofire.request

Hello i ' am new in swift.My problem is.i already set an array for a image request around 5 url. Then the result of responseImage is not in order as in earlier array. Please help me to figure out the solution to produce result in order.
Thank You

Bump to use Alamofire 3.0.0

@cnoon Now that Alamofire 3.0.0 has been released, would you please push a new version of this library that has a dependency on the stable release?

Thanks!

Downloading doesn't work via ImageDownloader

let downloader = ImageDownloader()
let URLRequest = NSURLRequest(URL: NSURL(string: "https://httpbin.org/image/jpeg")!)

downloader.downloadImage(URLRequest: URLRequest) { response in
    if let image = response.result.value {
        print(image)
    }
}

The completion block isn't even called. Using Alamofire image response serializer works fine.

Issue with Umlaut within the URL

Hi guys

I ran into a strange issue.

If I have a URL with a Umlaut in it e.g.

http://upload.wikimedia.org/wikipedia/commons/a/a9/Rösti_mit_Bratwurst.jpg

I'll get following error message

fatal error: unexpectedly found nil while unwrapping an Optional value

If a try it with a URL without an Umlaut everything works as expected.

Strange right? :)

2 phase image download

Hi, I have an idea for feature.

Some content driven apps use two phase image download. It download super small image preview first and then it request large full res image.

So the flow is:

  1. show placeholder image
  2. show blurred low res preview (is purged from memory as soon as full res is available)
  3. show cached full res image

Low res previews have slightly higher priority for download queue.

It would be super nice to have such feature build right in ImageDownloader.

Cheers and best wishes, Vlad

UIImageView extensions do not work sometimes for URL's that redirect

Xcode: 7.0
AlamofireImage: 1.1.0

Current around line 324 of UIImageView+AlamofireImage.swift there is this block of code:

                guard let
                    currentRequest = strongSelf.af_activeRequest?.task.currentRequest
                    where currentRequest.URLString == request?.URLString else
                {
                    return
                }

Trying to figure out why facebook profile photos don't load such as https://graph.facebook.com/v2.4/529271840955/picture?type=large turns out this check returns because of a 3XX that then results in a different URL.

Would it be worth generated a UUID rather than using the image url or some way of keeping track of the redirects?

Xcode complains that watchOS framework was built for iOS when installed through Carthage

I get this error when I try to add the 2 frameworks(Alamofire & AlamofireImage) to my WatchKit Extension target.

It actually does not matter from which platform Build folder I will add the frameworks. It always shows the same error.

d: building for watchOS simulator, but linking against dylib built for iOS, file '/Some-Project-Filder/Carthage/Build/iOS/AlamofireImage.framework/AlamofireImage' for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Bug with AlamoFireImage

myProg(63494,0xb029b000) malloc: *** error for object 0x79b5ce80: double free
*** set a breakpoint in malloc_error_break to debug

screen shot 2016-01-22 at 4 25 25 am

Composite filters

Hi,

First of all, thank you so much for such a good framework! I've been waiting for something like this for a very long time :-))))

That being said, I really like the filters, but I think we could make "compound" filters based on an (sorted) array of other filters.
For instance:

let filters = [AspectScaledToFillSizeFilter(size: someSize), BlurFilter(blurRadius: 20)]
let compoundFilter = CompoundFilter(filters: filters) // Or using variadic args ?

would create a filter that would first scale to fill, then apply a blur to the scaled image.

Classes such as AspectScaledToFillSizeWithRoundedCornersFilter could then themselves also be compound filters.

What do you think about it?

Cheers.

Image Inflate code between AFNetworking & AlamofireImage

The AFNetworking version is AFInflatedImageFromResponseWithDataAtScale which has nearly 90 lines code.

But AlamofireImage's is just
CGDataProviderCopyData(CGImageGetDataProvider(CGImage))

I wonder

  1. why the difference?
  2. a copy without CGDataProviderRelease is fine?

Installing and building from Carthage fails on the watchOS scheme

I am setting up my Cartfile as explained in the readme file and I get this console output when running "carthage update".


*** Fetching AlamofireImage
*** Fetching SDWebImage
*** Fetching Alamofire
*** Checking out Alamofire at "3.1.4"
*** Checking out AlamofireImage at "2.2.0"
*** Checking out SDWebImage at "3.7.3"
*** xcodebuild output can be found in /var/folders/pr/vgdvxhm93yjbq8_9w4p2q_z80000gn/T/carthage-xcodebuild.bnxNOt.log
*** Building scheme "Alamofire OSX" in Alamofire.xcworkspace
*** Building scheme "Alamofire watchOS" in Alamofire.xcworkspace
** BUILD FAILED **

The following build commands failed:
Check dependencies
(1 failure)
A shell task failed with exit code 65:
** BUILD FAILED **

The following build commands failed:
Check dependencies
(1 failure)

How to make perfect code for image caching from url[For Beginner Code Help]

I know its sounds like crazy.But,for a beginner like me,the documentation seems a little confuse.
So,If I can let me request a help from you because I want to use your library instead of KingFisher.
First of all,I have realm database which i used to store notification information.Every time the notifications comes in,it include data and 2 image url,

What i did in my program was,I insert every notifications that comes in at realm database and get all the data and then show at table cell.When each table cell is tapped,the detail goes on.

So,there will be one image at table view which will be max 50 records [1 image for each row] and,two images will be showed at the detail view when user tapped one of table view cell.

For,the table view which have 50 records max(let assume 10 notifications comes in)
How to download the 10 images asynchronously and cache and show the user?Even the user remove the app from app switcher and open again,the image should be still remain without needing to re-download again

This is the code that I applied at my table view (cellForRowAtIndexPath) for one notification only.

        let URL = NSURL(string: notification.image1)! // notification is realm object,there was image 1 & 2
       // image1 for list view and,both for detail view when user tapped on each record.
        let placeholderImage = UIImage(named: "Notification_PlaceHolder")!

        cell.notificationImageView.af_setImageWithURL(
            URL,
            placeholderImage: placeholderImage,
            imageTransition: .CrossDissolve(0.5)
        )

Any help please?

Store images on disk

Hey!

I have an idea for a feature.

Some apps store images in the disk and i could work following

1: The app check if the image is stored on the disk
2: If the image is stored on the disk, i should load it

  • If it's not stored i download the image.

It would be a sweet ass feature for AlamofireImage :o)

Cheers
// Kim

Image is never set when af_setImageWithURL is called 2 times in a row

I've noticed that images are never set if I call af_setImageWithURL several times.
The following (test) code will always result in only the placeholder image being set.

imageView.af_setImageWithURL(imageURL, placeholderImage: placeholder, filter: AspectScaledToFillSizeFilter(size: imageView.bounds.size))
imageView.af_setImageWithURL(imageURL, placeholderImage: placeholder, filter: AspectScaledToFillSizeFilter(size: imageView.bounds.size))

The first request seems to be successfully cancelled (I get a cancelled error if I set the completion block).

Cheers.

Support for AlamoFire 3.0

I was trying to update to AlamoFire 3.0 today, but I rely on this library as well. Thanks for the great work! Is there a plan to update the library?

Failed image load in cell reuse other cell's image

I was testing my comments' tableview listing with a user that has a broken image in the cell (Failed to load resource: the server responded with a status of 403), and when I was scrolling, the user with the broken image was assigned with another user's image in the listing. This does not happen when there's no 403 error on any image. I was previously using HanekeSwift and this was not happening, and none of my code has change.

I'm using vanilla UIImageView extension:

cell.pictureImageView.af_setImageWithURL(NSURL(string: urlString)!, imageTransition: .CrossDissolve(0.2))

This is nothing major, but wondering if it's fixable, either on my side or on AlamofireImage's side.

Thanks!

identify if a placeholder image is used

We are using af_setImageWithURLRequest to display a profile picture. Sometimes users don't have a profile picture so we use a placeholderimage instead. Is there a way to identify if the placeholderimage is used or not. Basically I want to set a UI action on profile pictures only but not placeholder images.

Image fails to load after device locked

When I lock my device (iPhone 6 iOS 9.0.2, AlamofireImage 2.0.0), I noticed that the first time I call af_setImageWithURL on a UIImageView the first image consistently does not load (if the image is not already cached). I believe this is due to Alamofire/Alamofire#872.

I was able to workaround the issue with the following code (which I'm not suggesting as a fix but I think shows it's the same underlying issue as Alamofire/Alamofire#872):

func applicationWillEnterForeground(application: UIApplication) {
    UIImageView.af_sharedImageDownloader = ImageDownloader()
}

Add "image/jpg" to the list of acceptableContentTypes

I'm not sure why it isn't already in the list but please add "image/jpg" here:

`private class func validateResponse(response: NSHTTPURLResponse?) -> Bool {

    let acceptableContentTypes: Set<String> = [
        "image/tiff",
        "image/jpeg",
        "image/gif",
        "image/png",
        "image/ico",
        "image/x-icon",
        "image/bmp",
        "image/x-bmp",
        "image/x-xbitmap",
        "image/x-win-bitmap"
    ]`

It's in Request+AlamofireImage.swift.

"image/jpg" is a valid content type and behaves identically to "image/jpeg".

Thanks.

WebP support

Are there any ideas/plans/thoughts around image/webp support? Would be awesome

Request: Optional URL/URL Request parameters

Could we make the URL/URL Request parameters optional on the setImageWith... methods?

I know this seems like it doesn't make sense at first, but I have a use case.

I'm using this library with a UImageView contained inside a UITableViewCell. My image url property on my model object is an optional, and if I don't have an image url to display, I'd like to display the placeholder image. In this case, if I have to do the following currently:

func setImageFromModel(modelObject: MyModel) { 
    guard let imageURL = modelObject.primaryImageURL else {
      imageView.image = modelObject.placeholderImage
      return
    }

    imageView.af_setImageWithURL(imageURL,
      placeholderImage: post.primaryImagePlaceholderImage,
      filter: nil,
      imageTransition: .CrossDissolve(0.2),
      completion: nil)
}

If the URL parameter was optional, this could be done just the one method call.

I'd be happy to make a PR, but I wanted to get input from @cnoon on this before I started.

Scale filter makes the image as red with the "color blended layers" option

Hi !

First, thank you for this great library, I really appreciate its design.

I noticed that when I'm using a scaling method of AlamofireImage (e.g. af_imageAspectScaledToFillSize), I see its container (basic UIImageView) as red in the "color blended layers". But if I'm using my "own", then the color is green.

I'm putting below the code I used to create the image/imageView (nothing special):

// instanciate image view
let imageView = UIImageView()
imageView.frame = CGRectMake(10.0, 10.0, 50.0, 50.0)
self.view.addSubview(imageView)

// add image
if let image = UIImage(named: "image-test")?.af_imageAspectScaledToFillSize(CGSizeMake(50.0, 50.0)) {
    image.af_inflate()
    imageView.image = image
}

I'm not sure if it's a big performance issue or not.
The resizing code I'm using is from this blog, which I converted to Swift.

1/ Do you want an Xcode project to reproduce the issue?
2/ Do you think it would be worth updating the scaling method? I could manage a pull-request if you want.

Notes: Xcode 7.2, iOS 9.2

Cheers,
Vincent

af_setImageWithURL doesn't use acceptableImageContentTypes and fails to load binary/octet-stream

This fixes the issue by replacing "Images/*" as the only acceptable to using the list of acceptable content types

// MARK: - Private - URL Request Helper Methods

private func URLRequestWithURL(URL: NSURL) -> NSURLRequest {
    let mutableURLRequest = NSMutableURLRequest(URL: URL)
    for mimeType in Request.acceptableImageContentTypes {
        mutableURLRequest.addValue(mimeType, forHTTPHeaderField: "Accept")
    }

    return mutableURLRequest
}

Crash at method imageAspectScaledToFillSize

Hi Alamofire team, I've tested my app on a iPhone 4S, 5, 5S and works fine. But when I test on a 6 or 6S, this happens:

unexpectedly found nil while unwrapping an Optional value

captura de tela 2015-11-25 as 14 36 24

I'm using the filter to create the rounded borders at the image, I`m using the version 2.1.1 and Swift 2.0.

var filter : ImageFilter? = nil

    ...

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! Cell
    let object = (self.objects?.objectAtIndex(indexPath.row))! as! Object

    cell.title.text = object.title

    if self.filter == nil {
      self.filter = AspectScaledToFillSizeWithRoundedCornersFilter(
      size: cell.image.frame.size, radius: 5.0)
    }
   ImageHelper.loadImage(cell.image, object: object, filter: filter, .None)
   return cell
}

The method to load the image is:

class func loadImage(imageView: UIImageView, object : Object, filter: ImageFilter?, imageTransition: UIImageView.ImageTransition) {

    let stringUrl = createURLImage(object)

    if let url = NSURL(string: stringUrl) {
      imageView.af_setImageWithURL(
        url,
        placeholderImage: UIImage(named: "app_logo"),
        filter: filter,
        imageTransition: imageTransition)
    }
}

Is it a bug? If I comment the code, it works fine.

Feature request: force image transition if image is cached

In the readme for this project, there's the line -

If the remote image is cached locally, the image transition is ignored.

This makes perfect sense in most cases. However, I have a use case where I would like to force the transition to be invoked - for cross dissolving a background image that may already have been downloaded elsewhere in the app.

Can I suggest some sort of override that we can use to ensure that the animation is not ignored if the image is in a cache?

I'm happy to create a pull request myself but I'd like others to agree on the implementation first.

The easiest solution would be to just add an extra optional parameter to af_setImageWithURLRequest.

Thoughts?

Need API to set inflateResponseImage to false

Hi. I noticed the line 'CGDataProviderCopyData(CGImageGetDataProvider(CGImage))' of function af_inflate uses a lot of memory especially when I load a large image on a cell (like 3000x3000 and file size is 2MB) and then scroll the pages quickly. This blows up the memory usage and crashes my app

Disabling the inflation works for me

How to set image and cache it?

I don't understand why the function imageView.af_setImageWithURL(URL) is not caching the results automatically or why there are no such option?

How to implement this? I tried to get cache and via fetch method to load image, but this don't work.

UInt64 cannot be negative

In ImageCache.swift

                let bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge

This sentence may EXC_BREAKPOINT, because self.currentMemoryUsage may less then self.preferredMemoryUsageAfterPurge.

and bytesToPruge is UInt64 type inference by Swift.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.