diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..ccfb6ef --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-2.7.0 diff --git a/.travis.yml b/.travis.yml index dbffc06..72484cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: objective-c -osx_image: xcode10 +osx_image: xcode11.6 + +cache: + - bundler + - cocoapods before_install: - - gem install xcpretty-travis-formatter; - - gem install cocoapods --no-document --quiet; - - pod install --repo-update; + - bundle install # --deployment # to cache vendor/bundle + - bundle exec pod install --repo-update script: - - set -o pipefail && xcodebuild -workspace LayoutFrameworkBenchmark.xcworkspace -scheme LayoutFrameworkBenchmark -sdk iphonesimulator12.0 -destination 'platform=iOS Simulator,name=iPhone 8' build | xcpretty -f `xcpretty-travis-formatter` + - set -o pipefail && xcodebuild -workspace LayoutFrameworkBenchmark.xcworkspace -scheme LayoutFrameworkBenchmark -sdk iphonesimulator13.6 -destination 'platform=iOS Simulator,name=iPhone 8' build | xcpretty diff --git a/Gemfile b/Gemfile index c9b8f87..375e960 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,4 @@ source 'https://rubygems.org' gem 'synx' gem 'cocoapods' +gem 'xcpretty-travis-formatter' diff --git a/Gemfile.lock b/Gemfile.lock index 5714adf..27fe2b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,76 +1,120 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.0) - activesupport (4.2.10) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - atomos (0.1.2) - claide (1.0.2) + CFPropertyList (3.0.7) + base64 + nkf + rexml + activesupport (7.1.5.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) + tzinfo (~> 2.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) + claide (1.1.0) clamp (0.6.5) - cocoapods (1.5.3) - activesupport (>= 4.0.2, < 5) + cocoapods (1.16.2) + addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.5.3) - cocoapods-deintegrate (>= 1.0.2, < 2.0) - cocoapods-downloader (>= 1.2.0, < 2.0) + cocoapods-core (= 1.16.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.3.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) colored2 (~> 3.1) escape (~> 0.0.4) - fourflusher (~> 2.0.1) + fourflusher (>= 2.3.0, < 3.0) gh_inspector (~> 1.0) - molinillo (~> 0.6.5) + molinillo (~> 0.8.0) nap (~> 1.0) - ruby-macho (~> 1.1) - xcodeproj (>= 1.5.7, < 2.0) - cocoapods-core (1.5.3) - activesupport (>= 4.0.2, < 6) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.27.0, < 2.0) + cocoapods-core (1.16.2) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.2) - cocoapods-downloader (1.2.1) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (2.1) cocoapods-plugins (1.0.0) nap - cocoapods-search (1.0.0) - cocoapods-stats (1.0.0) - cocoapods-trunk (1.3.0) + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) nap (>= 0.8, < 2.0) netrc (~> 0.11) - cocoapods-try (1.1.0) + cocoapods-try (1.2.0) colored2 (3.1.2) colorize (0.8.1) - concurrent-ruby (1.0.5) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + drb (2.2.3) escape (0.0.4) - fourflusher (2.0.1) + ethon (0.16.0) + ffi (>= 1.15.0) + ffi (1.17.2) + fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - i18n (0.9.5) + httpclient (2.9.0) + mutex_m + i18n (1.14.7) concurrent-ruby (~> 1.0) - minitest (5.11.3) - molinillo (0.6.5) - nanaimo (0.2.5) + json (2.13.2) + logger (1.7.0) + minitest (5.25.5) + molinillo (0.8.0) + mutex_m (0.3.0) + nanaimo (0.4.0) nap (1.1.0) netrc (0.11.0) - ruby-macho (1.1.0) + nkf (0.2.0) + public_suffix (4.0.7) + rexml (3.4.1) + rouge (3.28.0) + ruby-macho (2.5.1) + securerandom (0.3.2) synx (0.2.1) clamp (~> 0.6) colorize (~> 0.7) xcodeproj (~> 1.0) - thread_safe (0.3.6) - tzinfo (1.2.5) - thread_safe (~> 0.1) - xcodeproj (1.5.9) + typhoeus (1.4.1) + ethon (>= 0.9.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + xcodeproj (1.27.0) CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.2) + atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.5) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) + xcpretty (0.4.1) + rouge (~> 3.28.0) + xcpretty-travis-formatter (1.0.1) + xcpretty (~> 0.2, >= 0.0.7) PLATFORMS ruby @@ -78,6 +122,7 @@ PLATFORMS DEPENDENCIES cocoapods synx + xcpretty-travis-formatter BUNDLED WITH - 1.16.1 + 2.4.13 diff --git a/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj b/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj index 88f3df2..ad47acd 100644 --- a/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj +++ b/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj @@ -26,6 +26,8 @@ 24661D0A1F4EFFF5002CB883 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24661D081F4EFFF5002CB883 /* LaunchScreen.storyboard */; }; 639E5A2020DF62D700C6BCEA /* NKFrameLayoutKitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639E5A1F20DF62D700C6BCEA /* NKFrameLayoutKitView.swift */; }; BF3DC69820B560A400536177 /* FeedItemNotAutoLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3DC69720B560A400536177 /* FeedItemNotAutoLayoutView.swift */; }; + E4A8A14124FE99B1009D872B /* FeedItemTextureNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A8A14024FE982E009D872B /* FeedItemTextureNode.swift */; }; + E4A8A24F24FEDD14009D872B /* TextureCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A8A24E24FEDD14009D872B /* TextureCollectionViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -52,6 +54,8 @@ 639E5A1F20DF62D700C6BCEA /* NKFrameLayoutKitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NKFrameLayoutKitView.swift; sourceTree = ""; }; 73BD901DE3512A23A7603899 /* Pods-LayoutFrameworkBenchmark.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LayoutFrameworkBenchmark.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark.debug.xcconfig"; sourceTree = ""; }; BF3DC69720B560A400536177 /* FeedItemNotAutoLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedItemNotAutoLayoutView.swift; sourceTree = ""; }; + E4A8A14024FE982E009D872B /* FeedItemTextureNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedItemTextureNode.swift; sourceTree = ""; }; + E4A8A24E24FEDD14009D872B /* TextureCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureCollectionViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -69,6 +73,7 @@ 2401BC741F4F017D00788998 /* Benchmarks */ = { isa = PBXGroup; children = ( + E4A8A13F24FE981F009D872B /* Texture */, 2401BCA21F4F045600788998 /* AutoLayout */, 2401BC921F4F020D00788998 /* FlexLayout */, 2401BC8D1F4F01CC00788998 /* LayoutKit */, @@ -208,6 +213,15 @@ name = NotAutoLayout; sourceTree = ""; }; + E4A8A13F24FE981F009D872B /* Texture */ = { + isa = PBXGroup; + children = ( + E4A8A14024FE982E009D872B /* FeedItemTextureNode.swift */, + E4A8A24E24FEDD14009D872B /* TextureCollectionViewController.swift */, + ); + name = Texture; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -241,7 +255,6 @@ TargetAttributes = { 24661CFB1F4EFFF5002CB883 = { CreatedOnToolsVersion = 8.3.2; - DevelopmentTeam = ZYH5WDPX24; LastSwiftMigration = 1010; ProvisioningStyle = Automatic; }; @@ -252,6 +265,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -284,13 +298,17 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark-frameworks.sh", "${BUILT_PRODUCTS_DIR}/FlexLayout/FlexLayout.framework", "${BUILT_PRODUCTS_DIR}/LayoutKit/LayoutKit.framework", "${BUILT_PRODUCTS_DIR}/NKFrameLayoutKit/NKFrameLayoutKit.framework", "${BUILT_PRODUCTS_DIR}/NotAutoLayout/NotAutoLayout.framework", + "${BUILT_PRODUCTS_DIR}/PINCache/PINCache.framework", + "${BUILT_PRODUCTS_DIR}/PINOperation/PINOperation.framework", + "${BUILT_PRODUCTS_DIR}/PINRemoteImage/PINRemoteImage.framework", "${BUILT_PRODUCTS_DIR}/PinLayout/PinLayout.framework", - "${PODS_ROOT}/Reveal-SDK/RevealServer-19/iOS/RevealServer.framework", + "${BUILT_PRODUCTS_DIR}/Texture/AsyncDisplayKit.framework", + "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -298,12 +316,16 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LayoutKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NKFrameLayoutKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NotAutoLayout.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINCache.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINOperation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINRemoteImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PinLayout.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RevealServer.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AsyncDisplayKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FB2DF4C2068AD4C560959816 /* [CP] Check Pods Manifest.lock */ = { @@ -331,6 +353,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E4A8A24F24FEDD14009D872B /* TextureCollectionViewController.swift in Sources */, 2401BCA11F4F044000788998 /* FeedItemUIStackView.swift in Sources */, 2401BC8B1F4F018C00788998 /* Stopwatch.swift in Sources */, 2401BC8F1F4F01D600788998 /* FeedItemLayoutKitView.swift in Sources */, @@ -340,6 +363,7 @@ 2401BC821F4F018C00788998 /* CollectionViewController.swift in Sources */, 2401BC9E1F4F042700788998 /* FeedItemManualView.swift in Sources */, 2401BC811F4F018C00788998 /* BenchmarkViewController.swift in Sources */, + E4A8A14124FE99B1009D872B /* FeedItemTextureNode.swift in Sources */, BF3DC69820B560A400536177 /* FeedItemNotAutoLayoutView.swift in Sources */, 639E5A2020DF62D700C6BCEA /* NKFrameLayoutKitView.swift in Sources */, 2401BC9B1F4F03B300788998 /* ProfileCardLayout.swift in Sources */, @@ -480,14 +504,17 @@ baseConfigurationReference = 73BD901DE3512A23A7603899 /* Pods-LayoutFrameworkBenchmark.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ZYH5WDPX24; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = LayoutFrameworkBenchmark/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mirego.test.dev; + PRODUCT_BUNDLE_IDENTIFIER = com.layoutbox.LayoutFrameworkBenchmark; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -496,14 +523,17 @@ baseConfigurationReference = 1A3C4D1FF88A9395CE622CF2 /* Pods-LayoutFrameworkBenchmark.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ZYH5WDPX24; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = LayoutFrameworkBenchmark/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mirego.test.dev; + PRODUCT_BUNDLE_IDENTIFIER = com.layoutbox.LayoutFrameworkBenchmark; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/LayoutFrameworkBenchmark.xcodeproj/xcshareddata/xcschemes/LayoutFrameworkBenchmark.xcscheme b/LayoutFrameworkBenchmark.xcodeproj/xcshareddata/xcschemes/LayoutFrameworkBenchmark.xcscheme index a6b859d..5bf0a71 100755 --- a/LayoutFrameworkBenchmark.xcodeproj/xcshareddata/xcschemes/LayoutFrameworkBenchmark.xcscheme +++ b/LayoutFrameworkBenchmark.xcodeproj/xcshareddata/xcschemes/LayoutFrameworkBenchmark.xcscheme @@ -27,8 +27,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + + - - ASLayoutSpec { + let mainStack = ASStackLayoutSpec(direction: .vertical, + spacing: 4.0, + justifyContent: .spaceBetween, + alignItems: .stretch, + children: [topBarView, miniProfileView, miniContentView, socialActionsView, commentView]) + return mainStack + } +} + +class CommentNode: ASDisplayNode { + let actorImageView: ASImageNode = { + let i = ASImageNode() + i.image = UIImage(named: "50x50.png") + return i + }() + + let actorCommentLabel: ASTextNode = ASTextNode() + + override init() { + super.init() + [actorImageView, actorCommentLabel].forEach { addSubnode($0) } + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + actorCommentLabel.style.flexGrow = 1.0 + let mainStack = ASStackLayoutSpec(direction: .horizontal, + spacing: 4.0, + justifyContent: .spaceBetween, + alignItems: .center, + children: [actorImageView, actorCommentLabel]) + return mainStack + } +} + +class MiniContentNode: ASDisplayNode { + let contentImageView: ASImageNode = { + let i = ASImageNode() + i.image = UIImage(named: "350x200.png") + i.contentMode = .scaleAspectFit + i.backgroundColor = UIColor.orange + return i + }() + + let contentTitleLabel: ASTextNode = ASTextNode() + let contentDomainLabel: ASTextNode = ASTextNode() + + override init() { + super.init() + [contentImageView, contentTitleLabel, contentDomainLabel].forEach { addSubnode($0) } + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + let mainStack = ASStackLayoutSpec(direction: .vertical, + spacing: 0.0, + justifyContent: .spaceBetween, + alignItems: .stretch, + children: [contentImageView, contentTitleLabel, contentDomainLabel]) + return mainStack + } +} + +class MiniProfileNode: ASDisplayNode { + let posterImageView: ASImageNode = { + let i = ASImageNode() + i.image = UIImage(named: "50x50.png") + return i + }() + + let posterNameLabel: ASTextNode = { + let l = ASTextNode() + l.backgroundColor = UIColor.yellow + return l + }() + + let posterHeadlineLabel: ASTextNode = { + let l = ASTextNode() + l.maximumNumberOfLines = 3 + l.backgroundColor = UIColor.yellow + return l + }() + + let posterTimeLabel: ASTextNode = { + let l = ASTextNode() + l.backgroundColor = UIColor.yellow + return l + }() + + let posterCommentLabel: ASTextNode = ASTextNode() + + override init() { + super.init() + [posterNameLabel, posterHeadlineLabel, posterTimeLabel, posterImageView, posterCommentLabel].forEach { addSubnode($0) } + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + let textStack = ASStackLayoutSpec(direction: .vertical, spacing: 2.0, justifyContent: .spaceBetween, alignItems: .stretch, children: [posterNameLabel, posterHeadlineLabel, posterTimeLabel]) + textStack.style.flexGrow = 1.0 + + let imageTextStack = ASStackLayoutSpec(direction: .horizontal, + spacing: 4.0, + justifyContent: .spaceBetween, + alignItems: .center, + children: [posterImageView, + textStack]) + + let mainStack = ASStackLayoutSpec(direction: .vertical, + spacing: 3.0, + justifyContent: .start, + alignItems: .stretch, + children: [imageTextStack, + posterCommentLabel]) + + let insetStack = ASInsetLayoutSpec(insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 4.0), + child: mainStack) + + return insetStack + } +} + +class SocialActionsNode: ASDisplayNode { + let likeLabel: ASTextNode = { + let l = ASTextNode() + l.attributedText = "Like".makeAttributedString() + l.backgroundColor = .green + return l + }() + + let commentLabel: ASTextNode = { + let l = ASTextNode() + l.attributedText = "Comment".makeAttributedString() + l.backgroundColor = .green + return l + }() + + let shareLabel: ASTextNode = { + let l = ASTextNode() + l.attributedText = "Share".makeAttributedString() + l.backgroundColor = .green + return l + }() + + override init() { + super.init() + [likeLabel, commentLabel, shareLabel].forEach { addSubnode($0) } + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + let mainStack = ASStackLayoutSpec(direction: .horizontal, + spacing: 0.0, + justifyContent: .spaceBetween, + alignItems: .start, + children: [likeLabel, commentLabel, shareLabel]) + return mainStack + } +} + +class TopBarNode: ASDisplayNode { + let actionLabel: ASTextNode = ASTextNode() + + let optionsLabel: ASTextNode = { + let l = ASTextNode() + l.attributedText = "...".makeAttributedString() + return l + }() + + override init() { + super.init() + [actionLabel, optionsLabel].forEach { addSubnode($0) } + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + let mainStack = ASStackLayoutSpec(direction: .horizontal, + spacing: 0.0, + justifyContent: .start, + alignItems: .start, + children: [actionLabel, optionsLabel]) + actionLabel.style.flexGrow = 1.0 + return mainStack + } +} + +private extension String { + func makeAttributedString() -> NSAttributedString { + return NSAttributedString(string: self, attributes: [.font: UIFont.systemFont(ofSize: 17.0)]) + } +} diff --git a/LayoutFrameworkBenchmark/TextureCollectionViewController.swift b/LayoutFrameworkBenchmark/TextureCollectionViewController.swift new file mode 100644 index 0000000..e82507b --- /dev/null +++ b/LayoutFrameworkBenchmark/TextureCollectionViewController.swift @@ -0,0 +1,49 @@ +// Copyright 2016 LinkedIn Corp. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import AsyncDisplayKit + +class TextureCollectionViewController: ASDKViewController, ASCollectionDataSource, ASCollectionDelegate { + + let collectionNode: ASCollectionNode + let reuseIdentifier = "cell" + let data: [FeedItemData] + let flowLayout: UICollectionViewFlowLayout + + init(data: [FeedItemData]) { + self.data = data + self.flowLayout = UICollectionViewFlowLayout() + self.collectionNode = ASCollectionNode(collectionViewLayout: self.flowLayout) + super.init(node: collectionNode) + collectionNode.delegate = self + collectionNode.dataSource = self + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + collectionNode.reloadData() + } + + func numberOfSections(in collectionNode: ASCollectionNode) -> Int { + return 1 + } + + func collectionNode(_ collectionNode: ASCollectionNode, numberOfItemsInSection section: Int) -> Int { + return data.count + } + + func collectionNode(_ collectionNode: ASCollectionNode, nodeForItemAt indexPath: IndexPath) -> ASCellNode { + let cell = FeedItemTextureNode(data: data[indexPath.row]) + + return cell + } +} diff --git a/Podfile b/Podfile index f9e9415..1b69bbc 100755 --- a/Podfile +++ b/Podfile @@ -1,30 +1,18 @@ -source 'https://github.com/CocoaPods/Specs.git' +source 'https://cdn.cocoapods.org/' use_frameworks! project 'LayoutFrameworkBenchmark.xcodeproj' -platform :ios, '10.0' +platform :ios, '15.0' inhibit_all_warnings! target 'LayoutFrameworkBenchmark' do pod 'FlexLayout' - pod 'LayoutKit' + pod 'LayoutKit', :git => 'https://github.com/LinkedInAttic/LayoutKit.git' pod 'NotAutoLayout' pod 'NKFrameLayoutKit' pod 'PinLayout' - - pod 'Reveal-SDK' + pod 'Texture' end - - -post_install do |installer| - installer.pods_project.targets.each do |target| - if ['LayoutKit'].include? target.name - target.build_configurations.each do |config| - config.build_settings['SWIFT_VERSION'] = '4.1' - end - end - end -end \ No newline at end of file diff --git a/Podfile.lock b/Podfile.lock index 4efba48..ee3dca9 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,36 +1,88 @@ PODS: - - FlexLayout (1.3.11) - - LayoutKit (10.0.1) - - NKFrameLayoutKit (2.4) + - FlexLayout (2.2.2): + - Yoga (= 3.2.1) + - LayoutKit (10.1.0) + - NKFrameLayoutKit (2.5) - NotAutoLayout (3.2.0) - - PinLayout (1.8.6) - - Reveal-SDK (19) + - PINCache (3.0.4): + - PINCache/Arc-exception-safe (= 3.0.4) + - PINCache/Core (= 3.0.4) + - PINCache/Arc-exception-safe (3.0.4): + - PINCache/Core + - PINCache/Core (3.0.4): + - PINOperation (~> 1.2.3) + - PinLayout (1.10.6) + - PINOperation (1.2.3) + - PINRemoteImage/Core (3.0.4): + - PINOperation + - PINRemoteImage/iOS (3.0.4): + - PINRemoteImage/Core + - PINRemoteImage/PINCache (3.0.4): + - PINCache (~> 3.0.4) + - PINRemoteImage/Core + - Texture (3.2.0): + - Texture/AssetsLibrary (= 3.2.0) + - Texture/Core (= 3.2.0) + - Texture/MapKit (= 3.2.0) + - Texture/Photos (= 3.2.0) + - Texture/PINRemoteImage (= 3.2.0) + - Texture/Video (= 3.2.0) + - Texture/AssetsLibrary (3.2.0): + - Texture/Core + - Texture/Core (3.2.0) + - Texture/MapKit (3.2.0): + - Texture/Core + - Texture/Photos (3.2.0): + - Texture/Core + - Texture/PINRemoteImage (3.2.0): + - PINRemoteImage/iOS (~> 3.0.0) + - PINRemoteImage/PINCache + - Texture/Core + - Texture/Video (3.2.0): + - Texture/Core + - Yoga (3.2.1) DEPENDENCIES: - FlexLayout - - LayoutKit + - LayoutKit (from `https://github.com/LinkedInAttic/LayoutKit.git`) - NKFrameLayoutKit - NotAutoLayout - PinLayout - - Reveal-SDK + - Texture SPEC REPOS: - https://github.com/cocoapods/specs.git: + trunk: - FlexLayout - - LayoutKit - NKFrameLayoutKit - NotAutoLayout + - PINCache - PinLayout - - Reveal-SDK + - PINOperation + - PINRemoteImage + - Texture + - Yoga + +EXTERNAL SOURCES: + LayoutKit: + :git: https://github.com/LinkedInAttic/LayoutKit.git + +CHECKOUT OPTIONS: + LayoutKit: + :commit: 1f1b067b6b11a0779ea6b6ccd976585a1d7bb79b + :git: https://github.com/LinkedInAttic/LayoutKit.git SPEC CHECKSUMS: - FlexLayout: b008184d23aae0c56e1c916e803445a13a6f4e5a - LayoutKit: 4e69fb0f1cc3e9c2a764b58f99e88004f5da861c - NKFrameLayoutKit: c119f04a6ac305c7db5e29e1b856cee0e8a661bb + FlexLayout: c73d8da295a01937efece5531e12a692a3b9dd07 + LayoutKit: 66478bb3af5ce4519a056d9465bc4c7585d2350b + NKFrameLayoutKit: 8485fd4fb04c2c99e38e4dfd4b65a99ce10689b9 NotAutoLayout: 4723ad82a21a7c6c60c823fff7f7c29467811b92 - PinLayout: fe2a2432d6982588e208572005c941aeeae417ab - Reveal-SDK: 9f0d2c6c12eb7507921e5454ac165b7aa21140a4 + PINCache: d9a87a0ff397acffe9e2f0db972ac14680441158 + PinLayout: e2fceb4cbfdf49f3569fc242a7dfa0da4fb9aa06 + PINOperation: fb563bcc9c32c26d6c78aaff967d405aa2ee74a7 + PINRemoteImage: 6256a644f4996991f124811763c7286b2a63ff94 + Texture: 61e86ea2ee124f545be40293b54b5b8986006da2 + Yoga: 636ce73bd247407928a7df089f3bc3675916b3ff -PODFILE CHECKSUM: 3e63d42365b39b217c5809f0c7ebad9865d228e2 +PODFILE CHECKSUM: 995a4143850fbe450aace4486444d8fba0d0e46e -COCOAPODS: 1.5.3 +COCOAPODS: 1.16.2 diff --git a/README.md b/README.md index 98e85d8..398b1a6 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,8 @@ Benchmark the performances of various Swift layout frameworks. ### Requirements -* iOS 8.0+ -* Xcode 8.0+ -* Swift 3.0+ +* iOS 14.0+ +* Xcode 16.0+ # History This project is a spin-off of the excellent [LayoutKit benchmark](https://github.com/linkedin/LayoutKit). The benchmark has been extracted to add other iOS layout frameworks and to compare them. @@ -39,7 +38,7 @@ It displays the performance when layouting UICollectionView cells. This graph sh The **Y axis** indicates the **number of seconds** to render all cells. - +
@@ -76,6 +75,10 @@ Layout your views without Auto Layout constraints, in a much more swifty way. Fast Swift UIViews layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [PinLayout benchmark's source code](https://github.com/layoutBox/LayoutFrameworkBenchmark/blob/master/LayoutFrameworkBenchmark/Benchmarks/PinLayout/FeedItemPinLayoutView.swift) +* [**Texture**](https://github.com/TextureGroup/Texture) +Optimize your app by making user interfaces thread safe, which means that you will be able to shift all expensive views into background threads. +[Texture benchmark's source code](https://github.com/layoutBox/LayoutFrameworkBenchmark/blob/master/LayoutFrameworkBenchmark/FeedItemTextureNode.swift) + * **UIStackViews** Apple's UIStackViews. [UIStackViews benchmark's source code](https://github.com/layoutBox/LayoutFrameworkBenchmark/blob/master/LayoutFrameworkBenchmark/Benchmarks/UIStackView/FeedItemUIStackView.swift) @@ -98,6 +101,7 @@ Here are the benchmark rendering results to compare visual results: * [Manual layout rendering result](docs_markdown/benchmark_result_ManualLayout.png) * [NKFrameLayoutKit rendering result](docs_markdown/benchmark_result_NKFrameLayoutKit.png) * [PinLayout rendering result](docs_markdown/benchmark_result_PinLayout.png) +* [Texture rendering result](docs_markdown/benchmark_result_Texture.png) :pushpin: Some work would be required to adjust the layout so that they all match perfectly. @@ -112,23 +116,16 @@ You can see the benchmark's data and charts in this **[Google Spreadsheet Docume The **X axis** in following charts indicates the **number of cells** contained for each pass. The **Y axis** indicates the **number of seconds** to render all cells from one pass. - -
- - - -
- - +
- +
- +
- +
diff --git a/docs_markdown/benchmark_comparison.png b/docs_markdown/benchmark_comparison.png deleted file mode 100644 index 3b8db20..0000000 Binary files a/docs_markdown/benchmark_comparison.png and /dev/null differ diff --git a/docs_markdown/benchmark_comparison_all.png b/docs_markdown/benchmark_comparison_all.png index 9d0eea4..5ffdcdd 100644 Binary files a/docs_markdown/benchmark_comparison_all.png and b/docs_markdown/benchmark_comparison_all.png differ diff --git a/docs_markdown/benchmark_comparison_all_small.png b/docs_markdown/benchmark_comparison_all_small.png index 38dfd87..9aa6f57 100644 Binary files a/docs_markdown/benchmark_comparison_all_small.png and b/docs_markdown/benchmark_comparison_all_small.png differ diff --git a/docs_markdown/benchmark_iphone13pro.png b/docs_markdown/benchmark_iphone13pro.png new file mode 100644 index 0000000..7dcedae Binary files /dev/null and b/docs_markdown/benchmark_iphone13pro.png differ diff --git a/docs_markdown/benchmark_iphone16.png b/docs_markdown/benchmark_iphone16.png new file mode 100644 index 0000000..0b119d0 Binary files /dev/null and b/docs_markdown/benchmark_iphone16.png differ diff --git a/docs_markdown/benchmark_result_Texture.png b/docs_markdown/benchmark_result_Texture.png new file mode 100644 index 0000000..f5eccef Binary files /dev/null and b/docs_markdown/benchmark_result_Texture.png differ