Document version: 2.9.2
Last updated: 04/27/2018
Author: Nolan O'Brien
- Add
TIPRenderImage
util function - Add
tip_imageWithRenderFormattings:render:
method toUIImage+TIPAdditions
- Use modern
UIGraphicsImageRenderer
always when scaling images on iOS 10+- source the
UIGraphicsImageRendererFormat
from the image being scaled, this is optimal - roughly 10% speed boost
- add GraphicsRendererSpeed project that validates the perf differences
- source the
- Add P3 color gamut support
- Image scaling preserves P3 (on device's with P3 screens) now
- Add functions to check if a screen supports P3
- Add category property to UIImage to check if image has P3 colorspace
- Persist source image dimensions for Rendered Cache
- this provides more context about the source image, such as knowing if the displayed image was scaled up or scaled down
- also added new "RMem" value when showing info with debug info feature on
TIPImageViewFetchHelper
- improve
TIPImageViewFetchHelper
when reloading an image after a new "matching" image was cached (such as a larger resolution)
- Move
TIPImageViewFetchHelper
from usingUIImageView
instances directly to usingUIView
withTIPImageFetchable
protocol- makes it possible for
UIView
subclasses to support the fetch helper, likeUIButton
or a custom view
- makes it possible for
- improve
TIPImageFetchTransformer
support with optional identifier- was easy to get the rendered cache images mixed up between transformed and non-transformed fetches
- now, transform requests can only fetch images from the rendered cache if there is a match with the
tip_tranformerIdentifier
- transformers that don't provide an identifier cannot be cached nor retrieved from the rendered cache
- removed transformer from
TIPGlobalConfiguration
(would interfere with above improvement)
- add generic concrete class for
TIPImageFetchRequest
as convenience- generic fetch request is mutable/immutable pair:
TIPGenericImageFetchRequest
andTIPMutableGenericImageFetchRequest
- generic fetch request is mutable/immutable pair:
- add decoder config support
- enables custom TIPImageDecoder implementations to have configurable ways of being decoded
- add memory map loading option for images
- default continues to not use memory map loading, but it's now exposed on TIPImageContainer
- add MP4 decoder to TIP (as an extended decoder, not bundled by default)
- decodes MP4s as animated images
- Remove
TIPImageView
, just useUIImageView
category instead- Add
hidden
property support toUIImageView
fetch helper category
- Add
- Remove
TIPImageViewFetchHelper
subclassing event methods- Use delegate pattern for eventing instead of polymorphism #Simplify
- Remove
setViewHidden:
method forTIPImageViewFetchHelper
- It never did what it was advertised to do and muddied the control flow
- Add
fetchResultDimensions
toTIPImageViewFetchHelper
for more insight into results
- Remove detached downloads support for TIP image fetches
- using HTTP/2 is the ideal solution, removing the complexity to remove the crutch
- reduce thread count for TIP by unifying all disk caches to using 1 manifest queue
- make disk cache manifest load async instead of sync now that it is shared
- no real speed improvements, just fewer threads need to be used in multi-pipeline apps
- clean up some large inline functions to be regular functions
- Fix WebP Encoder (channels could be mixed up)
- Update WebP codec to v0.6.0
- Add support for changing a cached image's identifier
- Add category to
UIImageView
for setting aTIPImageViewFetchHelper
- offers convenience of TIP work encapsulated in
TIPImageViewFetchHelper
without needing to refactor ontoTIPImageView
- offers convenience of TIP work encapsulated in
- Add image transform support to TIP
- A
TIPImageFetchTransform
can be set globally or on a specific request - Clean up some nullability notation
- Update ImageSpeedComparison sample app
- add WebP
- add more bitrates
- add optional blur transform (for progress)
- add smaller PJPEG
- Reduce memory pressure w/
@autoreleasepool
blocks on GCD queues in TIP - Add "problem" for images not caching because they are too large
- Add "problem" when downloaded image cannot be decoded
- Add Animated PNG support (iOS 8+)
- Add the store operation as an argument to
TIPImagePipelineStoreCompletionBlock
- Tightened up some threading race conditions that cropped up with the thread sanitizer
- Fix decoder bug on iOS 9 that prevented images from decoding
- Revise
TIPImageFetchViewHelper
to use delegate and data source pattern, likeUITableView
andUIPickerView
do.- Less fiddly with simpler touch points by implementing the delegate and/or data source.
- Added a sample application that uses the Twitter API.
- Refactor
TIPImageFetchOperation
andTIPImageFetchDelegate
to use an encapsulatedTIPImageFetchResult
- Gives us a consistent interface for preview, progressive and final image results
- Add support for "placeholder" images
- This offers a way to contextually "flag" certain images as "less valuable" that full images
- Consider a black and white preview of a full color image, that could be flagged as a "placeholder"
- Cap caches to have a max number of images too
- TwitterImagePipeline now supports pluggable image decoding and encoding w/
TIPImageCodecs.h
TIPImageCodecCatalogue
exists to encapsulate the set of known codecs for TIP to use- The default codecs are all those included by iOS
- WebP codec is used in the unit tests, but does not come bundled with TIP as a default
- Consumers of TIP can use the WebP codec in their projects if they want to use it
- By default, process entries from the disk image cache manifest in parallel, reducing manifest load time by 25-50%
- Properly prefix methods in TwitterImagePipeline with
tip_
prefix
- Remove
forceUITraitCollectionToSynchronizeConstruction
property fromTIPGlobalConfiguration
- TIP will now always force the synchronization fix on iOS 8 & 9
- Move many image helper functions into
UIImage(TIPAdditions)
category - For some methods, add error output
- Rename remaining helper functions to have better names and drop the "Image" prefix
- Abstract out the networking of TIP via the
TIPImageFetchDownload
protocol inTIPImageFetchDownload.h
- This permits TIP to have it's own basic implementation but also frees consumers to plug in whatever networking layer they prefer instead. Twitter uses the protocol to plug in it's own Twitter Network Layer framework.
- Plugging in a custom
TIPImageFetchDownload
is done via theimageFetchDownloadClass
property onTIPGlobalConfiguration
. - The default TIP
TIPImageFetchDownload
implementation is just a thin wrapper onNSURLSession
.
- Refactor TIP to use
NSString
representations for image types instead ofTIPImageType
- Restructure TIP. No code/interface changes, just project layout and code moving between files.
- Add swizzling to mitigate crash in Apple's
UIImage
. UIImage
is thread safe except with image creation (Apple bugs #27141588 and #26954460) which creates aUITraitCollection
that has a race condition that leads to overrelease.- Following same pattern as Peter Steinberger to mitigate the issue: https://pspdfkit.com/blog/2016/investigating-thread-saftey-of-UIImage/
- Swizzle
[UITraitCollection traitCollectionWithDisplayScale:]
to use a mutex for thread safety - Swizzling is opt-in via
TIPGlobalConfiguration.forceUITraitCollectionToSynchronizeConstruction
- This issue definitely exists on iOS 9, but it might have been fixed on iOS 10. iOS 10 is in beta a.t.m. so we'll need to wait until we can validate in production.
- Update the API to be more Swift-friendly
- Value accessors in TIPImageFetchRequest and TIPImageStoreRequest are now defined as read-only properties, rather than as methods.
- Moves TIPImageFetchLoadingSourcesNone out of the TIPImageFetchLoadingSources NS_OPTIONS and defines it as a constant instead so that it does not break Swift's automatic prefix stripping for the rest of the values.
- Create
TIPImageViewFetchHelper
to encapsulate reusable fetch behavior for an Image View - With given glue methods, a fetch helper can dynamically update the fetch request to target the desired image view's constraints.
- By subclassing, a custom fetch helper can add additional concrete utility such as auto-selecting the best URL for a fetch based on the constraints of the target image view.
- Encapsulate
TIPImageViewFetchHelper
in aTIPImageView
for convenience
- Remove Twitter specific logging framework dependency and expose hooks to provide any desired logger
- Increase metadata of network downloaded images
- Support multiple global TIP observers instead of just one
- Rework
TIPImageFetchDelegate
to be weakly held and cancel its operation(s) on dealloc
- Add support for capping the size of an entry in the caches
[TIPGlobalConfiguration maxRatioSizeOfCacheEntry]
- Add
imageFetchOperation:willAttemptToLoadFromSource:
toTIPImageFetchDelegate
- Provide extensibility to
TIPImageStoreRequest
by offering ability to provide aTIPImageStoreRequestHydrater
. - The hydrater can be used to extend the work that executes for an image store operation.
- Useful for asynchronously loading the image from a PhotoKit
- or asynchronously tranforming or modifying the image to be cached.
- Expose the underlying
NSOperation
for the image store operation so that it can be used in dependency chains (but as aTIPDependencyOperation
) - Useful for preventing a fetch operation from starting until a related store operation completes
- Offers being made a dependency, being waited on until finished, and Key-Value-Observing when it finishes or transitions to/from executing
- Does not offer mutability of the operation: that includes cancelling, prioritization or applying dependencies
- Increase versatility of
TIPImageStoreRequest
by permitting a request to have both a data representation (NSData
orNSString
file path) and aUIImage
representation. - This provides a single action that applies a
UIImage
to the memory cache and the data representation to the disk cache so that if the caller already made these expensive serializations/deserializations, they needn't be duplicated by the image pipeline during storage. - Previous behavior is in tact so if only one image representation is provided, it will be accurately converted to the right formats for the appropriate caches.
- provide load source when a progressive frame is loaded or the first frame of an animated image is loaded
- Optimize TIP for when a TIPImageFetchOperation over HTTP/1.1 is cancelled
- When an op is cancelled and the underlying download would have no more delegates do the following:
- If the download is known to be going over SPDY or HTTP/2 (not always easy to detect), cancel the download
- If there is less than 1 KB of data left to download, continue as a "detached" download
- If there is less than 3 seconds of estimated time remaining, continue as a "detached" download
- Otherwise, just as before, cancel the download
- As a "detached" download receives more data; if the download slows down too much, cancel the download
- When a "detached" download completes, don't decode the image. Just store it to the disk cache.
- This optimization is particularly valuable on HTTP/1.1 (vs SPDY or HTTP/2) since it prevents connections from being closed and having to build up a new connection for subsequent image downloads
- Share max concurrent operations across all image pipelines
- Add method to TIPImagePipeline to get a copy of the on disk cache file for an image entry
- Add TIPGlobalConfiguration
- Share cache max bytes across all caches
- Encapsulate images fetched by TIP in a
TIPImageContainer
so that additional meta data can be maintained - Currently, additiona meta data is loop count and frame durations for animated images (GIFs)
- Add preliminary support for progressive JPEG-2000
- Still not ready and disabled in code
- Have progressive loading policy split into progressive loading policies so that a policy can be specified per
TIPImageType
- This will allow us to hone our policy for JPEG-2000 separately from PJPEG
- Fix bug in Progressive Loading logic for PJPEG (could skip scans by mistake)
- Update unit tests
- Add support for GIFs
- Animated GIFs will automatically be supported and retrieved as
UIImage
s withimages
property populated with the animated frames. Adding an animatedUIImage
to aUIImageView
will automatically animate. TIPImageFetchDelegate
now has a method to optionally have the first frame of an animated image loaded while the remainder of the animated image loads[TIPImageFetchDelegate tip_imageFetchOperation:didLoadFirstAnimatedImageFrame:progress:]
- Add TIPImageFetchMetrics for encapsulating the information related to an image fetch
- Provide ability to inspect TIPImagePipeline (info on all the entries in each cache)
- Provide mechanism to clear memory and/or disk caches specifically (usefull for debugging)
- Split up image fetches into two methods: 1) for constructing the operation and 2) for starting the operation
- Add ability to discard the delegate of a
TIPImageFetchOperation
- Increase sanitization of image identifiers loaded from disk that were hashed (under the covers, so a transparent increase in robustness)
- Detect invalid requests and elicit an appropriate error when encountered
- Add
TIPImagePipelineObserver
- Initial release