1.9.80
AsyncDisplayKit 1.9.8 sets a new record as the biggest release yet. We’ve been quietly shipping small dot releases to Cocoapods, but this is the first GitHub release with a documented changelog since 1.9.6.
Many thanks to our vibrant community, which has been especially active since January. Newcomers and experienced developers alike are invited to:
- Join the 120+ developers on our new Slack channel for real-time debugging help, community updates, and interesting discussion on app architecture. Signup at http://asdk-slack-auto-invite.herokuapp.com or email [email protected] to get an invite.
- Check out our upgraded website and (work-in-progress) documentation at http://asyncdisplaykit.org/docs/getting-started.html. To submit a documentation request, see our #documentation channel on Slack. After a long wait, we have phenomenal momentum building a detailed docset.
- Look for Luke Parham’s AsyncDisplayKit tutorial series, which will be on raywenderlich.com in the next few weeks! Three full-scale tutorials are planned, complete with example projects and very detailed advice on best practices.
Cocoapod Specs:
http://cocoapods.org/pods/AsyncDisplayKit
Total Downloads: 424,017
Dev-installs this week: 12,200
Apps: 4,146
1.9.8 Release Changes:
1,299 commits from 20 contributors
924 files changed with 47,413 lines added and 17,620 lines deleted
New features:
-
PINRemoteImage is now the default image downloader for ASDK’s powerful image components. PINRemoteImage is one of the best image downloaders on iOS, battle-tested by loading trillions of images for Pinterest. It’s most popular feature improves the experience of downloading images on slow network connections by progressively rendering JPEGs; Apple’s libraries don’t do this, nor do many image libraries.
- Progressive JPEG This isn't just the bare minimum. Images load automatically, with dynamic network reprioritization to focus on images closest to the screen, smart memory management, and a beautiful gaussian blur applied to progressive scans so they look smooth instead of blocky. https://github.com/pinterest/PINRemoteImage
-
Animated GIF support for ASImageNode and ASNetworkImageNode. This much requested feature is finally here!
-
Accessibility now works seamlessly in ways that even UIKit doesn’t provide. When using the powerful optimization features of
.layerBacked
and.shouldRasterizeDescendants
, VoiceOver can now access fine-grained metadata about each element. This is pretty amazing: CALayer doesn’t support accessibility, and rasterization reduces everything to a single flat image. The ASDK team fundamentally believes in Accessibility, and invested the time to create an innovative system to make this possible with zero developer effort. As a bonus, this also allows Automated UI Testing greater access to the interface. -
ASNavigationController and ASTabBarController, which implement a new protocol ASVisibility. These classes can be used even without ASDisplayNodes, making them suitable base classes for your inheritance hierarchy. For any child view controllers that are ASViewControllers, these classes know the exact number of user taps it would take to make the view controller visible (0 if currently visible).
Knowing a view controller’s visibility depth allows view controllers to automatically take appropriate actions as a user approaches or leaves them. Non-default tabs in an app might preload some of their data; a controller 3 levels deep in a navigation stack might progressively free memory for images, text, and fetched data as it gets deeper. Any container view controller can implement a simple protocol to integrate with the system. For example, ASNavigationController will return a visibility depth of it's own visibilityDepth + 1 for a view controller that would be revealed by tapping the back button once. -
ASEnvironment a performant and scalable way to enable upward and downward propagation of information throughout the node hierarchy. It stores a variety of critical “environmental” metadata, like the trait collection, interface state, hierarchy state, and more. This data flow is accomplished much more efficiently than UIKit, by using bit-packed C structures. ASEnvironment powers many of the most valuable features of AsyncDisplayKit.
-
ASVideoPlayerNode, a full video player with a variety of playhead controls. It contains an ASVideoNode, which will remain the lightweight, core video playback element. ASVideoPlayerNode is highly customizable, allowing the developer to build a completely custom look (and even completely different layout specification) without writing any initialization or controller code for the control behaviors. Out of the box, it provides a clean set of default controls. Check out the new ASDKTube app in examples/, and help us extend it!
-
ASLayoutTransition, was designed to make all animations with AsyncDisplayKit easy, even transforming an entire set of views into a completely different set of views! With this system, AsyncDisplayKit will do the work to animate between any two possible ASLayoutSpecs...even adding and removing nodes automatically!
Starting a transition is as easy as calling -transitionLayoutWithDuration:. This triggers -layoutSpecThatFits: - and the new spec is compared for each difference to the current layout. It will automatically add new elements, remove unneeded elements after the transition and update the position and size of any existing elements.There are also easy to use APIs that allow you to fully customize the starting state of new elements, as well as the ending state of removed elements. Commonly, you may want new things to fade in and old ones to fade out, which makes these transitions look great by default (existing elements animate from start to end). For a demo and documentation: http://asyncdisplaykit.org/docs/layout-transition-api.html
-
When enabled, Implicit Hierarchy Management (IHM) means that your code can optionally omit
addSubnode:
andremoveFromSupernode
calls! Instead, -layoutSpecThatFits: fully specifies the hierarchy; nodes which are present in a layout spec are then included in the hierarchy. If a node is no longer in the spec with a later relayout, it is removed.This feature is currently Beta, but will soon be enabled by default for all ASDisplayNodes using ASLayoutSpec. It is used in most parts of the Pinterest app, and is very stable; it is Beta only because API name adjustments are being considered. For details on the BOOL that enables it, see: http://asyncdisplaykit.org/docs/implicit-hierarchy-mgmt.html
-
ASTraitCollection provides thread-safe access to all of the UITraitCollection values from any ASViewController or ASDisplayNode.
-
ASRunLoopQueue is one of the most important optimizations in the history of AsyncDisplayKit, and has a few uses at the application level as well! It allows spreading work across multiple turns of the main thread runloop, when it is technically impossible to avoid that work occurring on the main thread. This means that touch events have dozens of new opportunities to capture control, as the runloop checks for touches on each turn — then enters a special “tracking” mode to pause less important work once a touch is locked in. Main thread stalls that could be >100ms are often reduced to 10ms, allowing an unprecedented level of 60FPS and zero-touch-latency operation even on very old devices!
It is brand new in this release. In testing with Pinterest, touch latency on slow devices like the iPad 3 was reduced by a full 3-5x from ASDK’s automatic use of the queue to spread out UIView -init, -addSubview:, and -removeFromSuperview.
Currently, the only common type of main thread stall that cannot be prevented with this technique — UIKit internal overhead for collection or table edit operations. ASDK does dramatically improve the performance of collections and tables (via concurrent measurement of sizes), but a lesser portion of the overhead remains in the form of one large UIKit operation.
Reach out on Slack if you’d like to learn more about this incredibly exciting achievement, such as how it builds on many other capabilities of ASDK in order to work (this technique cannot be used with a regular UIKit app). We’re also especially happy to look at Instruments profiles and help you dial in performance of your app.
-
ASTextKitFontSizeAdjuster is an advanced new typography feature that simplifies building a polished experience with localized and/or user-generated strings. ASTextNode now accepts an array of scale factors, customizable by your app designer, that will attempt to fit a string inside the constrained size. It also has a class method to take all of the attributed string attributes impacted by size (line spacing, kerning, etc) and scale them by the scale factor value.
-
ASRelativeLayoutSpec This new layout spec allows positioning a child at any 9-part box position (corners, edges, or center). For an example of this layout spec in action, check out the layoutSpecThatFits: method in the CatDealsCollectionView example app.
-
ASWeakSet is an easy-to-use collection class for maintaining zeroing weak references to objects. We have found a variety of useful applications for this class at both the framework and application layer, so try it out!
-
New debug tools, including an Image Scaling Tool for ASImageNodes to quickly check for image upscaling / downscaling and a Hit Test Visualization Tool for ASControlNodes. Check out the documentation at:
http://asyncdisplaykit.org/docs/debug-tool-pixel-scaling.html
http://asyncdisplaykit.org/docs/debug-tool-hit-test-visualization.html -
New example apps including
AsyncDisplayKitOverview: A catalog of ASDK’s UI components.
ASDKgram: Our largest and most diverse example app. It demonstrates the simplicity and lines of code saved when architecting an ASDK app. The, infinitely-scrolling social media feed is also reimplemented using UIKit to provide a side-by-side comparison.
ASDKTube: A scrolling feed of ASVideoPlayerNodes.
API improvements or extensions:
- ASVideoNode has substantial improvements in capabilities and API! It now derives from ASNetworkImageNode, making it easy to use a JPEG video thumbnail with automatic preloading, progressive decoding, shared image caching, etc. It now supports HTTP Live Streaming video sources. ASVideoPlayerNode provides highly customizable playback controls. Finally, a wide variety of notifications and playback management options are available to customize re-buffering behavior and more.
- ASRangeController now offers 4 different range modes, allowing quick switching of the aggressiveness and behavior of the data and display preload ranges. In addition, memory is automatically reclaimed when the application suspends, and during a memory warning. These features integrate with ASVisibility to gracefully scale memory usage while proactively reloading content if a user comes near to it again.
- New property
.layoutSpecBlock
can be set on any ASDisplayNode, to provide an implementation of --layoutSpecThatFits: without subclassing. This is particularly useful for the node of an ASViewController. - UIView & CALayer bridged properties may now be written to from any background thread even after the view or layer is created. This eliminates the rare, but annoying “Thread Affinity” assertion that could occur with otherwise reasonable, threadsafe code.
ASPendingStateController
carefully marshalls the property updates to the main thread in transaction batches, synchronized with the main thread runloop to ensure they land in the same CATransaction. Advanced use cases are possible if many property writes must be included in the same frame update. - ASMapNode has significant performance and memory usage improvements.
- ASNetworkImageNode can now notify you when each progressive scan is finished rendering. You can use this for precise metrics on image loading times.
- Improved integration with tvOS UIFocus APIs. Added default focus states to ASControlNode and ASImageNode.
Full commit list here: 1.9.6...1.9.8
As always, email [email protected] or ping us on Slack with any questions or comments. Thanks for following the development of our framework — I hope the community continues to bring you advanced and exciting software technology for years to come!