├── .gitignore
├── .travis.yml
├── Docs
├── CZInstagram.gif
└── FLUX.jpeg
├── Example
├── ReactiveListViewKitDemo.xcodeproj
│ └── project.pbxproj
├── ReactiveListViewKitDemo
│ ├── Data Layer
│ │ ├── CZMocker.swift
│ │ ├── Feed.swift
│ │ ├── ImageInfo.swift
│ │ └── User.swift
│ ├── FLUX
│ │ ├── FeedListAction.swift
│ │ ├── SuggestedUserAction.swift
│ │ └── UserStoryAction.swift
│ ├── Info.plist
│ ├── Resources
│ │ ├── feeds copy.json
│ │ ├── feeds.json
│ │ ├── users copy.json
│ │ └── users.json
│ ├── Supported Files
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ ├── ColorFrame.imageset
│ │ │ │ ├── ColorFrameFull.png
│ │ │ │ └── Contents.json
│ │ │ ├── Comment.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── ic_chat_1-1.png
│ │ │ │ ├── ic_chat_1-2.png
│ │ │ │ └── ic_chat_1.png
│ │ │ ├── Contents.json
│ │ │ ├── InstagramTitle.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── instagramTitle-1.png
│ │ │ │ ├── instagramTitle-2.png
│ │ │ │ └── instagramTitle.png
│ │ │ ├── Like.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── ic_like-1.png
│ │ │ │ ├── ic_like-2.png
│ │ │ │ └── ic_like.png
│ │ │ ├── Liked.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── ic_liked-1.png
│ │ │ │ ├── ic_liked-2.png
│ │ │ │ └── ic_liked.png
│ │ │ ├── Menu.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── ic_menu-1.png
│ │ │ │ └── ic_menu.png
│ │ │ ├── PostImage.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── placeholder.png
│ │ │ ├── Share.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── ic_share_file-1.png
│ │ │ │ ├── ic_share_file-2.png
│ │ │ │ └── ic_share_file.png
│ │ │ └── noUser.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ └── SceneDelegate.swift
│ ├── UI Layer
│ │ └── FeedList
│ │ │ ├── FeedCellView.swift
│ │ │ ├── FeedCellView.xib
│ │ │ ├── FeedCellViewModel.swift
│ │ │ ├── FeedListActionHandler.swift
│ │ │ ├── FeedListViewController.swift
│ │ │ ├── FeedListViewModel.swift
│ │ │ └── HotUsers
│ │ │ ├── HotUserCellCardView.swift
│ │ │ ├── HotUserCellCardView.xib
│ │ │ ├── HotUserCellView.swift
│ │ │ ├── HotUserCellView.xib
│ │ │ ├── HotUserCellViewModel.swift
│ │ │ ├── HotUsersCellViewController.swift
│ │ │ ├── HotUsersCellViewController.xib
│ │ │ └── HotUsersCellViewModel.swift
│ └── Utils
│ │ └── Constants.swift
└── ReactiveListViewKitDemoUITests
│ ├── IncrementalUpdatesUITest.swift
│ ├── NoneIncrementalUpdatesUITest.swift
│ ├── ReactiveListViewKitDemoUITests.swift
│ └── ReactiveListViewKitDemoUITestsLaunchTests.swift
├── Experimental
└── MERGED_SelfSizingCell
│ ├── Example
│ ├── ReactiveListViewKitDemo.xcodeproj
│ │ └── project.pbxproj
│ ├── ReactiveListViewKitDemo
│ │ ├── Data Layer
│ │ │ ├── CZMocker.swift
│ │ │ ├── Feed.swift
│ │ │ ├── ImageInfo.swift
│ │ │ └── User.swift
│ │ ├── FLUX
│ │ │ ├── FeedListAction.swift
│ │ │ ├── SuggestedUserAction.swift
│ │ │ └── UserStoryAction.swift
│ │ ├── ListViewUITest.swift
│ │ ├── Supported Files
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Base.lproj
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── CommonCrypto
│ │ │ │ ├── .gitignore
│ │ │ │ ├── CommonCrypto.xcodeproj
│ │ │ │ │ └── project.pbxproj
│ │ │ │ ├── CommonCrypto
│ │ │ │ │ ├── CommonCrypto.xcconfig
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ ├── appletvos.modulemap
│ │ │ │ │ ├── appletvsimulator.modulemap
│ │ │ │ │ ├── iphoneos.modulemap
│ │ │ │ │ ├── iphonesimulator.modulemap
│ │ │ │ │ ├── macosx.modulemap
│ │ │ │ │ ├── watchos.modulemap
│ │ │ │ │ └── watchsimulator.modulemap
│ │ │ │ └── README.md
│ │ │ ├── Info.plist
│ │ │ └── Resources
│ │ │ │ ├── Assets.xcassets
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── ColorFrame.imageset
│ │ │ │ │ ├── ColorFrameFull.png
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Comment.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── ic_chat_1-1.png
│ │ │ │ │ ├── ic_chat_1-2.png
│ │ │ │ │ └── ic_chat_1.png
│ │ │ │ ├── Contents.json
│ │ │ │ ├── InstagramTitle.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── instagramTitle-1.png
│ │ │ │ │ ├── instagramTitle-2.png
│ │ │ │ │ └── instagramTitle.png
│ │ │ │ ├── Like.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── ic_like-1.png
│ │ │ │ │ ├── ic_like-2.png
│ │ │ │ │ └── ic_like.png
│ │ │ │ ├── Liked.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── ic_liked-1.png
│ │ │ │ │ ├── ic_liked-2.png
│ │ │ │ │ └── ic_liked.png
│ │ │ │ ├── Menu.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── ic_menu-1.png
│ │ │ │ │ └── ic_menu.png
│ │ │ │ ├── PostImage.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── placeholder.png
│ │ │ │ ├── Share.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── ic_share_file-1.png
│ │ │ │ │ ├── ic_share_file-2.png
│ │ │ │ │ └── ic_share_file.png
│ │ │ │ └── noUser.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg
│ │ │ │ ├── feeds copy.json
│ │ │ │ ├── feeds.json
│ │ │ │ ├── users copy.json
│ │ │ │ └── users.json
│ │ ├── UI Layer
│ │ │ └── FeedList
│ │ │ │ ├── FeedCellView.swift
│ │ │ │ ├── FeedCellView.xib
│ │ │ │ ├── FeedCellViewModel.swift
│ │ │ │ ├── FeedListActionHandler.swift
│ │ │ │ ├── FeedListViewController.swift
│ │ │ │ ├── FeedListViewModel.swift
│ │ │ │ └── HotUsers
│ │ │ │ ├── HotUserCellCardView.swift
│ │ │ │ ├── HotUserCellCardView.xib
│ │ │ │ ├── HotUserCellView.swift
│ │ │ │ ├── HotUserCellView.xib
│ │ │ │ ├── HotUserCellViewModel.swift
│ │ │ │ ├── HotUsersCellViewController.swift
│ │ │ │ ├── HotUsersCellViewController.xib
│ │ │ │ └── HotUsersCellViewModel.swift
│ │ └── Utils
│ │ │ ├── CZNetworking
│ │ │ ├── CZNetworking
│ │ │ │ ├── CZHTTPCache.swift
│ │ │ │ ├── CZHTTPJsonSerializer.swift
│ │ │ │ ├── CZHTTPManager.swift
│ │ │ │ ├── CZHTTPRequester.swift
│ │ │ │ ├── CZNetError.swift
│ │ │ │ ├── CZNetworking.h
│ │ │ │ ├── CommonCrypto
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ ├── CommonCrypto.xcodeproj
│ │ │ │ │ │ └── project.pbxproj
│ │ │ │ │ ├── CommonCrypto
│ │ │ │ │ │ ├── CommonCrypto.xcconfig
│ │ │ │ │ │ ├── Info.plist
│ │ │ │ │ │ ├── appletvos.modulemap
│ │ │ │ │ │ ├── appletvsimulator.modulemap
│ │ │ │ │ │ ├── iphoneos.modulemap
│ │ │ │ │ │ ├── iphonesimulator.modulemap
│ │ │ │ │ │ ├── macosx.modulemap
│ │ │ │ │ │ ├── watchos.modulemap
│ │ │ │ │ │ └── watchsimulator.modulemap
│ │ │ │ │ └── README.md
│ │ │ │ ├── Extensions.swift
│ │ │ │ └── Info.plist
│ │ │ ├── CZNetworkingTests
│ │ │ │ ├── CZNetworkingTests.swift
│ │ │ │ └── Info.plist
│ │ │ ├── LICENSE
│ │ │ └── README.md
│ │ │ └── Constants.swift
│ └── ReactiveListViewKitUITests
│ │ ├── IncrementalUpdatesUITest.swift
│ │ ├── Info.plist
│ │ ├── NoneIncrementalUpdatesUITest.swift
│ │ └── Utils
│ │ ├── CZUITest.swift
│ │ └── KIFUtils.swift
│ └── ReactiveListViewKit
│ ├── ReactiveListViewKit.podspec
│ ├── ReactiveListViewKit.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── ReactiveListViewKit.xcscheme
│ │ └── ReactiveListViewKitTests.xcscheme
│ ├── ReactiveListViewKit
│ ├── CZFeedCellViewable.swift
│ ├── CZFeedDetailsFacadeView.swift
│ ├── CZFeedDetailsModel.swift
│ ├── CZFeedDetailsViewModel.swift
│ ├── CZFeedListCell.swift
│ ├── CZFeedListFacadeView.swift
│ ├── CZFeedListViewAction.swift
│ ├── CZFeedListViewModel.swift
│ ├── CZFeedListViewStateMachine.swift
│ ├── CZFeedModel.swift
│ ├── CZFeedViewModelable.swift
│ ├── CZListDiff.swift
│ ├── CZReactiveFeedDetailsFacadeView.swift
│ ├── CZReactiveFeedListFacadeView.swift
│ ├── CZSectionModel.swift
│ ├── Reactor.swift
│ ├── TemplateViews
│ │ ├── CZDividerView.swift
│ │ ├── CZFeedListSupplementaryLineView.swift
│ │ ├── CZFeedListSupplementaryTextView.swift
│ │ ├── CZFeedListSupplementaryView.swift
│ │ ├── CZHorizontalSectionAdapterCell.swift
│ │ ├── CZHorizontalSectionAdapterView.swift
│ │ ├── CZHorizontalSectionAdapterViewModel.swift
│ │ ├── CZTextFeedCellView.swift
│ │ └── CZTextFeedViewModel.swift
│ └── Utils
│ │ ├── Array+Extension.swift
│ │ ├── CZFacadeViewHelper.swift
│ │ ├── CZListDiffableHelper.swift
│ │ ├── Constants.swift
│ │ └── ReactiveListViewKitHelper.swift
│ ├── ReactiveListViewKitTests
│ ├── Info.plist
│ ├── ListDiffTests.swift
│ └── Utils
│ │ └── CZListDiff+.swift
│ └── Supported Files
│ ├── CZUtils
│ ├── Info.plist
│ ├── LICENSE
│ ├── Package.swift
│ ├── README.md
│ ├── Sources
│ │ └── CZUtils
│ │ │ ├── CZAlertManager.swift
│ │ │ ├── CZConcurrentOperation.swift
│ │ │ ├── CZDictionary.swift
│ │ │ ├── CZError.swift
│ │ │ ├── CZFileHelper.swift
│ │ │ ├── CZHTTPJsonSerializer.swift
│ │ │ ├── CZMainQueueScheduler.swift
│ │ │ ├── CZMutexLock.swift
│ │ │ ├── CZNibLoadable.swift
│ │ │ ├── CZProMutexLock.swift
│ │ │ ├── CZTheme.swift
│ │ │ ├── CZUtils.swift
│ │ │ ├── Error+.swift
│ │ │ ├── Extensions
│ │ │ ├── Array+.swift
│ │ │ ├── Character+.swift
│ │ │ ├── Codable+.swift
│ │ │ ├── Date+.swift
│ │ │ ├── Dictionary+.swift
│ │ │ ├── NSObject+.swift
│ │ │ ├── Optional+.swift
│ │ │ ├── Set+.swift
│ │ │ ├── String+.swift
│ │ │ ├── UIButton+.swift
│ │ │ ├── UIImage+.swift
│ │ │ ├── UIScreen+.swift
│ │ │ ├── UIView+.swift
│ │ │ └── UIViewController+.swift
│ │ │ ├── Investigation
│ │ │ ├── CZDispatchGroup.swift
│ │ │ └── CriticalSectionLock.swift
│ │ │ ├── NSNullGuard.swift
│ │ │ ├── RegExHelper.swift
│ │ │ ├── Supported Files
│ │ │ ├── CZUtils.h
│ │ │ └── Info.plist
│ │ │ ├── Swizzling.swift
│ │ │ ├── ThreadSafeDictionary.swift
│ │ │ └── Utils
│ │ │ └── PrettyDescription.swift
│ └── Tests
│ │ ├── CZUtilsTests
│ │ ├── CZUtilsTests.swift
│ │ ├── TestArray.swift
│ │ ├── TestThreadSafeDictionary.swift
│ │ └── XCTestManifests.swift
│ │ └── LinuxMain.swift
│ ├── Info.plist
│ └── ReactiveListViewKit.h
├── LICENSE
├── README.md
└── ReactiveListViewKit
├── ReactiveListViewKit.podspec
├── ReactiveListViewKit.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ ├── ReactiveListViewKit.xcscheme
│ └── ReactiveListViewKitTests.xcscheme
├── ReactiveListViewKit
├── CZFeedCellViewable.swift
├── CZFeedDetailsFacadeView.swift
├── CZFeedDetailsModel.swift
├── CZFeedDetailsViewModel.swift
├── CZFeedListCell.swift
├── CZFeedListFacadeView.swift
├── CZFeedListViewAction.swift
├── CZFeedListViewModel.swift
├── CZFeedListViewStateMachine.swift
├── CZFeedModel.swift
├── CZFeedViewModelable.swift
├── CZListDiff.swift
├── CZReactiveFeedDetailsFacadeView.swift
├── CZReactiveFeedListFacadeView.swift
├── CZSectionModel.swift
├── Store
│ ├── Store.swift
│ └── StoreObserverProtocol.swift
├── TemplateViews
│ ├── CZDividerView.swift
│ ├── CZFeedListSupplementaryLineView.swift
│ ├── CZFeedListSupplementaryTextView.swift
│ ├── CZFeedListSupplementaryView.swift
│ ├── CZHorizontalSectionAdapterCell.swift
│ ├── CZHorizontalSectionAdapterView.swift
│ ├── CZHorizontalSectionAdapterViewModel.swift
│ ├── CZTextFeedCellView.swift
│ └── CZTextFeedViewModel.swift
└── Utils
│ ├── Array+Extension.swift
│ ├── CZFacadeViewHelper.swift
│ ├── CZListDiffableHelper.swift
│ ├── Constants.swift
│ └── ReactiveListViewKitHelper.swift
├── ReactiveListViewKitTests
├── Info.plist
├── ListDiffTests.swift
└── Utils
│ └── CZListDiff+.swift
└── Supported Files
├── CZUtils
├── Info.plist
├── LICENSE
├── Package.swift
├── README.md
├── Sources
│ └── CZUtils
│ │ ├── CZAlertManager.swift
│ │ ├── CZConcurrentOperation.swift
│ │ ├── CZDictionary.swift
│ │ ├── CZError.swift
│ │ ├── CZFileHelper.swift
│ │ ├── CZHTTPJsonSerializer.swift
│ │ ├── CZMainQueueScheduler.swift
│ │ ├── CZMutexLock.swift
│ │ ├── CZNibLoadable.swift
│ │ ├── CZProMutexLock.swift
│ │ ├── CZTheme.swift
│ │ ├── CZUtils.swift
│ │ ├── Error+.swift
│ │ ├── Extensions
│ │ ├── Array+.swift
│ │ ├── Character+.swift
│ │ ├── Codable+.swift
│ │ ├── Date+.swift
│ │ ├── Dictionary+.swift
│ │ ├── NSObject+.swift
│ │ ├── Optional+.swift
│ │ ├── Set+.swift
│ │ ├── String+.swift
│ │ ├── UIButton+.swift
│ │ ├── UIImage+.swift
│ │ ├── UIScreen+.swift
│ │ ├── UIView+.swift
│ │ └── UIViewController+.swift
│ │ ├── Investigation
│ │ ├── CZDispatchGroup.swift
│ │ └── CriticalSectionLock.swift
│ │ ├── NSNullGuard.swift
│ │ ├── RegExHelper.swift
│ │ ├── Supported Files
│ │ ├── CZUtils.h
│ │ └── Info.plist
│ │ ├── Swizzling.swift
│ │ ├── ThreadSafeDictionary.swift
│ │ └── Utils
│ │ └── PrettyDescription.swift
└── Tests
│ ├── CZUtilsTests
│ ├── CZUtilsTests.swift
│ ├── TestArray.swift
│ ├── TestThreadSafeDictionary.swift
│ └── XCTestManifests.swift
│ └── LinuxMain.swift
├── Info.plist
└── ReactiveListViewKit.h
/.gitignore:
--------------------------------------------------------------------------------
1 | syntax: glob
2 |
3 | # Mac OS X
4 | **DS_Store
5 |
6 | # Xcode
7 | .DS_Store
8 | *xcuserstate
9 | **xcuserstate
10 | *.xcuserstate
11 | *.mode1v3
12 | *.pbxuser
13 | *.xccheckout
14 | *.moved-aside
15 | *.mode2v3
16 | xcuserdata
17 | *.perspectivev3
18 | project.xcworkspace
19 | Groupon.xcworkspace/xcshareddata/Groupon.xccheckout
20 | *.xcscmblueprint
21 |
22 | # AppCode
23 | .idea/
24 | # VSCode
25 | .vscode/
26 |
27 | # React-Capacitor
28 | .capacitor/
29 |
30 | #Generated files
31 | *.pyc
32 |
33 | # Temporary files
34 | *.swp
35 | Pods/resources-to-copy-Groupon.txt
36 |
37 | # Ruby
38 | gems/
39 | .bundle/
40 |
41 | # Other
42 | build*
43 | data_archive*
44 | *.kpf
45 | *.wpr
46 | *.wpu
47 | *.db
48 | *.rej
49 | *.orig
50 | 3rd_party
51 | DerivedData/
52 | GrouponUITests/odo
53 | GrouponUITests/screenshots
54 | GrouponUITests/Deeplink
55 | GrouponUITests/OfflineRepository
56 | GrouponUITests/scripts/DisableUITestsSetupScriptDefaultValue.txt
57 |
58 | # Carthage
59 | Carthage/Build/*
60 |
61 | # We have to unignore certain frameworks that come as pre-packaged.
62 | # Note: We HAVE to ignore ALL swift frameworks before Swift 3.0, that's why this is opt-in
63 | !Carthage/Build/iOS/Realm.framework
64 | !Carthage/Build/iOS/Realm.dsym
65 | !Carthage/Build/iOS/AFNetworking.framework
66 | !Carthage/Build/iOS/AFNetworking.framework.dsym
67 | !Carthage/Build/iOS/EasyMapping.framework
68 | !Carthage/Build/iOS/EasyMapping.framework.dsym
69 |
70 | # Fastlane
71 | /fastlane
72 | .fastlane/.fastlane
73 | .fastlane/output
74 | .fastlane/derived_data
75 | .fastlane/test_output
76 | .fastlane/report.xml
77 | code_coverage.tar.gz
78 | test_output/
79 | output_log.txt
80 |
81 | # Swift merge files
82 | /Reference_Groupon.xcodeproj
83 | /GrouponUtilsTests-merge.swift
84 | /GrouponUtils-merge.swift
85 | /GrouponUITests-merge.swift
86 | /GrouponTests-merge.swift
87 | /GrouponImageStressTests-merge.swift
88 | /Groupon-merge.swift
89 | /GPNSTTests-merge.swift
90 | /GPNST-merge.swift
91 | /GPLoggingTests-merge.swift
92 | /GPLogging-merge.swift
93 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode11.3
3 | xcode_project: ReactiveListViewKit/ReactiveListViewKit.xcodeproj # path to your xcodeproj folder
4 | xcode_scheme: ReactiveListViewKit
5 | xcode_destination: platform=iOS Simulator,OS=11.3,name=iPhone X
6 |
--------------------------------------------------------------------------------
/Docs/CZInstagram.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Docs/CZInstagram.gif
--------------------------------------------------------------------------------
/Docs/FLUX.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Docs/FLUX.jpeg
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Data Layer/CZMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZMocker.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/12/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | class CZMocker: NSObject {
13 | static let shared = CZMocker()
14 |
15 | var feeds: [Feed] {
16 | let url = Bundle.main.url(forResource: "feeds", withExtension: "json")!
17 | return CodableHelper.decode(url) ?? []
18 | }
19 |
20 | var hotUsers: [User] {
21 | let url = Bundle.main.url(forResource: "users", withExtension: "json")!
22 | return CodableHelper.decode(url) ?? []
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Data Layer/ImageInfo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageInfo.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | /// Model of image info
13 | class ImageInfo: ReactiveListDiffable {
14 | let url: String
15 | let width: Int
16 | let height: Int
17 |
18 | // MARK: - CZListDiffable
19 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
20 | return isEqual(toCodable: object)
21 | }
22 |
23 | // MARK: - NSCopying
24 | func copy(with zone: NSZone? = nil) -> Any {
25 | return codableCopy(with: zone)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Data Layer/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/3/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | /// Model of user
13 | class User: ReactiveListDiffable {
14 | let userId: String
15 | let userName: String
16 | let fullName: String?
17 | let portraitUrl: String?
18 |
19 | enum CodingKeys: String, CodingKey {
20 | case userId = "id"
21 | case userName = "username"
22 | case fullName = "full_name"
23 | case portraitUrl = "profile_picture"
24 | }
25 |
26 | // MARK: - CZListDiffable
27 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
28 | return isEqual(toCodable: object)
29 | }
30 |
31 | // MARK: - NSCopying
32 | func copy(with zone: NSZone? = nil) -> Any {
33 | return codableCopy(with: zone)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/FLUX/FeedListAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedListActions.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | // MARK: - Events
13 |
14 | /// Action that User likes one `Feed`
15 | struct LikeFeedAction: CZActionProtocol {
16 | var feed: Feed
17 | }
18 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/FLUX/SuggestedUserAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SuggestedUserEvent.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/28/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | /// Action that follow/ignore `SuggestedUser`
13 | enum SuggestedUserAction: CZActionProtocol {
14 | case follow(user: User)
15 | case ignore(user: User)
16 | }
17 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/FLUX/UserStoryAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserStoryEvent.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/28/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | /// Action that User selects `UserStory`
13 | enum UserStoryAction: CZActionProtocol {
14 | case selected(user: User)
15 | }
16 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Resources/users copy.json:
--------------------------------------------------------------------------------
1 | [{
2 | "full_name": "Diane",
3 | "username": "fallinlight",
4 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/fallinlight.jpg",
5 | "id": "0"
6 | }, {
7 | "full_name": "Caeli",
8 | "username": "caeliyt",
9 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/caeliyt.jpg",
10 | "id": "1"
11 | }, {
12 | "full_name": "Pixlr",
13 | "username": "pixlr",
14 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/pixlr.jpg",
15 | "id": "2"
16 | }, {
17 | "full_name": "Zayn Malik",
18 | "username": "zayn",
19 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/zayn.jpg",
20 | "id": "3"
21 | }, {
22 | "full_name": "Martin Garrix",
23 | "username": "martingarrix",
24 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/martingarrix.jpg",
25 | "id": "4"
26 | }, {
27 | "full_name": "Mariale Marrero",
28 | "username": "mariale",
29 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/mariale.jpg",
30 | "id": "5"
31 | }, {
32 | "full_name": "Picsart Editor",
33 | "username": "picsart_ediitor",
34 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/picsart_ediitor.jpg",
35 | "id": "6"
36 | }, {
37 | "full_name": "Tutorial edit PicsArt",
38 | "username": "picsart_indo",
39 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/picsart_indo.jpg",
40 | "id": "7"
41 | }, {
42 | "full_name": "Annegien",
43 | "username": "fetching_tigerss",
44 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/fetching_tigerss.jpg",
45 | "id": "8"
46 | }, {
47 | "full_name": "Lesslie Polinesia",
48 | "username": "ppteamlesslie",
49 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/ppteamlesslie.jpg",
50 | "id": "9"
51 | }]
52 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 7/14/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 | var window: UIWindow?
14 |
15 | internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | return true
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/ColorFrame.imageset/ColorFrameFull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/ColorFrame.imageset/ColorFrameFull.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/ColorFrame.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "ColorFrameFull.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_chat_1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_chat_1-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_chat_1-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/ic_chat_1-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/ic_chat_1-1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/ic_chat_1-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/ic_chat_1-2.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/ic_chat_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Comment.imageset/ic_chat_1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "instagramTitle-1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "instagramTitle-2.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "instagramTitle.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/instagramTitle-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/instagramTitle-1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/instagramTitle-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/instagramTitle-2.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/instagramTitle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/InstagramTitle.imageset/instagramTitle.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_like.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_like-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_like-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/ic_like-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/ic_like-1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/ic_like-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/ic_like-2.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/ic_like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Like.imageset/ic_like.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_liked-2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_liked-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_liked.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/ic_liked-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/ic_liked-1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/ic_liked-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/ic_liked-2.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/ic_liked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Liked.imageset/ic_liked.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Menu.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_menu.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_menu-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_menu-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Menu.imageset/ic_menu-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Menu.imageset/ic_menu-1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Menu.imageset/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Menu.imageset/ic_menu.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/PostImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "placeholder.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/PostImage.imageset/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/PostImage.imageset/placeholder.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_share_file.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_share_file-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_share_file-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/ic_share_file-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/ic_share_file-1.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/ic_share_file-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/ic_share_file-2.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/ic_share_file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/Share.imageset/ic_share_file.png
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/noUser.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/noUser.imageset/no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Example/ReactiveListViewKitDemo/Supported Files/Assets.xcassets/noUser.imageset/no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Supported Files/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/UI Layer/FeedList/FeedCellViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedCellViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | /**
13 | ViewModel of `FeedCellView`, composed of elements needed for UI populating, based on `Feed` model
14 | */
15 | class FeedCellViewModel: NSObject, CZFeedViewModelable {
16 | var diffId: String {
17 | return currentClassName + feed.feedId
18 | }
19 | private(set) var feed: Feed
20 | var isInFeedDetails: Bool = false
21 |
22 | var userName: String? {return feed.user?.userName}
23 | var content: String? {return feed.content}
24 |
25 | var portraitUrl: URL? {
26 | guard let urlStr = feed.user?.portraitUrl else {return nil}
27 | return URL(string: urlStr)
28 | }
29 | var imageUrl: URL? {
30 | guard let urlStr = feed.imageInfo?.url else {return nil}
31 | return URL(string: urlStr)
32 | }
33 | var likesCount: Int {
34 | return feed.likesCount
35 | }
36 | var userHasLiked: Bool {
37 | return feed.userHasLiked
38 | }
39 |
40 | required init(_ feed: Feed) {
41 | self.feed = feed
42 | super.init()
43 | }
44 |
45 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
46 | guard let object = object as? FeedCellViewModel else {return false}
47 | return feed.isEqual(toDiffableObj: object.feed) &&
48 | isInFeedDetails == object.isInFeedDetails
49 | }
50 |
51 | func copy(with zone: NSZone?) -> Any {
52 | let feedCopy = feed.copy() as! Feed
53 | return FeedCellViewModel(feedCopy)
54 | }
55 | }
56 |
57 | extension FeedCellViewModel: StateProtocol {
58 | func reduce(action: CZActionProtocol) -> Self {
59 | return self
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/UI Layer/FeedList/FeedListActionHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedListActionHandler.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 7/14/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CZUtils
11 | import ReactiveListViewKit
12 |
13 | protocol FeedListActionHandlerCoordinator {}
14 |
15 | /**
16 | Action handler for `FeedListViewController`
17 |
18 | Coordinator pattern decouples user action handling from ViewController to make it less massive
19 | */
20 | class FeedListActionHandler: NSObject, StoreObserverProtocol {
21 |
22 | var coordinator: FeedListActionHandlerCoordinator?
23 |
24 | // MARK: - StoreObserverProtocol
25 |
26 | func storeDidUpdate(state: FeedListState,
27 | previousState: FeedListState?) {
28 | // No-op.
29 | }
30 |
31 | /// Handles the store `action`.
32 | func didReceiveStoreAction(_ action: CZActionProtocol) {
33 | dbgPrintWithFunc(self, "\(action)")
34 |
35 | switch action {
36 | case let CZFeedListViewAction.selectedCell(indexPath, feedModel):
37 | break
38 | default:
39 | break
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/UI Layer/FeedList/HotUsers/HotUserCellViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HotUserCellViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | class HotUserCellViewModel: NSObject, CZFeedViewModelable {
13 | var diffId: String {
14 | return currentClassName + (user.userId ?? "")
15 | }
16 | private(set) var user: User
17 | var userName: String? {return user.userName}
18 | var fullName: String? {return user.fullName}
19 |
20 | var portraitUrl: URL? {
21 | guard let urlStr = user.portraitUrl else {return nil}
22 | return URL(string: urlStr)
23 | }
24 |
25 | required init(_ user: User) {
26 | self.user = user
27 | super.init()
28 | }
29 |
30 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
31 | guard let object = object as? HotUserCellViewModel else {return false}
32 | return user.isEqual(toDiffableObj: object.user)
33 | }
34 |
35 | func copy(with zone: NSZone?) -> Any {
36 | let userCopy = user.copy() as! User
37 | return HotUserCellViewModel(userCopy)
38 | }
39 | }
40 |
41 | extension HotUserCellViewModel: StateProtocol {
42 | func reduce(action: CZActionProtocol) -> Self {
43 | return self
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/UI Layer/FeedList/HotUsers/HotUsersCellViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/UI Layer/FeedList/HotUsers/HotUsersCellViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HotUsersCellViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | class HotUsersCellViewModel: NSObject, CZFeedViewModelable {
13 | var diffId: String {
14 | return currentClassName
15 | }
16 | private(set) var users: [User]
17 |
18 | required init(_ users: [User]) {
19 | self.users = users
20 | super.init()
21 | }
22 |
23 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
24 | guard let object = object as? HotUsersCellViewModel else {return false}
25 | return users.isEqual(toDiffableObj: object.users)
26 | }
27 |
28 | func copy(with zone: NSZone?) -> Any {
29 | let usersCopy = users.copy() as! [User]
30 | return HotUsersCellViewModel(usersCopy)
31 | }
32 | }
33 |
34 | extension HotUsersCellViewModel: StateProtocol {
35 | func reduce(action: CZActionProtocol) -> Self {
36 | return self
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemo/Utils/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 7/14/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// Constants of the project
12 | enum Constants {
13 | static let feedListViewInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
14 | static let userStoriesSectionHeight: CGFloat = 40
15 | static let suggestedUsersCellHeight: CGFloat = 110
16 | static let suggestedUsersCellBGColor = UIColor(white: 250.0 / 255.0, alpha: 1)
17 | }
18 |
19 | enum AccessibilityLabel {
20 | static let feedListCollectionView = "feedListCollectionView"
21 | }
22 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemoUITests/ReactiveListViewKitDemoUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKitDemoUITests.swift
3 | // ReactiveListViewKitDemoUITests
4 | //
5 | // Created by Cheng Zhang on 2025/03/29.
6 | //
7 |
8 | import XCTest
9 |
10 | final class ReactiveListViewKitDemoUITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | @MainActor
26 | func testExample() throws {
27 | // UI tests must launch the application that they test.
28 | let app = XCUIApplication()
29 | app.launch()
30 |
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 | }
33 |
34 | @MainActor
35 | func testLaunchPerformance() throws {
36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
37 | // This measures how long it takes to launch your application.
38 | measure(metrics: [XCTApplicationLaunchMetric()]) {
39 | XCUIApplication().launch()
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Example/ReactiveListViewKitDemoUITests/ReactiveListViewKitDemoUITestsLaunchTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKitDemoUITestsLaunchTests.swift
3 | // ReactiveListViewKitDemoUITests
4 | //
5 | // Created by Cheng Zhang on 2025/03/29.
6 | //
7 |
8 | import XCTest
9 |
10 | final class ReactiveListViewKitDemoUITestsLaunchTests: XCTestCase {
11 |
12 | override class var runsForEachTargetApplicationUIConfiguration: Bool {
13 | true
14 | }
15 |
16 | override func setUpWithError() throws {
17 | continueAfterFailure = false
18 | }
19 |
20 | @MainActor
21 | func testLaunch() throws {
22 | let app = XCUIApplication()
23 | app.launch()
24 |
25 | // Insert steps here to perform after app launch but before taking a screenshot,
26 | // such as logging into a test account or navigating somewhere in the app
27 |
28 | let attachment = XCTAttachment(screenshot: app.screenshot())
29 | attachment.name = "Launch Screen"
30 | attachment.lifetime = .keepAlways
31 | add(attachment)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Data Layer/CZMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZMocker.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/12/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | class CZMocker: NSObject {
13 | static let shared = CZMocker()
14 |
15 | var feeds: [Feed] {
16 | let url = Bundle.main.url(forResource: "feeds", withExtension: "json")!
17 | return CodableHelper.decode(url) ?? []
18 | }
19 |
20 | var hotUsers: [User] {
21 | let url = Bundle.main.url(forResource: "users", withExtension: "json")!
22 | return CodableHelper.decode(url) ?? []
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Data Layer/ImageInfo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageInfo.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | /// Model of image info
13 | class ImageInfo: ReactiveListDiffable {
14 | let url: String
15 | let width: Int
16 | let height: Int
17 |
18 | // MARK: - CZListDiffable
19 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
20 | return isEqual(toCodable: object)
21 | }
22 |
23 | // MARK: - NSCopying
24 | func copy(with zone: NSZone? = nil) -> Any {
25 | return codableCopy(with: zone)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Data Layer/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/3/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | /// Model of user
13 | class User: ReactiveListDiffable {
14 | let userId: String
15 | let userName: String
16 | let fullName: String?
17 | let portraitUrl: String?
18 |
19 | enum CodingKeys: String, CodingKey {
20 | case userId = "id"
21 | case userName = "username"
22 | case fullName = "full_name"
23 | case portraitUrl = "profile_picture"
24 | }
25 |
26 | // MARK: - CZListDiffable
27 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
28 | return isEqual(toCodable: object)
29 | }
30 |
31 | // MARK: - NSCopying
32 | func copy(with zone: NSZone? = nil) -> Any {
33 | return codableCopy(with: zone)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/FLUX/FeedListAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedListActions.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | // MARK: - Events
13 |
14 | /// Action that User likes one `Feed`
15 | struct LikeFeedAction: Action {
16 | var feed: Feed
17 | }
18 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/FLUX/SuggestedUserAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SuggestedUserEvent.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/28/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | /// Action that follow/ignore `SuggestedUser`
13 | enum SuggestedUserAction: Action {
14 | case follow(user: User)
15 | case ignore(user: User)
16 | }
17 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/FLUX/UserStoryAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserStoryEvent.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/28/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | /// Action that User selects `UserStory`
13 | enum UserStoryAction: Action {
14 | case selected(user: User)
15 | }
16 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/ListViewUITest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ListViewUITest.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 10/26/18.
6 | // Copyright © 2018 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class ListViewUITest: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 7/14/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 | var window: UIWindow?
14 |
15 | internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | return true
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/CommonCrypto.xcconfig:
--------------------------------------------------------------------------------
1 | MODULEMAP_FILE[sdk=macosx*] = $(SRCROOT)/CommonCrypto/macosx.modulemap
2 | MODULEMAP_FILE[sdk=iphoneos*] = $(SRCROOT)/CommonCrypto/iphoneos.modulemap
3 | MODULEMAP_FILE[sdk=iphonesimulator*] = $(SRCROOT)/CommonCrypto/iphonesimulator.modulemap
4 | MODULEMAP_FILE[sdk=watchos*] = $(SRCROOT)/CommonCrypto/watchos.modulemap
5 | MODULEMAP_FILE[sdk=watchsimulator*] = $(SRCROOT)/CommonCrypto/watchsimulator.modulemap
6 | MODULEMAP_FILE[sdk=appletvos*] = $(SRCROOT)/CommonCrypto/appletvos.modulemap
7 | MODULEMAP_FILE[sdk=appletvsimulator*] = $(SRCROOT)/CommonCrypto/appletvsimulator.modulemap
8 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/appletvos.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/appletvsimulator.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/iphoneos.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/iphonesimulator.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/macosx.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/watchos.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/CommonCrypto/watchsimulator.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/CommonCrypto/README.md:
--------------------------------------------------------------------------------
1 | # CommonCrypto
2 | CommonCrypto module wrapper project for Xcode 8 and Swift 3
3 |
4 | # How to use
5 |
6 | ## Adding as subproject into Xcode
7 | Clone / download this project. Add this project as a subproject to your swift framework / app by dragging .xcodeproj file a little below your main project in Xcode.
8 |
9 | ## Adding as \*.framework binaries
10 | Build binary for each target which produces CommonCrypto.framework for each platform, then copy those \*.framework files with their parent folders into your parent project via dropping them to Xcode and applying “Copy items if needed” checkbox (unselect any target membership though). If you drop them without folders Xcode will not allow to do that because their names are equivalent.
11 |
12 | After you added it as a subproject or as binary frameworks into Xcode, just use "import CommonCrypto" statement in your target swift classes, now underlying CommonCrypto C API is available.
13 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/ColorFrame.imageset/ColorFrameFull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/ColorFrame.imageset/ColorFrameFull.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/ColorFrame.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "ColorFrameFull.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_chat_1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_chat_1-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_chat_1-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/ic_chat_1-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/ic_chat_1-1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/ic_chat_1-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/ic_chat_1-2.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/ic_chat_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Comment.imageset/ic_chat_1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "instagramTitle-1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "instagramTitle-2.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "instagramTitle.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/instagramTitle-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/instagramTitle-1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/instagramTitle-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/instagramTitle-2.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/instagramTitle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/InstagramTitle.imageset/instagramTitle.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_like.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_like-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_like-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/ic_like-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/ic_like-1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/ic_like-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/ic_like-2.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/ic_like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Like.imageset/ic_like.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_liked-2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_liked-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_liked.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/ic_liked-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/ic_liked-1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/ic_liked-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/ic_liked-2.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/ic_liked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Liked.imageset/ic_liked.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Menu.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_menu.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_menu-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_menu-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Menu.imageset/ic_menu-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Menu.imageset/ic_menu-1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Menu.imageset/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Menu.imageset/ic_menu.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/PostImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "placeholder.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/PostImage.imageset/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/PostImage.imageset/placeholder.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_share_file.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_share_file-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_share_file-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/ic_share_file-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/ic_share_file-1.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/ic_share_file-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/ic_share_file-2.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/ic_share_file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/Share.imageset/ic_share_file.png
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/noUser.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/noUser.imageset/no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geekaurora/ReactiveListViewKit/3e94cde3afd99cf8f6f94ebea9932f60d478a1ad/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/Assets.xcassets/noUser.imageset/no-user-image-square-9f6a473a32ad639f619216331d10d61ce1b35c9271d5683920960e1a5ee45bb8.jpg
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Supported Files/Resources/users copy.json:
--------------------------------------------------------------------------------
1 | [{
2 | "full_name": "Diane",
3 | "username": "fallinlight",
4 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/fallinlight.jpg",
5 | "id": "0"
6 | }, {
7 | "full_name": "Caeli",
8 | "username": "caeliyt",
9 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/caeliyt.jpg",
10 | "id": "1"
11 | }, {
12 | "full_name": "Pixlr",
13 | "username": "pixlr",
14 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/pixlr.jpg",
15 | "id": "2"
16 | }, {
17 | "full_name": "Zayn Malik",
18 | "username": "zayn",
19 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/zayn.jpg",
20 | "id": "3"
21 | }, {
22 | "full_name": "Martin Garrix",
23 | "username": "martingarrix",
24 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/martingarrix.jpg",
25 | "id": "4"
26 | }, {
27 | "full_name": "Mariale Marrero",
28 | "username": "mariale",
29 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/mariale.jpg",
30 | "id": "5"
31 | }, {
32 | "full_name": "Picsart Editor",
33 | "username": "picsart_ediitor",
34 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/picsart_ediitor.jpg",
35 | "id": "6"
36 | }, {
37 | "full_name": "Tutorial edit PicsArt",
38 | "username": "picsart_indo",
39 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/picsart_indo.jpg",
40 | "id": "7"
41 | }, {
42 | "full_name": "Annegien",
43 | "username": "fetching_tigerss",
44 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/fetching_tigerss.jpg",
45 | "id": "8"
46 | }, {
47 | "full_name": "Lesslie Polinesia",
48 | "username": "ppteamlesslie",
49 | "profile_picture": "https://d37t5b145o82az.cloudfront.net/portriats/ppteamlesslie.jpg",
50 | "id": "9"
51 | }]
52 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/UI Layer/FeedList/FeedCellViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedCellViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 | import ReactiveListViewKit
11 |
12 | /**
13 | ViewModel of `FeedCellView`, composed of elements needed for UI populating, based on `Feed` model
14 | */
15 | class FeedCellViewModel: NSObject, CZFeedViewModelable {
16 | var diffId: String {
17 | return currentClassName + feed.feedId
18 | }
19 | private(set) var feed: Feed
20 | var isInFeedDetails: Bool = false
21 |
22 | var userName: String? {return feed.user?.userName}
23 | var content: String? {return feed.content}
24 |
25 | var portraitUrl: URL? {
26 | guard let urlStr = feed.user?.portraitUrl else {return nil}
27 | return URL(string: urlStr)
28 | }
29 | var imageUrl: URL? {
30 | guard let urlStr = feed.imageInfo?.url else {return nil}
31 | return URL(string: urlStr)
32 | }
33 | var likesCount: Int {
34 | return feed.likesCount
35 | }
36 | var userHasLiked: Bool {
37 | return feed.userHasLiked
38 | }
39 |
40 | required init(_ feed: Feed) {
41 | self.feed = feed
42 | super.init()
43 | }
44 |
45 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
46 | guard let object = object as? FeedCellViewModel else {return false}
47 | return feed.isEqual(toDiffableObj: object.feed) &&
48 | isInFeedDetails == object.isInFeedDetails
49 | }
50 |
51 | func copy(with zone: NSZone?) -> Any {
52 | let feedCopy = feed.copy() as! Feed
53 | return FeedCellViewModel(feedCopy)
54 | }
55 | }
56 |
57 | extension FeedCellViewModel: State {
58 | func reduce(action: Action) {
59 | // No-op.
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/UI Layer/FeedList/FeedListActionHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedListActionHandler.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 7/14/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | protocol FeedListActionHandlerCoordinator {}
13 |
14 | /**
15 | Action handler for `FeedListViewController`
16 |
17 | Coordinator pattern decouples user action handling from ViewController to make it less massive
18 | */
19 | class FeedListActionHandler: NSObject, Middleware {
20 |
21 | var coordinator: FeedListActionHandlerCoordinator?
22 |
23 | // MARK: - Middleware
24 |
25 | func process(action: Action, state: FeedListState) {
26 | dbgPrint("Received action: \(action)")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/UI Layer/FeedList/HotUsers/HotUserCellViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HotUserCellViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | class HotUserCellViewModel: NSObject, CZFeedViewModelable {
13 | var diffId: String {
14 | return currentClassName + (user.userId ?? "")
15 | }
16 | private(set) var user: User
17 | var userName: String? {return user.userName}
18 | var fullName: String? {return user.fullName}
19 |
20 | var portraitUrl: URL? {
21 | guard let urlStr = user.portraitUrl else {return nil}
22 | return URL(string: urlStr)
23 | }
24 |
25 | required init(_ user: User) {
26 | self.user = user
27 | super.init()
28 | }
29 |
30 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
31 | guard let object = object as? HotUserCellViewModel else {return false}
32 | return user.isEqual(toDiffableObj: object.user)
33 | }
34 |
35 | func copy(with zone: NSZone?) -> Any {
36 | let userCopy = user.copy() as! User
37 | return HotUserCellViewModel(userCopy)
38 | }
39 | }
40 |
41 | extension HotUserCellViewModel: State {
42 | func reduce(action: Action) {
43 | // no-op
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/UI Layer/FeedList/HotUsers/HotUsersCellViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/UI Layer/FeedList/HotUsers/HotUsersCellViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HotUsersCellViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 3/4/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ReactiveListViewKit
11 |
12 | class HotUsersCellViewModel: NSObject, CZFeedViewModelable {
13 | var diffId: String {
14 | return currentClassName
15 | }
16 | private(set) var users: [User]
17 |
18 | required init(_ users: [User]) {
19 | self.users = users
20 | super.init()
21 | }
22 |
23 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
24 | guard let object = object as? HotUsersCellViewModel else {return false}
25 | return users.isEqual(toDiffableObj: object.users)
26 | }
27 |
28 | func copy(with zone: NSZone?) -> Any {
29 | let usersCopy = users.copy() as! [User]
30 | return HotUsersCellViewModel(usersCopy)
31 | }
32 | }
33 |
34 | extension HotUsersCellViewModel: State {
35 | func reduce(action: Action) {
36 | // no-op
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CZNetError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZNetError.swift
3 | // CZNetworking
4 | //
5 | // Created by Cheng Zhang on 12/9/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 |
11 | /// Network Error class
12 | open class CZNetError: CZError {
13 | fileprivate static let domain = "CZNetworking"
14 | public static let `default` = CZNetError("Network Error")
15 | public static let returnType = CZNetError("ReturnType Error")
16 |
17 | public init(_ description: String? = nil, code: Int = 99) {
18 | super.init(domain: CZNetError.domain, code: code, description: description)
19 | }
20 |
21 | required public init?(coder aDecoder: NSCoder) {
22 | super.init(coder: aDecoder)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CZNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // CZNetworking.h
3 | // CZNetworking
4 | //
5 | // Created by Cheng Zhang on 12/9/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for CZNetworking.
12 | FOUNDATION_EXPORT double CZNetworkingVersionNumber;
13 |
14 | //! Project version string for CZNetworking.
15 | FOUNDATION_EXPORT const unsigned char CZNetworkingVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/CommonCrypto.xcconfig:
--------------------------------------------------------------------------------
1 | MODULEMAP_FILE[sdk=macosx*] = $(SRCROOT)/CommonCrypto/macosx.modulemap
2 | MODULEMAP_FILE[sdk=iphoneos*] = $(SRCROOT)/CommonCrypto/iphoneos.modulemap
3 | MODULEMAP_FILE[sdk=iphonesimulator*] = $(SRCROOT)/CommonCrypto/iphonesimulator.modulemap
4 | MODULEMAP_FILE[sdk=watchos*] = $(SRCROOT)/CommonCrypto/watchos.modulemap
5 | MODULEMAP_FILE[sdk=watchsimulator*] = $(SRCROOT)/CommonCrypto/watchsimulator.modulemap
6 | MODULEMAP_FILE[sdk=appletvos*] = $(SRCROOT)/CommonCrypto/appletvos.modulemap
7 | MODULEMAP_FILE[sdk=appletvsimulator*] = $(SRCROOT)/CommonCrypto/appletvsimulator.modulemap
8 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/appletvos.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/appletvsimulator.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/iphoneos.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/iphonesimulator.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/macosx.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/watchos.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/CommonCrypto/watchsimulator.modulemap:
--------------------------------------------------------------------------------
1 | module CommonCrypto [system] {
2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/CommonCrypto/README.md:
--------------------------------------------------------------------------------
1 | # CommonCrypto
2 | CommonCrypto module wrapper project for Xcode 8 and Swift 3
3 |
4 | # How to use
5 |
6 | ## Adding as subproject into Xcode
7 | Clone / download this project. Add this project as a subproject to your swift framework / app by dragging .xcodeproj file a little below your main project in Xcode.
8 |
9 | ## Adding as \*.framework binaries
10 | Build binary for each target which produces CommonCrypto.framework for each platform, then copy those \*.framework files with their parent folders into your parent project via dropping them to Xcode and applying “Copy items if needed” checkbox (unselect any target membership though). If you drop them without folders Xcode will not allow to do that because their names are equivalent.
11 |
12 | After you added it as a subproject or as binary frameworks into Xcode, just use "import CommonCrypto" statement in your target swift classes, now underlying CommonCrypto C API is available.
13 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworking/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // CZNetworking
4 | //
5 | // Created by Cheng Zhang on 12/11/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CommonCrypto
11 |
12 | public extension String {
13 | /// MD5 HashValue: Should #import in your Bridging-Header file
14 | public var MD5: String {
15 | let length = Int(CC_MD5_DIGEST_LENGTH)
16 | var digest = [UInt8](repeating: 0, count: length)
17 |
18 | if let d = self.data(using: String.Encoding.utf8) {
19 | _ = d.withUnsafeBytes { (body: UnsafePointer) in
20 | CC_MD5(body, CC_LONG(d.count), &digest)
21 | }
22 | }
23 |
24 | return (0..
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworkingTests/CZNetworkingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZNetworkingTests.swift
3 | // CZNetworkingTests
4 | //
5 | // Created by Cheng Zhang on 12/9/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CZNetworking
11 |
12 | class CZNetworkingTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/CZNetworkingTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Cheng Zhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/CZNetworking/README.md:
--------------------------------------------------------------------------------
1 | # CZNetworking
2 |
3 | Elegant progressive asynchronous HTTP request flow management framework.
4 |
5 | * Supports GET/PUT/POST/DELETE
6 | * Supports success/failure/pregress callback closure
7 |
8 | ### Instagram Demo - [Github](https://github.com/showt1me/CZInstagram)
9 | Implemented on top of **CZNetworking**
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitDemo/Utils/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // ReactiveListViewKitDemo
4 | //
5 | // Created by Cheng Zhang on 7/14/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// Constants of the project
12 | enum Constants {
13 | static let feedListViewInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
14 | static let userStoriesSectionHeight: CGFloat = 40
15 | static let suggestedUsersCellHeight: CGFloat = 110
16 | static let suggestedUsersCellBGColor = UIColor(white: 250.0 / 255.0, alpha: 1)
17 | }
18 |
19 | enum AccessibilityLabel {
20 | static let feedListCollectionView = "feedListCollectionView"
21 | }
22 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitUITests/Utils/CZUITest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZUITest.swift
3 | //
4 | // Created by Cheng Zhang on 2/6/17.
5 | // Copyright © 2017 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import KIF
9 |
10 | class CZUITest: KIFTestCase {
11 | override func setUp() {
12 | super.setUp()
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/Example/ReactiveListViewKitUITests/Utils/KIFUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KIFUtils.swift
3 | //
4 | // Created by Cheng Zhang on 2/6/17.
5 | // Copyright © 2017 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import KIF
9 |
10 | extension XCTestCase {
11 | func tester(file : String = #file, _ line : Int = #line) -> KIFUITestActor {
12 | return KIFUITestActor(inFile: file, atLine: line, delegate: self)
13 | }
14 |
15 | func system(file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
16 | return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
17 | }
18 | }
19 |
20 | extension KIFTestActor {
21 | func tester(file : String = #file, _ line : Int = #line) -> KIFUITestActor {
22 | return KIFUITestActor(inFile: file, atLine: line, delegate: self)
23 | }
24 |
25 | func system(file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
26 | return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
27 | }
28 | }
29 |
30 | extension KIFUITestActor {
31 | /**
32 | Return View with given `accessibilityIdentifier` if present, nil otherwise
33 |
34 | - warning: Should specify accessibilityIdentifier, instead of accessibilityLabel
35 | */
36 | func view(withAccessibilityIdentifier accessibilityIdentifier: String) -> UIView? {
37 | var view: UIView?
38 | wait(for: nil, view: &view, withIdentifier: accessibilityIdentifier, tappable: false)
39 | return view
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'ReactiveListViewKit'
3 | s.version = '1.2.4'
4 | s.summary = 'MVVM + FLUX Reactive Facade ViewKit, eliminates Massive View Controller in unidirectional action/state flow manner.'
5 |
6 | s.description = <<-DESC
7 | - MVVM + FLUX reactive facade ViewKit for feed based app development
8 | - Eliminates Massive View Controller in unidirectional Action/State flow manner
9 | DESC
10 |
11 | s.homepage = 'https://github.com/geekaurora/ReactiveListViewKit'
12 | #s.screenshots = ''
13 | s.license = { :type => 'MIT', :file => 'LICENSE' }
14 | s.author = { 'geekaurora' => 'showt2me@gmail.com' }
15 | s.source = { :git => 'https://github.com/geekaurora/ReactiveListViewKit.git', :tag => s.version.to_s }
16 | # s.social_media_url = 'https://twitter.com/'
17 |
18 | s.ios.deployment_target = '10.0'
19 | s.source_files = 'ReactiveListViewKit/ReactiveListViewKit/**/*'
20 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3' }
21 |
22 | # s.resource_bundles = {
23 | # 'ReactiveListViewKit' => ['ReactiveListViewKit/Assets/*.png']
24 | # }
25 |
26 | # s.public_header_files = 'Pod/Classes/**/*.h'
27 |
28 | s.frameworks = 'UIKit'
29 | s.dependency 'CZUtils'
30 |
31 | end
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/CZFeedDetailsModel.swift:
--------------------------------------------------------------------------------
1 | ///
2 | // CZFeedDetailsModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/5/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// Base building block for `CZFeedDetailsFacadeView`, highly decouples View/ViewModel layers
12 | ///
13 | /// Composed of:
14 | /// - viewClass: CZFeedCellViewSizeCalculatable
15 | /// - voewModel: CZFeedViewModelable
16 | ///
17 | public typealias CZFeedDetailsModel = CZFeedModel
18 |
19 | //public class CZFeedDetailsModel: NSObject, CZFeedModelable {
20 | // public let viewClass: CZFeedCellViewable.Type
21 | // public let viewModel: CZFeedViewModelable
22 | //
23 | // public required init(viewClass: CZFeedCellViewable.Type,
24 | // viewModel: CZFeedViewModelable) {
25 | // self.viewClass = viewClass
26 | // self.viewModel = viewModel
27 | // super.init()
28 | // }
29 | //
30 | // public func isEqual(toDiffableObj object: AnyObject) -> Bool {
31 | // guard let object = object as? CZFeedDetailsModel else {return false}
32 | // return viewClass == object.viewClass &&
33 | // viewModel.isEqual(toDiffableObj: object.viewModel)
34 | // }
35 | //
36 | // public func copy(with zone: NSZone? = nil) -> Any {
37 | // let viewClassCopy = viewClass
38 | // let viewModelCopy = viewModel.copy(with: zone) as! CZFeedViewModelable
39 | // return type(of: self).init(
40 | // viewClass: viewClassCopy,
41 | // viewModel: viewModelCopy)
42 | // }
43 | //}
44 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/CZFeedDetailsViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedDetailsViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/3/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | ViewModel/State class for `CZFeedDetailsFacadeView`
13 | */
14 | open class CZFeedDetailsViewModel: NSObject, NSCopying {
15 |
16 | private var _feedModels: [CZFeedModelable]
17 | required public init(feedModels: [CZFeedModelable]? = nil) {
18 | _feedModels = feedModels ?? []
19 | }
20 |
21 | public func batchUpdate(with feedModels: [CZFeedModelable]) {
22 | _feedModels.removeAll()
23 | _feedModels.append(contentsOf: feedModels)
24 | }
25 |
26 | // MARK: - NSCopying
27 | public func copy(with zone: NSZone? = nil) -> Any {
28 | let feedModels = _feedModels.compactMap{ $0.copy(with: nil) as? CZFeedModelable}
29 | let viewModel = type(of: self).init(feedModels: feedModels)
30 | return viewModel
31 | }
32 |
33 | public var feedModels: [CZFeedDetailsModel] {
34 | return (_feedModels as? [CZFeedDetailsModel]) ?? []
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/CZFeedListViewAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedViewAction.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/10/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Action handler closure
13 | */
14 | public typealias OnAction = (_ action: Action) -> Void
15 |
16 | /**
17 | General ViewAction
18 | */
19 | public typealias CZViewAction = Action
20 |
21 | public struct BaseState: State {
22 | public func reduce(action: Action) {}
23 | }
24 |
25 | /**
26 | ViewAction for container feedListView
27 | */
28 | public enum CZFeedListViewAction: CZViewAction {
29 | case selectedCell(CZFeedModel)
30 | case loadMore
31 | case pullToRefresh(isFirst: Bool)
32 | case prefetch([IndexPath])
33 | case cancelPrefetching([IndexPath])
34 | case visibleIndexPathsChanged(newValue: [IndexPath])// (oldIndexPaths, newIndexPaths)
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/CZFeedViewModelable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedViewModelable.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/5/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 |
11 | /**
12 | Fundamental protocol for CellView of `CZFeedListFacadeView`/`CZFeedDetailsFacadeView`
13 | */
14 | public protocol CZFeedViewModelable: class, NSObjectProtocol, CZListDiffable, NSCopying {
15 | /// `diffId` is used for diff algorithm of batch update, verify whether two involved viewModels equal
16 | var diffId: String {get}
17 |
18 | var viewHeight: CGFloat {get}
19 |
20 | func isEqual(toDiffableObj object: AnyObject) -> Bool
21 |
22 | func copy(with zone: NSZone?) -> Any
23 | }
24 |
25 | public extension CZFeedViewModelable {
26 | var diffId: String {
27 | currentClassName
28 | }
29 |
30 | var viewHeight: CGFloat {
31 | -1
32 | }
33 | }
34 |
35 | public extension CZFeedViewModelable {
36 | var currentClassName: String {
37 | return NSStringFromClass(type(of: self))
38 | }
39 | }
40 |
41 | /// Fundamental protocol for ViewModel involved in ListView, verify whether two viewModels equal
42 | public protocol CZListDiffable {
43 | /// Workaround of `Equatable`, because `Equatable` uses associatedType `Self`, which makes `Equatable` can only be used as generic constraint
44 | func isEqual(toDiffableObj object: AnyObject) -> Bool
45 | }
46 |
47 | /// Fundamental protocol composition of reactive listDiffable model
48 | /// - note: The protocol only requires conformance of `Codable` and `NSCopying`, other protocols are conformed by categories automatically.
49 | public typealias ReactiveListDiffable = Codable & NSCopying & CustomStringConvertible & CZListDiffable
50 |
51 | public typealias CZListDiffableObject = CZListDiffable & AnyObject
52 |
53 | // MARK: CZListDiffable
54 | public extension Encodable where Self: Decodable {
55 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
56 | return isEqual(toCodable: object)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/CZReactiveFeedDetailsFacadeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZReactiveFeedDetailsFacadeView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/11/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private var kViewModelObserverContext: Int = 0
12 |
13 | /**
14 | Reactive view class of `FeedDetailsFacadeView`, supports FLUX pattern
15 | */
16 | open class CZReactiveFeedDetailsFacadeView: CZFeedDetailsFacadeView {
17 | var store: Store?
18 | public override var onAction: OnAction? {
19 | get {
20 | guard let store = store else { return super.onAction }
21 | return {action in store.dispatch(action: action) }
22 | }
23 | set { super.onAction = newValue }
24 | }
25 |
26 | public init(containerViewController: UIViewController? = nil,
27 | store: Store? = nil,
28 | onAction: OnAction? = nil) {
29 | super.init(containerViewController: containerViewController, onAction: onAction)
30 | self.store = store
31 | }
32 | public required init?(coder: NSCoder) {
33 | super.init(coder: coder)
34 | }
35 |
36 | public override func setup() {
37 | super.setup()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/CZReactiveFeedListFacadeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZReactiveFeedListFacadeView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/11/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Reactive view class of `FeedListFacadeView`, supports FLUX pattern
13 | */
14 | open class CZReactiveFeedListFacadeView: CZFeedListFacadeView {
15 |
16 | let store: Store
17 |
18 | public init(store: Store,
19 | sectionModelsTransformer: @escaping SectionModelsTransformer,
20 | parentViewController: UIViewController? = nil,
21 | loadMoreThreshold: Int = CZFeedListFacadeView.kLoadMoreThreshold,
22 | minimumLineSpacing: CGFloat = ReactiveListViewKit.minimumLineSpacing) {
23 | self.store = store
24 | let onAction = { (action: Action) in
25 | store.dispatch(action: action)
26 | }
27 | super.init(sectionModelsTransformer: sectionModelsTransformer,
28 | onAction: onAction,
29 | parentViewController: parentViewController,
30 | loadMoreThreshold: loadMoreThreshold)
31 | }
32 |
33 | public required init?(coder: NSCoder) { fatalError("Must call designated initializer.") }
34 | }
35 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/TemplateViews/CZDividerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZDividerView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/16/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Convenience divider view class
13 | */
14 | public final class CZDividerView: UIView {
15 | private let size: CGFloat
16 | private let bgColor: UIColor
17 |
18 | public init(size: CGFloat = 1,
19 | backgroudColor: UIColor = ReactiveListViewKit.GreyDividerColor) {
20 | self.size = size
21 | self.bgColor = backgroudColor
22 | super.init(frame: .zero)
23 | setup()
24 | }
25 |
26 | public required init?(coder: NSCoder) {
27 | fatalError("Must call designated initializer.")
28 | }
29 | }
30 |
31 | private extension CZDividerView {
32 | func setup() {
33 | translatesAutoresizingMaskIntoConstraints = false
34 | backgroundColor = self.bgColor
35 | let sizeContrait = heightAnchor.constraint(equalToConstant: size)
36 | sizeContrait.priority = UILayoutPriority(rawValue: 749)
37 | sizeContrait.isActive = true
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/TemplateViews/CZFeedListSupplementaryView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedListSupplementaryView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/7/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Convenience class of SectionHeaderView/SectionFooterView
13 | */
14 | open class CZFeedListSupplementaryView: UICollectionReusableView {
15 | open override var reuseIdentifier: String? {
16 | return type(of: self).reuseId
17 | }
18 | private var model: CZFeedModel?
19 | private var contentView: CZFeedCellViewSizeCalculatable?
20 | public static var reuseId: String {
21 | return NSStringFromClass(object_getClass(self)!)
22 | }
23 | open func config(with model: CZFeedModel,
24 | onAction: OnAction?) {
25 | defer {
26 | self.model = model
27 | contentView?.config(with: model.viewModel)
28 | }
29 | // Reset contentView if contentViewClass differs from the current one
30 | if let contentView = contentView,
31 | let currModel = self.model,
32 | currModel.viewClass != model.viewClass {
33 | (contentView as? UIView)?.removeFromSuperview()
34 | self.contentView = nil
35 | }
36 | if contentView == nil {
37 | self.contentView = model.viewClass.init(viewModel: model.viewModel, onAction: onAction)
38 | guard let contentView = self.contentView as? UIView else {
39 | assertionFailure("\(model.viewClass) should be subClass of UIView!")
40 | return
41 | }
42 | contentView.translatesAutoresizingMaskIntoConstraints = false
43 | contentView.isUserInteractionEnabled = false
44 | addSubview(contentView)
45 | contentView.overlayOnSuperview()
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/Utils/Array+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array+Extension.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/15/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension Array where Element: CZListDiffableObject {
12 | /**
13 | Check whether elements in two arrays equal
14 | */
15 | public func isEqual(toDiffableObj object: Any) -> Bool {
16 | guard let object = object as? [Element],
17 | count == object.count else {
18 | return false
19 | }
20 | return (0.. Bool {
14 | switch(obj1, obj2) {
15 | case let (obj1 as CZListDiffableObject, obj2 as CZListDiffableObject):
16 | return obj1.isEqual(toDiffableObj: obj2)
17 | default:
18 | return (obj1 == nil && obj2 == nil)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/Utils/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKitConstants.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/2/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Constants of ReactiveListViewKit
13 | */
14 | public enum ReactiveListViewKit {
15 | public static var isDebugMode = true
16 | public static var isIncrementalUpdateEnabled = true
17 | public static var useGCD = false
18 |
19 | // MARK: - Self Sizing Cells
20 |
21 | public static var enableSelfSizingCellsForVerticalOrientation = true
22 | public static var enableSelfSizingCellsForHorizontalOrientation = true
23 |
24 | public static let ClearBGColor = UIColor.clear
25 | public static let GreyBGColor = UIColor(white: 240.0 / 255.0, alpha: 1.0)
26 | public static let GreyDividerColor = UIColor(white: 217.0 / 255.0, alpha: 1.0)
27 | public static let minimumLineSpacing: CGFloat = 10
28 | public static let minimumInteritemSpacing: CGFloat = 10
29 | public static let sectionInset = UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 0)
30 |
31 | public enum FeedListSupplementaryTextView {
32 | public static let inset = UIEdgeInsets(top: 8, left: 10, bottom: 3, right: 10)
33 | public static let titleFont = UIFont.boldSystemFont(ofSize: 14)
34 | public static let titleColor = UIColor(white: 0.1, alpha: 1)
35 | public static let actionButtonColor = UIColor(red: 62.0 / 255.0, green: 153 / 255.0, blue: 237 / 255.0, alpha: 1)
36 | }
37 |
38 | public static let horizontalSectionAdapterViewBGColor: UIColor = .clear
39 |
40 | public static let feedListSupplementaryLineHeaderViewInset = UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)
41 | public static let feedListSupplementaryLineFooterViewInset = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0)
42 | }
43 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKit/Utils/ReactiveListViewKitHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKitHelper.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 11/6/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 |
11 | public func dbgPrint(_ item: CustomStringConvertible) {
12 | guard ReactiveListViewKit.isDebugMode else { return }
13 | _dbgPrint(item)
14 | }
15 |
16 | public func PrettyString(_ object: Any) -> String {
17 | guard let object = object as? CustomStringConvertible else {
18 | return ""
19 | }
20 | if let indexSet = object as? IndexSet {
21 | return indexSet.reduce("[") { (prevResult, index) -> String in
22 | prevResult + String(index) + ", "
23 | } + "]"
24 | } else {
25 | return object.description
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKitTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/ReactiveListViewKitTests/Utils/CZListDiff+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZListDiff.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/5/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import ReactiveListViewKit
10 |
11 | extension CZListDiff {
12 | /**
13 | Return empty SectionIndexDiffResult
14 | */
15 | public static var emptyDiffSectionModelIndexes: SectionIndexDiffResult {
16 | let sectionsDiff: [SectionDiffResultKey: Any] = [:]
17 | let rowsDiff: [RowDiffResultKey: [Any]] = [:]
18 | return (sectionsDiff, rowsDiff)
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Cheng Zhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "CZUtils",
8 | platforms: [
9 | .iOS(.v11),
10 | ],
11 | products: [
12 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
13 | .library(
14 | name: "CZUtils",
15 | targets: ["CZUtils"]),
16 | ],
17 | dependencies: [
18 | // Dependencies declare other packages that this package depends on.
19 | // .package(url: /* package url */, from: "1.0.0"),
20 | ],
21 | targets: [
22 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
23 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
24 | .target(
25 | name: "CZUtils",
26 | dependencies: []),
27 | .testTarget(
28 | name: "CZUtilsTests",
29 | dependencies: ["CZUtils"]),
30 | ]
31 | )
32 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/README.md:
--------------------------------------------------------------------------------
1 | # CZUtils
2 |
3 | [](http://cocoapods.org/pods/CZUtils)
4 | [](https://github.com/Carthage/Carthage)
5 | 
6 | [](http://cocoapods.org/pods/CZUtils)
7 | [](http://cocoapods.org/pods/CZUtils)
8 |
9 | ### Powerful toolset for Utils layer
10 |
11 | * CZMutexLock on top of GCD
12 | * NSNullGuard
13 | * MainQueueScheduler
14 | * SwizzlingHelper
15 | * ThreadSafeDictionary
16 | * NibLoadable for UIView/Cell
17 |
18 |
19 | ## Installation
20 |
21 | CZUtils is available through [CocoaPods](http://cocoapods.org). To install
22 | it, simply add the following line to your Podfile:
23 |
24 | ```ruby
25 | pod 'CZUtils'
26 | ```
27 |
28 | And run `pod install` in your work folder.
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZAlertManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZAlertManager.swift
3 | //
4 | // Created by Cheng Zhang on 1/15/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// Convenient helper class for AlertViewController displaying
11 | open class CZAlertManager: NSObject {
12 |
13 | open class func showAlert(title: String? = nil,
14 | message: String,
15 | confirmText: String = "Ok",
16 | confirmHandler: ((UIAlertAction) -> Void)? = nil,
17 | cancelText: String? = nil,
18 | cancelHandler: ((UIAlertAction) -> Void)? = nil,
19 | on viewController: UIViewController? = nil,
20 | completion: (() -> Void)? = nil) {
21 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
22 | let action1 = UIAlertAction(title: confirmText, style: .default, handler: confirmHandler)
23 | alertController.addAction(action1)
24 | if let cancelText = cancelText {
25 | let action2 = UIAlertAction(title: cancelText, style: .cancel, handler: cancelHandler)
26 | alertController.addAction(action2)
27 | }
28 |
29 | guard let presentingViewController = viewController ?? UIApplication.shared.keyWindow?.rootViewController else {
30 | assertionFailure("Couldn't find valid presenting ViewController.")
31 | return
32 | }
33 | presentingViewController.topMost.present(alertController, animated: true, completion: completion)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZDictionary.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZDictionary.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 2018/7/6.
6 | // Copyright © 2019 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public typealias CZDictionary = [AnyHashable : Any]
12 |
13 | public protocol CZDictionaryable {
14 | init(dictionary: CZDictionary)
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZError.swift
3 | //
4 | // Created by Cheng Zhang on 1/10/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Convenience Error class
11 | open class CZError: NSError {
12 | public init(domain: String, code: Int = 99, description: String? = nil) {
13 | var userInfo: [String: Any]? = nil
14 | if let description = description {
15 | userInfo = [NSLocalizedDescriptionKey: description]
16 | }
17 | super.init(domain: domain, code: code, userInfo: userInfo)
18 | }
19 |
20 | required public init?(coder aDecoder: NSCoder) {
21 | super.init(coder: aDecoder)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZFileHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFileHelper.swift
3 | //
4 | // Created by Cheng Zhang on 1/13/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Helper class for file related methods
11 | @objc open class CZFileHelper: NSObject {
12 | public static func getFileSize(_ filePath: String?) -> Int? {
13 | guard let filePath = filePath else {return nil}
14 | do {
15 | let attrs = try FileManager.default.attributesOfItem(atPath: filePath)
16 | let size = attrs[.size] as? Int
17 | return size
18 | } catch {
19 | dbgPrint("Failed to get file size of \(filePath). Error - \(error.localizedDescription)")
20 | }
21 | return nil
22 | }
23 |
24 | @objc public static var documentDirectory: String {
25 | return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZMainQueueScheduler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZMainQueueScheduler.swift
3 | //
4 | // Created by Cheng Zhang on 1/4/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Convenience class for scheduling sync/async execution on main queue
11 | open class CZMainQueueScheduler: NSObject {
12 |
13 | /// Synchronous execution: inferring function returnType with `execution` closure returnType
14 | public class func sync(_ execution: @escaping () -> T) -> T {
15 | if Thread.isMainThread {
16 | return execution()
17 | } else {
18 | return DispatchQueue.main.sync {
19 | execution()
20 | }
21 | }
22 | }
23 |
24 | /// Asynchronous execution
25 | public class func async(execution: @escaping () -> Void ) {
26 | DispatchQueue.main.async {
27 | execution()
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZProMutexLock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZProMutexLock.swift
3 | //
4 | // Created by Cheng Zhang on 2/3/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Mutex lock on top of `pthread_mutex_lock`/`pthread_mutex_unlock`
11 | open class CZProMutexLock: NSObject {
12 | private var mutex = pthread_mutex_t()
13 |
14 | public override init() {
15 | var attr = pthread_mutexattr_t()
16 | guard pthread_mutexattr_init(&attr) == 0 else {
17 | preconditionFailure()
18 | }
19 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)
20 | guard pthread_mutex_init(&mutex, &attr) == 0 else {
21 | preconditionFailure()
22 | }
23 | }
24 |
25 | deinit {
26 | pthread_mutex_destroy(&mutex)
27 | }
28 |
29 | public func withLock(_ closure: () -> T) -> T {
30 | defer {
31 | pthread_mutex_unlock(&mutex)
32 | }
33 | pthread_mutex_lock(&mutex)
34 | return closure()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZTheme.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZTheme.swift
3 | //
4 | // Created by Cheng Zhang on 4/18/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// Common theme settings for projects
11 | public struct CZTheme {
12 | public static let greyDividerColor: CGFloat = 217.0 / 255.0
13 | }
14 |
15 | public extension UIColor {
16 | static let candyGreen = UIColor(red: 67.0/255.0, green: 205.0/255.0, blue: 135.0/255.0, alpha: 1.0)
17 | static let facebookBlue = UIColor(red: 68.0/255.0, green: 105.0/255.0, blue: 176.0/255.0, alpha: 1.0)
18 | static let dividerGrey = UIColor(white: CZTheme.greyDividerColor, alpha: 1)
19 | static let searchBarColor = UIColor(white: 217.0 / 255.0, alpha: 1)
20 | static let searchBarTextGrey = UIColor(white: 127.0 / 255.0, alpha: 1)
21 | static let tabBarTintColor = UIColor(white: 250.0 / 255.0, alpha: 1)
22 | static let tabBarItemTintColor = UIColor(white: 38.0 / 255.0, alpha: 1)
23 | }
24 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Utils.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 2/19/18.
6 | // Copyright © 2018 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public class CZUtils {
12 | public static func dbgPrint(_ item: CustomStringConvertible) {
13 | #if DEBUG
14 | print(item)
15 | #endif
16 | }
17 | }
18 |
19 | public func dbgPrint(_ item: CustomStringConvertible) {
20 | CZUtils.dbgPrint(item)
21 | }
22 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Error+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Error+.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 8/10/19.
6 | // Copyright © 2019 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Error {
12 | var retrievedCode: Int {
13 | return (self as NSError).code
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Array+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array+Extensoin.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 1/26/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Array {
12 | /**
13 | Returns element at specified `safe` index if exists, otherwise nil
14 | */
15 | subscript (safe index: Index) -> Element? {
16 | return indices.contains(index) ? self[index] : nil
17 | }
18 |
19 | /**
20 | Pretty formatted description string
21 | */
22 | var prettyDescription: String {
23 | return Pretty.describing(self)
24 | }
25 | }
26 |
27 | public extension Array where Element: NSCopying {
28 | func copy(with zone: NSZone? = nil) -> Any {
29 | return compactMap{ $0.copy() }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Character+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Character+.swift
3 | //
4 | // Created by Cheng Zhang on 12/30/18.
5 | // Copyright © 2018 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | extension Character {
11 |
12 | public var ascii: Int {
13 | return Int(String(self).unicodeScalars.first!.value)
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Date+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Date+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 5/19/16.
6 | // Copyright © 2016 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Date {
12 | var simpleString: String {
13 | return string(withFormat: "yyyy-MM-dd hh:mm")
14 | }
15 |
16 | var complexString: String {
17 | return string(withFormat: "EEE, dd MMM yyyy hh:mm:ss +zzzz")
18 | }
19 |
20 | func string(withFormat formatterStr: String) -> String {
21 | let dateFormatter = DateFormatter()
22 | dateFormatter.dateFormat = formatterStr
23 | return dateFormatter.string(from: self)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Dictionary+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dictionary+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 1/29/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Dictionary {
12 | /// Retrieve value from `dotedKey`, compatible with multi-dot in keyPath. e.g. "user.profile.fullName"
13 | func value(forDotedKey dotedKey: String) -> Value? {
14 | return value(forSegmentedKey: dotedKey)
15 | }
16 |
17 | /// Retrieve value from `segmentedKey`, compatible with multi-segments separated by `splitter`. e.g. "user.profile.fullName", "user/profile/fullName"
18 | func value(forSegmentedKey segmentedKey: String, splitter: String = ".") -> Value? {
19 | var value: Any? = nil
20 | var dict: Dictionary? = self
21 |
22 | for subkey in segmentedKey.components(separatedBy: splitter) {
23 | guard dict != nil, let subkey = subkey as? Key else {
24 | return nil
25 | }
26 | value = dict?[subkey]
27 | dict = value as? Dictionary
28 | }
29 | return (value is NSNull) ? nil : (value as? Value)
30 | }
31 |
32 | /// Insert key/value pairs with input Dictionary
33 | mutating func insert(_ other: Dictionary) {
34 | for (key, value) in other {
35 | self[key] = value
36 | }
37 | }
38 |
39 | /// Pretty formatted description string
40 | var prettyDescription: String {
41 | return Pretty.describing(self)
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/NSObject+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 5/19/16.
6 | // Copyright © 2016 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Convenient methods of NSObject
13 | */
14 | public extension NSObject {
15 | var className: String {
16 | return NSStringFromClass(type(of: self))
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Set+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dictionary+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 1/29/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Set {
12 |
13 | func compactMap(_ transform: (Element) -> ElementOfResult?) -> [ElementOfResult] {
14 | return Array(self).compactMap(transform)
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIButton+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 3/7/16.
6 | // Copyright © 2016 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private var controlHandlerKey: Int8 = 0
12 | public extension UIButton {
13 | /**
14 | Add self-contained action handler for button
15 | */
16 | func addHandler(for controlEvents: UIControl.Event, handler: @escaping (UIButton) -> ()) {
17 | if let oldTarget = objc_getAssociatedObject(self, &controlHandlerKey) as? CocoaTarget {
18 | self.removeTarget(oldTarget, action: #selector(oldTarget.sendNext), for: controlEvents)
19 | }
20 |
21 | let target = CocoaTarget(handler)
22 | objc_setAssociatedObject(self, &controlHandlerKey, target, .OBJC_ASSOCIATION_RETAIN)
23 | self.addTarget(target, action: #selector(target.sendNext), for: controlEvents)
24 | }
25 |
26 | /**
27 | Set image with tintColor for desired controlState
28 | */
29 | func setImage(_ imageName: String, for controlState: UIControl.State = .normal, tintColor: UIColor) {
30 | let image = UIImage(named: imageName)?.withRenderingMode(.alwaysTemplate)
31 | setImage(image, for: controlState)
32 | self.tintColor = tintColor
33 | }
34 | }
35 |
36 | /**
37 | A target that accepts action messages
38 | */
39 | public final class CocoaTarget: NSObject {
40 | private let action: (T) -> ()
41 |
42 | public init(_ action: @escaping (T) -> ()) {
43 | self.action = action
44 | }
45 |
46 | @objc
47 | public func sendNext(_ receiver: Any?) {
48 | guard let receiver = receiver as? T else {
49 | preconditionFailure("`receiver` isn't expected type.")
50 | }
51 | action(receiver)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIImage+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Extension.swift
3 | //
4 | // Created by Cheng Zhang on 1/12/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 | import ImageIO
10 |
11 | public extension UIImage {
12 | @objc(cropToRect:)
13 | func crop(toRect rect: CGRect) -> UIImage {
14 | let croppedCGImage = self.cgImage!.cropping(to: rect)!
15 | let res = UIImage(cgImage: croppedCGImage)
16 | return res
17 | }
18 |
19 | @objc(cropToSize:)
20 | func crop(toSize size: CGSize) -> UIImage {
21 | var size = size
22 | let ratio = size.height / size.width
23 | if size.width < size.height {
24 | size.width = self.size.width * self.scale
25 | size.height = size.width * ratio
26 | } else {
27 | size.height = self.size.height * self.scale
28 | size.width = size.width * ratio
29 | }
30 | let rect = CGRect(origin: CGPoint(x: (self.size.width * self.scale - size.width) / 2,
31 | y: (self.size.height * self.scale - size.height) / 2),
32 | size: size)
33 | return crop(toRect: rect)
34 | }
35 |
36 | // height / width
37 | @objc(cropToRatio:)
38 | func crop(toRatio ratio: CGFloat) -> UIImage {
39 | var size: CGSize = self.size
40 | if ratio < 1 {
41 | size.width = self.size.width * self.scale
42 | size.height = size.width * ratio
43 | } else {
44 | size.height = self.size.height * self.scale
45 | size.width = size.height / ratio
46 | }
47 | let rect = CGRect(origin: CGPoint(x: (self.size.width * self.scale - size.width) / 2,
48 | y: (self.size.height * self.scale - size.height) / 2),
49 | size: size)
50 | return crop(toRect: rect)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIScreen+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIScreen+Extension.swift
3 | //
4 | // Created by Cheng Zhang on 1/8/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | public extension UIScreen {
11 | static var currSize: CGSize {
12 | return main.bounds.size
13 | }
14 |
15 | static var currWidth: CGFloat {
16 | return currSize.width
17 | }
18 |
19 | static var currHeight: CGFloat {
20 | return currSize.height
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIView+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.swift
3 | //
4 | // Created by Cheng Zhang on 1/12/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// Constants for UIView extensions
11 | public enum UIViewConstants {
12 | public static let fadeInDuration: TimeInterval = 0.4
13 | public static let fadeInAnimationName = "com.tony.animation.fadein"
14 | }
15 |
16 | // MARK: - Corner/Border
17 |
18 | public extension UIView {
19 |
20 | func roundToCircle() {
21 | let width = self.bounds.size.width
22 | layer.cornerRadius = width / 2
23 | layer.masksToBounds = true
24 | }
25 |
26 | func roundCorner(_ cornerRadius: CGFloat = 2,
27 | boarderWidth: CGFloat = 0,
28 | boarderColor: UIColor = .clear,
29 | shadowColor: UIColor = .clear,
30 | shadowOffset: CGSize = .zero,
31 | shadowRadius: CGFloat = 2,
32 | shadowOpacity: Float = 1) {
33 | layer.masksToBounds = true
34 | layer.cornerRadius = cornerRadius
35 | layer.borderColor = boarderColor.cgColor
36 | layer.borderWidth = boarderWidth
37 |
38 | layer.shadowColor = shadowColor.cgColor
39 | layer.shadowOffset = shadowOffset
40 | layer.shadowRadius = shadowRadius
41 | }
42 |
43 | }
44 |
45 | // MARK: - Animations
46 |
47 | public extension UIView {
48 | func fadeIn(animationName: String = UIViewConstants.fadeInAnimationName,
49 | duration: TimeInterval = UIViewConstants.fadeInDuration) {
50 | let transition = CATransition()
51 | transition.duration = duration
52 | transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
53 | transition.type = CATransitionType.fade
54 | layer.add(transition, forKey: animationName)
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Investigation/CriticalSectionLock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CriticalSectionLock.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 11/3/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Convenience mutex lock on top of NSLock
12 | open class CriticalSectionLock: NSLock {
13 | public func execute(_ execution: () -> T) -> T {
14 | lock()
15 | defer {
16 | unlock()
17 | }
18 | return execution()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/RegExHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RegExHelper.swift
3 | //
4 | // Created by Cheng Zhang on 2/18/20.
5 | // Copyright © 2020 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | public class RegExHelper {
11 |
12 | /// Extract variable with RegEx group match name. e.g. "(?.*)
" pattern.
13 | /// - Note: Group name in `pattern` should be 'var'.
14 | public static func extractVariable(_ string: String,
15 | pattern: String,
16 | options: NSRegularExpression.Options = .caseInsensitive,
17 | groupName: String = "var") -> String? {
18 | guard let regex = (try? NSRegularExpression(pattern: pattern, options: options)).assertIfNil,
19 | let match = regex.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)),
20 | let matchedRange = Range(match.range(withName: groupName), in: string) else {
21 | return nil
22 | }
23 | return String(string[matchedRange])
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Supported Files/CZUtils.h:
--------------------------------------------------------------------------------
1 | //
2 | // CZUtils.h
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 11/19/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for CZUtils.
12 | FOUNDATION_EXPORT double CZUtilsVersionNumber;
13 |
14 | //! Project version string for CZUtils.
15 | FOUNDATION_EXPORT const unsigned char CZUtilsVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Supported Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Swizzling.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Swizzling.swift
3 | //
4 | // Created by Cheng Zhang on 12/9/15.
5 | // Copyright © 2015 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Generic swizzling function - workable for subclasses of NSObject
11 | /// NSObject subclass maintains a DispatchTable which maps between method selector and actural IMP
12 | public func swizzling(_ aClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
13 | let originalMethod = class_getInstanceMethod(aClass, originalSelector)
14 | let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)
15 | let didAddMethod = class_addMethod(aClass, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
16 | if didAddMethod {
17 | class_replaceMethod(aClass, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!)!)
18 | } else {
19 | method_exchangeImplementations(originalMethod!, swizzledMethod!)
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Utils/PrettyDescription.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PrettyDescription.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 7/29/19.
6 | // Copyright © 2019 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public class Pretty {
12 |
13 | /**
14 | Return Pretty formatted description for valid JSON object
15 | */
16 | static func describing(_ object: Any) -> String {
17 | do {
18 | let data: Data = try JSONSerialization.data(withJSONObject: object, options: .prettyPrinted)
19 | return String(data: data, encoding: .utf8).assertIfNil ?? ""
20 | } catch {
21 | assertionFailure("Failed to retrieve pretty printed description. error - \(error.localizedDescription)")
22 | return ""
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Tests/CZUtilsTests/CZUtilsTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import CZUtils
3 |
4 | final class CZUtilsTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | XCTAssertEqual(CZUtils().text, "Hello, World!")
10 | }
11 |
12 | static var allTests = [
13 | ("testExample", testExample),
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Tests/CZUtilsTests/TestArray.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestArray.swift
3 | // CZUtilsTests
4 | //
5 | // Created by Cheng Zhang on 7/26/18.
6 | // Copyright © 2018 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CZUtils
11 |
12 | class TestArray: XCTestCase {
13 | func testSafeSubscript() {
14 | let array = [Int](0..<10)
15 |
16 | // Elements within bounds
17 | [0, 3, 9].forEach { index in
18 | let element = array[safe: index]
19 | XCTAssert(element == index, "Unexpected element '\(String(describing: element))' at specified index '\(index)'. Expected value = '\(index)'")
20 | }
21 |
22 | // Elements out of bounds
23 | [-1, 10, 13, 20, 1000].forEach { index in
24 | let element = array[safe: index]
25 | XCTAssert(element == nil, "Unexpected element '\(String(describing: element))' at specified index '\(index)'. Expected value = nil")
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Tests/CZUtilsTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(CZUtilsTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/CZUtils/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import CZUtilsTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += CZUtilsTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Experimental/MERGED_SelfSizingCell/ReactiveListViewKit/Supported Files/ReactiveListViewKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKit.h
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/2/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for ReactiveListViewKit.
12 | FOUNDATION_EXPORT double ReactiveListViewKitVersionNumber;
13 |
14 | //! Project version string for ReactiveListViewKit.
15 | FOUNDATION_EXPORT const unsigned char ReactiveListViewKitVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Cheng Zhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'ReactiveListViewKit'
3 | s.version = '1.2.4'
4 | s.summary = 'MVVM + FLUX Reactive Facade ViewKit, eliminates Massive View Controller in unidirectional action/state flow manner.'
5 |
6 | s.description = <<-DESC
7 | - MVVM + FLUX reactive facade ViewKit for feed based app development
8 | - Eliminates Massive View Controller in unidirectional Action/State flow manner
9 | DESC
10 |
11 | s.homepage = 'https://github.com/geekaurora/ReactiveListViewKit'
12 | #s.screenshots = ''
13 | s.license = { :type => 'MIT', :file => 'LICENSE' }
14 | s.author = { 'geekaurora' => 'showt2me@gmail.com' }
15 | s.source = { :git => 'https://github.com/geekaurora/ReactiveListViewKit.git', :tag => s.version.to_s }
16 | # s.social_media_url = 'https://twitter.com/'
17 |
18 | s.ios.deployment_target = '10.0'
19 | s.source_files = 'ReactiveListViewKit/ReactiveListViewKit/**/*'
20 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3' }
21 |
22 | # s.resource_bundles = {
23 | # 'ReactiveListViewKit' => ['ReactiveListViewKit/Assets/*.png']
24 | # }
25 |
26 | # s.public_header_files = 'Pod/Classes/**/*.h'
27 |
28 | s.frameworks = 'UIKit'
29 | s.dependency 'CZUtils'
30 |
31 | end
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/CZFeedDetailsModel.swift:
--------------------------------------------------------------------------------
1 | ///
2 | // CZFeedDetailsModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/5/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// Base building block for `CZFeedDetailsFacadeView`, highly decouples View/ViewModel layers
12 | ///
13 | /// Composed of:
14 | /// - viewClass: CZFeedCellViewSizeCalculatable
15 | /// - voewModel: CZFeedViewModelable
16 | ///
17 | public typealias CZFeedDetailsModel = CZFeedModel
18 |
19 | //public class CZFeedDetailsModel: NSObject, CZFeedModelable {
20 | // public let viewClass: CZFeedCellViewable.Type
21 | // public let viewModel: CZFeedViewModelable
22 | //
23 | // public required init(viewClass: CZFeedCellViewable.Type,
24 | // viewModel: CZFeedViewModelable) {
25 | // self.viewClass = viewClass
26 | // self.viewModel = viewModel
27 | // super.init()
28 | // }
29 | //
30 | // public func isEqual(toDiffableObj object: AnyObject) -> Bool {
31 | // guard let object = object as? CZFeedDetailsModel else {return false}
32 | // return viewClass == object.viewClass &&
33 | // viewModel.isEqual(toDiffableObj: object.viewModel)
34 | // }
35 | //
36 | // public func copy(with zone: NSZone? = nil) -> Any {
37 | // let viewClassCopy = viewClass
38 | // let viewModelCopy = viewModel.copy(with: zone) as! CZFeedViewModelable
39 | // return type(of: self).init(
40 | // viewClass: viewClassCopy,
41 | // viewModel: viewModelCopy)
42 | // }
43 | //}
44 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/CZFeedDetailsViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedDetailsViewModel.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/3/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | ViewModel/State class for `CZFeedDetailsFacadeView`
13 | */
14 | open class CZFeedDetailsViewModel: NSObject, NSCopying {
15 |
16 | private var _feedModels: [CZFeedModelable]
17 | required public init(feedModels: [CZFeedModelable]? = nil) {
18 | _feedModels = feedModels ?? []
19 | }
20 |
21 | public func batchUpdate(with feedModels: [CZFeedModelable]) {
22 | _feedModels.removeAll()
23 | _feedModels.append(contentsOf: feedModels)
24 | }
25 |
26 | // MARK: - NSCopying
27 | public func copy(with zone: NSZone? = nil) -> Any {
28 | let feedModels = _feedModels.compactMap{ $0.copy(with: nil) as? CZFeedModelable}
29 | let viewModel = type(of: self).init(feedModels: feedModels)
30 | return viewModel
31 | }
32 |
33 | public var feedModels: [CZFeedDetailsModel] {
34 | return (_feedModels as? [CZFeedDetailsModel]) ?? []
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/CZFeedListViewAction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedViewAction.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/10/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | CZActionProtocol handler closure
13 | */
14 | public typealias OnAction = (_ action: CZActionProtocol) -> Void
15 |
16 | /**
17 | General ViewAction
18 | */
19 | public typealias CZViewAction = CZActionProtocol
20 |
21 | public struct BaseState: StateProtocol {
22 | public func reduce(action: CZActionProtocol) -> Self {
23 | return self
24 | }
25 | }
26 |
27 | /**
28 | ViewAction for container feedListView
29 | */
30 | public enum CZFeedListViewAction: CZViewAction {
31 | case selectedCell(IndexPath, CZFeedModel)
32 | case loadMore
33 | case pullToRefresh(isFirst: Bool)
34 | case prefetch([IndexPath])
35 | case cancelPrefetching([IndexPath])
36 | case visibleIndexPathsChanged(newValue: [IndexPath])// (oldIndexPaths, newIndexPaths)
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/CZFeedViewModelable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedViewModelable.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/5/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 |
11 | /**
12 | Fundamental protocol for CellView of `CZFeedListFacadeView`/`CZFeedDetailsFacadeView`
13 | */
14 | public protocol CZFeedViewModelable: class, NSObjectProtocol, CZListDiffable, NSCopying {
15 | /// `diffId` is used for diff algorithm of batch update, verify whether two involved viewModels equal
16 | var diffId: String {get}
17 |
18 | var viewHeight: CGFloat {get}
19 |
20 | func isEqual(toDiffableObj object: AnyObject) -> Bool
21 |
22 | func copy(with zone: NSZone?) -> Any
23 | }
24 |
25 | public extension CZFeedViewModelable {
26 | var diffId: String {
27 | currentClassName
28 | }
29 |
30 | var viewHeight: CGFloat {
31 | -1
32 | }
33 | }
34 |
35 | public extension CZFeedViewModelable {
36 | var currentClassName: String {
37 | return NSStringFromClass(type(of: self))
38 | }
39 | }
40 |
41 | /// Fundamental protocol for ViewModel involved in ListView, verify whether two viewModels equal
42 | public protocol CZListDiffable {
43 | /// Workaround of `Equatable`, because `Equatable` uses associatedType `Self`, which makes `Equatable` can only be used as generic constraint
44 | func isEqual(toDiffableObj object: AnyObject) -> Bool
45 | }
46 |
47 | /// Fundamental protocol composition of reactive listDiffable model
48 | /// - note: The protocol only requires conformance of `Codable` and `NSCopying`, other protocols are conformed by categories automatically.
49 | public typealias ReactiveListDiffable = Codable & NSCopying & CustomStringConvertible & CZListDiffable
50 |
51 | public typealias CZListDiffableObject = CZListDiffable & AnyObject
52 |
53 | // MARK: CZListDiffable
54 | public extension Encodable where Self: Decodable {
55 | func isEqual(toDiffableObj object: AnyObject) -> Bool {
56 | return isEqual(toCodable: object)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/CZReactiveFeedDetailsFacadeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZReactiveFeedDetailsFacadeView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/11/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private var kViewModelObserverContext: Int = 0
12 |
13 | /**
14 | Reactive view class of `FeedDetailsFacadeView`, supports FLUX pattern
15 | */
16 | open class CZReactiveFeedDetailsFacadeView: CZFeedDetailsFacadeView {
17 | var store: Store?
18 | public override var onAction: OnAction? {
19 | get {
20 | guard let store = store else { return super.onAction }
21 | return {action in store.dispatch(action: action) }
22 | }
23 | set { super.onAction = newValue }
24 | }
25 |
26 | public init(containerViewController: UIViewController? = nil,
27 | store: Store? = nil,
28 | onAction: OnAction? = nil) {
29 | super.init(containerViewController: containerViewController, onAction: onAction)
30 | self.store = store
31 | }
32 | public required init?(coder: NSCoder) {
33 | super.init(coder: coder)
34 | }
35 |
36 | public override func setup() {
37 | super.setup()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/CZReactiveFeedListFacadeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZReactiveFeedListFacadeView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/11/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Reactive view class of `FeedListFacadeView`, supports FLUX pattern
13 | */
14 | open class CZReactiveFeedListFacadeView: CZFeedListFacadeView {
15 |
16 | let store: Store
17 |
18 | public init(store: Store,
19 | sectionModelsTransformer: @escaping SectionModelsTransformer,
20 | parentViewController: UIViewController? = nil,
21 | loadMoreThreshold: Int = CZFeedListFacadeView.kLoadMoreThreshold,
22 | minimumLineSpacing: CGFloat = ReactiveListViewKit.minimumLineSpacing) {
23 | self.store = store
24 | let onAction = { (action: CZActionProtocol) in
25 | store.dispatch(action: action)
26 | }
27 | super.init(sectionModelsTransformer: sectionModelsTransformer,
28 | onAction: onAction,
29 | parentViewController: parentViewController,
30 | loadMoreThreshold: loadMoreThreshold)
31 | }
32 |
33 | public required init?(coder: NSCoder) { fatalError("Must call designated initializer.") }
34 | }
35 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/Store/StoreObserverProtocol.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /// The protocol that defines the observer to observe the store state changes.
4 | public protocol StoreObserverProtocol {
5 | associatedtype StateType
6 |
7 | /// Gets notified with the current `state` and `previousState` when the store state changes.
8 | func storeDidUpdate(state: StateType,
9 | previousState: StateType?)
10 |
11 | /// Gets notified with a dispatched action.
12 | func didReceiveStoreAction(_ action: CZActionProtocol)
13 | }
14 |
15 | public extension StoreObserverProtocol {
16 | func didReceiveStoreAction(_ action: CZActionProtocol) {
17 | // No-op.
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/TemplateViews/CZDividerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZDividerView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/16/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Convenience divider view class
13 | */
14 | public final class CZDividerView: UIView {
15 | private let size: CGFloat
16 | private let bgColor: UIColor
17 |
18 | public init(size: CGFloat = 1,
19 | backgroudColor: UIColor = ReactiveListViewKit.GreyDividerColor) {
20 | self.size = size
21 | self.bgColor = backgroudColor
22 | super.init(frame: .zero)
23 | setup()
24 | }
25 |
26 | public required init?(coder: NSCoder) {
27 | fatalError("Must call designated initializer.")
28 | }
29 | }
30 |
31 | private extension CZDividerView {
32 | func setup() {
33 | translatesAutoresizingMaskIntoConstraints = false
34 | backgroundColor = self.bgColor
35 | let sizeContrait = heightAnchor.constraint(equalToConstant: size)
36 | sizeContrait.priority = UILayoutPriority(rawValue: 749)
37 | sizeContrait.isActive = true
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/TemplateViews/CZFeedListSupplementaryView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFeedListSupplementaryView.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 2/7/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Convenience class of SectionHeaderView/SectionFooterView
13 | */
14 | open class CZFeedListSupplementaryView: UICollectionReusableView {
15 | open override var reuseIdentifier: String? {
16 | return type(of: self).reuseId
17 | }
18 | private var model: CZFeedModel?
19 | private var contentView: CZFeedCellViewSizeCalculatable?
20 | public static var reuseId: String {
21 | return NSStringFromClass(object_getClass(self)!)
22 | }
23 | open func config(with model: CZFeedModel,
24 | onAction: OnAction?) {
25 | defer {
26 | self.model = model
27 | contentView?.config(with: model.viewModel)
28 | }
29 | // Reset contentView if contentViewClass differs from the current one
30 | if let contentView = contentView,
31 | let currModel = self.model,
32 | currModel.viewClass != model.viewClass {
33 | (contentView as? UIView)?.removeFromSuperview()
34 | self.contentView = nil
35 | }
36 | if contentView == nil {
37 | self.contentView = model.viewClass.init(viewModel: model.viewModel, onAction: onAction)
38 | guard let contentView = self.contentView as? UIView else {
39 | assertionFailure("\(model.viewClass) should be subClass of UIView!")
40 | return
41 | }
42 | contentView.translatesAutoresizingMaskIntoConstraints = false
43 | contentView.isUserInteractionEnabled = false
44 | addSubview(contentView)
45 | contentView.overlayOnSuperview()
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/Utils/Array+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array+Extension.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/15/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension Array where Element: CZListDiffableObject {
12 | /**
13 | Check whether elements in two arrays equal
14 | */
15 | public func isEqual(toDiffableObj object: Any) -> Bool {
16 | guard let object = object as? [Element],
17 | count == object.count else {
18 | return false
19 | }
20 | return (0.. Bool {
14 | switch(obj1, obj2) {
15 | case let (obj1 as CZListDiffableObject, obj2 as CZListDiffableObject):
16 | return obj1.isEqual(toDiffableObj: obj2)
17 | default:
18 | return (obj1 == nil && obj2 == nil)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/Utils/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKitConstants.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/2/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Constants of ReactiveListViewKit
13 | */
14 | public enum ReactiveListViewKit {
15 | public static var isDebugMode = true
16 | public static var isIncrementalUpdateEnabled = false
17 | public static var useGCD = false
18 |
19 | // MARK: - Self Sizing Cells
20 |
21 | public static var enableSelfSizingCellsForVerticalOrientation = true
22 | public static var enableSelfSizingCellsForHorizontalOrientation = true
23 |
24 | public static let ClearBGColor = UIColor.clear
25 | public static let GreyBGColor = UIColor(white: 240.0 / 255.0, alpha: 1.0)
26 | public static let GreyDividerColor = UIColor(white: 217.0 / 255.0, alpha: 1.0)
27 | public static let minimumLineSpacing: CGFloat = 10
28 | public static let minimumInteritemSpacing: CGFloat = 10
29 | public static let sectionInset = UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 0)
30 |
31 | public enum FeedListSupplementaryTextView {
32 | public static let inset = UIEdgeInsets(top: 8, left: 10, bottom: 3, right: 10)
33 | public static let titleFont = UIFont.boldSystemFont(ofSize: 14)
34 | public static let titleColor = UIColor(white: 0.1, alpha: 1)
35 | public static let actionButtonColor = UIColor(red: 62.0 / 255.0, green: 153 / 255.0, blue: 237 / 255.0, alpha: 1)
36 | }
37 |
38 | public static let horizontalSectionAdapterViewBGColor: UIColor = .clear
39 |
40 | public static let feedListSupplementaryLineHeaderViewInset = UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)
41 | public static let feedListSupplementaryLineFooterViewInset = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0)
42 | }
43 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKit/Utils/ReactiveListViewKitHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKitHelper.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 11/6/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import CZUtils
10 |
11 | public func dbgPrint(_ item: CustomStringConvertible) {
12 | guard ReactiveListViewKit.isDebugMode else { return }
13 | _dbgPrint(item)
14 | }
15 |
16 | public func PrettyString(_ object: Any) -> String {
17 | guard let object = object as? CustomStringConvertible else {
18 | return ""
19 | }
20 | if let indexSet = object as? IndexSet {
21 | return indexSet.reduce("[") { (prevResult, index) -> String in
22 | prevResult + String(index) + ", "
23 | } + "]"
24 | } else {
25 | return object.description
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKitTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/ReactiveListViewKitTests/Utils/CZListDiff+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZListDiff.swift
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/5/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import ReactiveListViewKit
10 |
11 | extension CZListDiff {
12 | /**
13 | Return empty SectionIndexDiffResult
14 | */
15 | public static var emptyDiffSectionModelIndexes: SectionIndexDiffResult {
16 | let sectionsDiff: [SectionDiffResultKey: Any] = [:]
17 | let rowsDiff: [RowDiffResultKey: [Any]] = [:]
18 | return (sectionsDiff, rowsDiff)
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 2.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Cheng Zhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "CZUtils",
8 | platforms: [
9 | .iOS(.v11),
10 | ],
11 | products: [
12 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
13 | .library(
14 | name: "CZUtils",
15 | targets: ["CZUtils"]),
16 | ],
17 | dependencies: [
18 | // Dependencies declare other packages that this package depends on.
19 | // .package(url: /* package url */, from: "1.0.0"),
20 | ],
21 | targets: [
22 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
23 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
24 | .target(
25 | name: "CZUtils",
26 | dependencies: []),
27 | .testTarget(
28 | name: "CZUtilsTests",
29 | dependencies: ["CZUtils"]),
30 | ]
31 | )
32 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/README.md:
--------------------------------------------------------------------------------
1 | # CZUtils
2 |
3 | [](http://cocoapods.org/pods/CZUtils)
4 | [](https://github.com/Carthage/Carthage)
5 | 
6 | [](http://cocoapods.org/pods/CZUtils)
7 | [](http://cocoapods.org/pods/CZUtils)
8 |
9 | ### Powerful toolset for Utils layer
10 |
11 | * CZMutexLock on top of GCD
12 | * NSNullGuard
13 | * MainQueueScheduler
14 | * SwizzlingHelper
15 | * ThreadSafeDictionary
16 | * NibLoadable for UIView/Cell
17 |
18 |
19 | ## Installation
20 |
21 | CZUtils is available through [CocoaPods](http://cocoapods.org). To install
22 | it, simply add the following line to your Podfile:
23 |
24 | ```ruby
25 | pod 'CZUtils'
26 | ```
27 |
28 | And run `pod install` in your work folder.
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZAlertManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZAlertManager.swift
3 | //
4 | // Created by Cheng Zhang on 1/15/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// Convenient helper class for AlertViewController displaying
11 | open class CZAlertManager: NSObject {
12 |
13 | open class func showAlert(title: String? = nil,
14 | message: String,
15 | confirmText: String = "Ok",
16 | confirmHandler: ((UIAlertAction) -> Void)? = nil,
17 | cancelText: String? = nil,
18 | cancelHandler: ((UIAlertAction) -> Void)? = nil,
19 | on viewController: UIViewController? = nil,
20 | completion: (() -> Void)? = nil) {
21 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
22 | let action1 = UIAlertAction(title: confirmText, style: .default, handler: confirmHandler)
23 | alertController.addAction(action1)
24 | if let cancelText = cancelText {
25 | let action2 = UIAlertAction(title: cancelText, style: .cancel, handler: cancelHandler)
26 | alertController.addAction(action2)
27 | }
28 |
29 | guard let presentingViewController = viewController ?? UIApplication.shared.keyWindow?.rootViewController else {
30 | assertionFailure("Couldn't find valid presenting ViewController.")
31 | return
32 | }
33 | presentingViewController.topMost.present(alertController, animated: true, completion: completion)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZDictionary.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZDictionary.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 2018/7/6.
6 | // Copyright © 2019 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public typealias CZDictionary = [AnyHashable : Any]
12 |
13 | public protocol CZDictionaryable {
14 | init(dictionary: CZDictionary)
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZError.swift
3 | //
4 | // Created by Cheng Zhang on 1/10/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Convenience Error class
11 | open class CZError: NSError {
12 | public init(domain: String, code: Int = 99, description: String? = nil) {
13 | var userInfo: [String: Any]? = nil
14 | if let description = description {
15 | userInfo = [NSLocalizedDescriptionKey: description]
16 | }
17 | super.init(domain: domain, code: code, userInfo: userInfo)
18 | }
19 |
20 | required public init?(coder aDecoder: NSCoder) {
21 | super.init(coder: aDecoder)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZFileHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZFileHelper.swift
3 | //
4 | // Created by Cheng Zhang on 1/13/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Helper class for file related methods
11 | @objc open class CZFileHelper: NSObject {
12 | public static func getFileSize(_ filePath: String?) -> Int? {
13 | guard let filePath = filePath else {return nil}
14 | do {
15 | let attrs = try FileManager.default.attributesOfItem(atPath: filePath)
16 | let size = attrs[.size] as? Int
17 | return size
18 | } catch {
19 | dbgPrint("Failed to get file size of \(filePath). Error - \(error.localizedDescription)")
20 | }
21 | return nil
22 | }
23 |
24 | @objc public static var documentDirectory: String {
25 | return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZMainQueueScheduler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZMainQueueScheduler.swift
3 | //
4 | // Created by Cheng Zhang on 1/4/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Convenience class for scheduling sync/async execution on main queue
11 | open class CZMainQueueScheduler: NSObject {
12 |
13 | /// Synchronous execution: inferring function returnType with `execution` closure returnType
14 | public class func sync(_ execution: @escaping () -> T) -> T {
15 | if Thread.isMainThread {
16 | return execution()
17 | } else {
18 | return DispatchQueue.main.sync {
19 | execution()
20 | }
21 | }
22 | }
23 |
24 | /// Asynchronous execution
25 | public class func async(execution: @escaping () -> Void ) {
26 | DispatchQueue.main.async {
27 | execution()
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZProMutexLock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZProMutexLock.swift
3 | //
4 | // Created by Cheng Zhang on 2/3/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Mutex lock on top of `pthread_mutex_lock`/`pthread_mutex_unlock`
11 | open class CZProMutexLock: NSObject {
12 | private var mutex = pthread_mutex_t()
13 |
14 | public override init() {
15 | var attr = pthread_mutexattr_t()
16 | guard pthread_mutexattr_init(&attr) == 0 else {
17 | preconditionFailure()
18 | }
19 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)
20 | guard pthread_mutex_init(&mutex, &attr) == 0 else {
21 | preconditionFailure()
22 | }
23 | }
24 |
25 | deinit {
26 | pthread_mutex_destroy(&mutex)
27 | }
28 |
29 | public func withLock(_ closure: () -> T) -> T {
30 | defer {
31 | pthread_mutex_unlock(&mutex)
32 | }
33 | pthread_mutex_lock(&mutex)
34 | return closure()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZTheme.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CZTheme.swift
3 | //
4 | // Created by Cheng Zhang on 4/18/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// Common theme settings for projects
11 | public struct CZTheme {
12 | public static let greyDividerColor: CGFloat = 217.0 / 255.0
13 | }
14 |
15 | public extension UIColor {
16 | static let candyGreen = UIColor(red: 67.0/255.0, green: 205.0/255.0, blue: 135.0/255.0, alpha: 1.0)
17 | static let facebookBlue = UIColor(red: 68.0/255.0, green: 105.0/255.0, blue: 176.0/255.0, alpha: 1.0)
18 | static let dividerGrey = UIColor(white: CZTheme.greyDividerColor, alpha: 1)
19 | static let searchBarColor = UIColor(white: 217.0 / 255.0, alpha: 1)
20 | static let searchBarTextGrey = UIColor(white: 127.0 / 255.0, alpha: 1)
21 | static let tabBarTintColor = UIColor(white: 250.0 / 255.0, alpha: 1)
22 | static let tabBarItemTintColor = UIColor(white: 38.0 / 255.0, alpha: 1)
23 | }
24 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/CZUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Utils.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 2/19/18.
6 | // Copyright © 2018 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public class CZUtils {
12 | public static func dbgPrint(_ item: CustomStringConvertible) {
13 | #if DEBUG
14 | print(item)
15 | #endif
16 | }
17 | }
18 |
19 | public func dbgPrint(_ item: CustomStringConvertible) {
20 | CZUtils.dbgPrint(item)
21 | }
22 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Error+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Error+.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 8/10/19.
6 | // Copyright © 2019 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Error {
12 | var retrievedCode: Int {
13 | return (self as NSError).code
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Array+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array+Extensoin.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 1/26/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Array {
12 | /**
13 | Returns element at specified `safe` index if exists, otherwise nil
14 | */
15 | subscript (safe index: Index) -> Element? {
16 | return indices.contains(index) ? self[index] : nil
17 | }
18 |
19 | /**
20 | Pretty formatted description string
21 | */
22 | var prettyDescription: String {
23 | return Pretty.describing(self)
24 | }
25 | }
26 |
27 | public extension Array where Element: NSCopying {
28 | func copy(with zone: NSZone? = nil) -> Any {
29 | return compactMap{ $0.copy() }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Character+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Character+.swift
3 | //
4 | // Created by Cheng Zhang on 12/30/18.
5 | // Copyright © 2018 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | extension Character {
11 |
12 | public var ascii: Int {
13 | return Int(String(self).unicodeScalars.first!.value)
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Date+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Date+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 5/19/16.
6 | // Copyright © 2016 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Date {
12 | var simpleString: String {
13 | return string(withFormat: "yyyy-MM-dd hh:mm")
14 | }
15 |
16 | var complexString: String {
17 | return string(withFormat: "EEE, dd MMM yyyy hh:mm:ss +zzzz")
18 | }
19 |
20 | func string(withFormat formatterStr: String) -> String {
21 | let dateFormatter = DateFormatter()
22 | dateFormatter.dateFormat = formatterStr
23 | return dateFormatter.string(from: self)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Dictionary+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dictionary+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 1/29/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Dictionary {
12 | /// Retrieve value from `dotedKey`, compatible with multi-dot in keyPath. e.g. "user.profile.fullName"
13 | func value(forDotedKey dotedKey: String) -> Value? {
14 | return value(forSegmentedKey: dotedKey)
15 | }
16 |
17 | /// Retrieve value from `segmentedKey`, compatible with multi-segments separated by `splitter`. e.g. "user.profile.fullName", "user/profile/fullName"
18 | func value(forSegmentedKey segmentedKey: String, splitter: String = ".") -> Value? {
19 | var value: Any? = nil
20 | var dict: Dictionary? = self
21 |
22 | for subkey in segmentedKey.components(separatedBy: splitter) {
23 | guard dict != nil, let subkey = subkey as? Key else {
24 | return nil
25 | }
26 | value = dict?[subkey]
27 | dict = value as? Dictionary
28 | }
29 | return (value is NSNull) ? nil : (value as? Value)
30 | }
31 |
32 | /// Insert key/value pairs with input Dictionary
33 | mutating func insert(_ other: Dictionary) {
34 | for (key, value) in other {
35 | self[key] = value
36 | }
37 | }
38 |
39 | /// Pretty formatted description string
40 | var prettyDescription: String {
41 | return Pretty.describing(self)
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/NSObject+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 5/19/16.
6 | // Copyright © 2016 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Convenient methods of NSObject
13 | */
14 | public extension NSObject {
15 | var className: String {
16 | return NSStringFromClass(type(of: self))
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Optional+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Optional+.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 9/22/18.
6 | // Copyright © 2018 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Convenient methods of Swift Optional
13 | */
14 | extension Optional {
15 | /**
16 | If this optional has a value, unwrap the optional and call the given function passing the unwrapped value
17 | */
18 | public func ifPresent(_ function: ((Wrapped) -> Void)? = nil) {
19 | guard let function = function else {
20 | return
21 | }
22 |
23 | switch (self) {
24 | case .some(let value):
25 | function(value)
26 | default:
27 | break
28 | }
29 | }
30 |
31 | /**
32 | If this optional has a value, call the given function passing this optional
33 | */
34 | public func ifPresent(_ function: ((Wrapped?) -> Void)? = nil) {
35 | guard let function = function else {
36 | return
37 | }
38 |
39 | switch (self) {
40 | case .some(let value):
41 | function(value)
42 | default:
43 | break
44 | }
45 | }
46 |
47 | /**
48 | Raises an assert if the value is nil.
49 | */
50 | public var assertIfNil: Optional {
51 | assert(self != nil, "Expected a non-nil \(Wrapped.self)")
52 | return self
53 | }
54 |
55 | /**
56 | Returns a string-interpolated value for item contained in this optional, or the default value if the optional is nil.
57 | This can be used instead of String(describing:) if you don't want the result to contain "Optional()"
58 |
59 | Note: If this is a doubly-nested optional (e.g. Int??), you could still get the "Optional()" string as this only unwraps one level.
60 | */
61 | public func interpolatedString(withDefaultValue defaultValue: String = "nil") -> String {
62 | return self.map { wrapped in "\(wrapped)" } ?? defaultValue
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/Set+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dictionary+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 1/29/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public extension Set {
12 |
13 | func compactMap(_ transform: (Element) -> ElementOfResult?) -> [ElementOfResult] {
14 | return Array(self).compactMap(transform)
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIButton+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+Extension.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 3/7/16.
6 | // Copyright © 2016 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private var controlHandlerKey: Int8 = 0
12 | public extension UIButton {
13 | /**
14 | Add self-contained action handler for button
15 | */
16 | func addHandler(for controlEvents: UIControl.Event, handler: @escaping (UIButton) -> ()) {
17 | if let oldTarget = objc_getAssociatedObject(self, &controlHandlerKey) as? CocoaTarget {
18 | self.removeTarget(oldTarget, action: #selector(oldTarget.sendNext), for: controlEvents)
19 | }
20 |
21 | let target = CocoaTarget(handler)
22 | objc_setAssociatedObject(self, &controlHandlerKey, target, .OBJC_ASSOCIATION_RETAIN)
23 | self.addTarget(target, action: #selector(target.sendNext), for: controlEvents)
24 | }
25 |
26 | /**
27 | Set image with tintColor for desired controlState
28 | */
29 | func setImage(_ imageName: String, for controlState: UIControl.State = .normal, tintColor: UIColor) {
30 | let image = UIImage(named: imageName)?.withRenderingMode(.alwaysTemplate)
31 | setImage(image, for: controlState)
32 | self.tintColor = tintColor
33 | }
34 | }
35 |
36 | /**
37 | A target that accepts action messages
38 | */
39 | public final class CocoaTarget: NSObject {
40 | private let action: (T) -> ()
41 |
42 | public init(_ action: @escaping (T) -> ()) {
43 | self.action = action
44 | }
45 |
46 | @objc
47 | public func sendNext(_ receiver: Any?) {
48 | guard let receiver = receiver as? T else {
49 | preconditionFailure("`receiver` isn't expected type.")
50 | }
51 | action(receiver)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIImage+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Extension.swift
3 | //
4 | // Created by Cheng Zhang on 1/12/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 | import ImageIO
10 |
11 | public extension UIImage {
12 | @objc(cropToRect:)
13 | func crop(toRect rect: CGRect) -> UIImage {
14 | let croppedCGImage = self.cgImage!.cropping(to: rect)!
15 | let res = UIImage(cgImage: croppedCGImage)
16 | return res
17 | }
18 |
19 | @objc(cropToSize:)
20 | func crop(toSize size: CGSize) -> UIImage {
21 | var size = size
22 | let ratio = size.height / size.width
23 | if size.width < size.height {
24 | size.width = self.size.width * self.scale
25 | size.height = size.width * ratio
26 | } else {
27 | size.height = self.size.height * self.scale
28 | size.width = size.width * ratio
29 | }
30 | let rect = CGRect(origin: CGPoint(x: (self.size.width * self.scale - size.width) / 2,
31 | y: (self.size.height * self.scale - size.height) / 2),
32 | size: size)
33 | return crop(toRect: rect)
34 | }
35 |
36 | // height / width
37 | @objc(cropToRatio:)
38 | func crop(toRatio ratio: CGFloat) -> UIImage {
39 | var size: CGSize = self.size
40 | if ratio < 1 {
41 | size.width = self.size.width * self.scale
42 | size.height = size.width * ratio
43 | } else {
44 | size.height = self.size.height * self.scale
45 | size.width = size.height / ratio
46 | }
47 | let rect = CGRect(origin: CGPoint(x: (self.size.width * self.scale - size.width) / 2,
48 | y: (self.size.height * self.scale - size.height) / 2),
49 | size: size)
50 | return crop(toRect: rect)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIScreen+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIScreen+Extension.swift
3 | //
4 | // Created by Cheng Zhang on 1/8/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | public extension UIScreen {
11 | static var currSize: CGSize {
12 | return main.bounds.size
13 | }
14 |
15 | static var currWidth: CGFloat {
16 | return currSize.width
17 | }
18 |
19 | static var currHeight: CGFloat {
20 | return currSize.height
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Extensions/UIView+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.swift
3 | //
4 | // Created by Cheng Zhang on 1/12/16.
5 | // Copyright © 2016 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// Constants for UIView extensions
11 | public enum UIViewConstants {
12 | public static let fadeInDuration: TimeInterval = 0.4
13 | public static let fadeInAnimationName = "com.tony.animation.fadein"
14 | }
15 |
16 | // MARK: - Corner/Border
17 |
18 | public extension UIView {
19 |
20 | func roundToCircle() {
21 | let width = self.bounds.size.width
22 | layer.cornerRadius = width / 2
23 | layer.masksToBounds = true
24 | }
25 |
26 | func roundCorner(_ cornerRadius: CGFloat = 2,
27 | boarderWidth: CGFloat = 0,
28 | boarderColor: UIColor = .clear,
29 | shadowColor: UIColor = .clear,
30 | shadowOffset: CGSize = .zero,
31 | shadowRadius: CGFloat = 2,
32 | shadowOpacity: Float = 1) {
33 | layer.masksToBounds = true
34 | layer.cornerRadius = cornerRadius
35 | layer.borderColor = boarderColor.cgColor
36 | layer.borderWidth = boarderWidth
37 |
38 | layer.shadowColor = shadowColor.cgColor
39 | layer.shadowOffset = shadowOffset
40 | layer.shadowRadius = shadowRadius
41 | }
42 |
43 | }
44 |
45 | // MARK: - Animations
46 |
47 | public extension UIView {
48 | func fadeIn(animationName: String = UIViewConstants.fadeInAnimationName,
49 | duration: TimeInterval = UIViewConstants.fadeInDuration) {
50 | let transition = CATransition()
51 | transition.duration = duration
52 | transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
53 | transition.type = CATransitionType.fade
54 | layer.add(transition, forKey: animationName)
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Investigation/CriticalSectionLock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CriticalSectionLock.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 11/3/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Convenience mutex lock on top of NSLock
12 | open class CriticalSectionLock: NSLock {
13 | public func execute(_ execution: () -> T) -> T {
14 | lock()
15 | defer {
16 | unlock()
17 | }
18 | return execution()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/RegExHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RegExHelper.swift
3 | //
4 | // Created by Cheng Zhang on 2/18/20.
5 | // Copyright © 2020 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | public class RegExHelper {
11 |
12 | /// Extract variable with RegEx group match name. e.g. "(?.*)
" pattern.
13 | /// - Note: Group name in `pattern` should be 'var'.
14 | public static func extractVariable(_ string: String,
15 | pattern: String,
16 | options: NSRegularExpression.Options = .caseInsensitive,
17 | groupName: String = "var") -> String? {
18 | guard let regex = (try? NSRegularExpression(pattern: pattern, options: options)).assertIfNil,
19 | let match = regex.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)),
20 | let matchedRange = Range(match.range(withName: groupName), in: string) else {
21 | return nil
22 | }
23 | return String(string[matchedRange])
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Supported Files/CZUtils.h:
--------------------------------------------------------------------------------
1 | //
2 | // CZUtils.h
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 11/19/15.
6 | // Copyright © 2015 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for CZUtils.
12 | FOUNDATION_EXPORT double CZUtilsVersionNumber;
13 |
14 | //! Project version string for CZUtils.
15 | FOUNDATION_EXPORT const unsigned char CZUtilsVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Supported Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Swizzling.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Swizzling.swift
3 | //
4 | // Created by Cheng Zhang on 12/9/15.
5 | // Copyright © 2015 Cheng Zhang. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Generic swizzling function - workable for subclasses of NSObject
11 | /// NSObject subclass maintains a DispatchTable which maps between method selector and actural IMP
12 | public func swizzling(_ aClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
13 | let originalMethod = class_getInstanceMethod(aClass, originalSelector)
14 | let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)
15 | let didAddMethod = class_addMethod(aClass, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
16 | if didAddMethod {
17 | class_replaceMethod(aClass, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!)!)
18 | } else {
19 | method_exchangeImplementations(originalMethod!, swizzledMethod!)
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Sources/CZUtils/Utils/PrettyDescription.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PrettyDescription.swift
3 | // CZUtils
4 | //
5 | // Created by Cheng Zhang on 7/29/19.
6 | // Copyright © 2019 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public class Pretty {
12 |
13 | /**
14 | Return Pretty formatted description for valid JSON object
15 | */
16 | static func describing(_ object: Any) -> String {
17 | do {
18 | let data: Data = try JSONSerialization.data(withJSONObject: object, options: .prettyPrinted)
19 | return String(data: data, encoding: .utf8).assertIfNil ?? ""
20 | } catch {
21 | assertionFailure("Failed to retrieve pretty printed description. error - \(error.localizedDescription)")
22 | return ""
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Tests/CZUtilsTests/CZUtilsTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import CZUtils
3 |
4 | final class CZUtilsTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | XCTAssertEqual(CZUtils().text, "Hello, World!")
10 | }
11 |
12 | static var allTests = [
13 | ("testExample", testExample),
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Tests/CZUtilsTests/TestArray.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestArray.swift
3 | // CZUtilsTests
4 | //
5 | // Created by Cheng Zhang on 7/26/18.
6 | // Copyright © 2018 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CZUtils
11 |
12 | class TestArray: XCTestCase {
13 | func testSafeSubscript() {
14 | let array = [Int](0..<10)
15 |
16 | // Elements within bounds
17 | [0, 3, 9].forEach { index in
18 | let element = array[safe: index]
19 | XCTAssert(element == index, "Unexpected element '\(String(describing: element))' at specified index '\(index)'. Expected value = '\(index)'")
20 | }
21 |
22 | // Elements out of bounds
23 | [-1, 10, 13, 20, 1000].forEach { index in
24 | let element = array[safe: index]
25 | XCTAssert(element == nil, "Unexpected element '\(String(describing: element))' at specified index '\(index)'. Expected value = nil")
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Tests/CZUtilsTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(CZUtilsTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/CZUtils/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import CZUtilsTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += CZUtilsTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ReactiveListViewKit/Supported Files/ReactiveListViewKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // ReactiveListViewKit.h
3 | // ReactiveListViewKit
4 | //
5 | // Created by Cheng Zhang on 1/2/17.
6 | // Copyright © 2017 Cheng Zhang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for ReactiveListViewKit.
12 | FOUNDATION_EXPORT double ReactiveListViewKitVersionNumber;
13 |
14 | //! Project version string for ReactiveListViewKit.
15 | FOUNDATION_EXPORT const unsigned char ReactiveListViewKitVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------