Initial commit

This commit is contained in:
Ryo Aoyama
2019-06-24 05:49:24 +09:00
commit 3e216e1aa4
98 changed files with 12591 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
---
name: Bug Report
about: Create a bug report.
---
## Checklist
- [ ] This is not a Apple's bug.
- [ ] Reviewed the README and documents.
- [ ] Searched existing issues for ensure not duplicated.
## Expected Behavior
<!--- Tell us what should happen -->
## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->
## Steps to Reproduce
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->
1.
2.
3.
4.
## Detailed Description (Include Screenshots)
<!--- Provide a detailed description of the bug -->
## Reproducible Demo Project
<!--- If you have, provide links of bug reproducible project that we can refer -->
## Environments
- version:
- Swift version:
- iOS version:
- Xcode version:
- Devices/Simulators:
- CocoaPods/Carthage version:
+18
View File
@@ -0,0 +1,18 @@
---
name: Feature Request
about: Create a feature request.
---
## Checklist
- [ ] Reviewed the README and documents.
- [ ] Searched existing issues for ensure not duplicated.
## Description
<!--- Provide a detailed description of the feature you are proposing -->
## Motivation and Context
<!--- Why is this feature required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
## Proposed Solution
<!--- Describe the solution you proposing. -->
+30
View File
@@ -0,0 +1,30 @@
---
name: Question
about: Create a bug question.
---
## Checklist
- [ ] Reviewed the README and documents.
- [ ] Searched existing issues for ensure not duplicated.
## Expected Behavior
<!--- Tell us what should happen -->
## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->
## Detailed Description (Include Screenshots)
<!--- Provide a detailed description of your question -->
## Environment
- version:
- Swift version:
- iOS version:
- Xcode version:
- Devices/Simulators:
- CocoaPods/Carthage version:
+23
View File
@@ -0,0 +1,23 @@
## Checklist
- [ ] All tests are passed.
- [ ] Added tests.
- [ ] Documented the code using [Xcode markup](https://developer.apple.com/library/mac/documentation/Xcode/Reference/xcode_markup_formatting_ref).
- [ ] Searched existing pull requests for ensure not duplicated.
## Description
<!--- Describe your changes in detail -->
## Related Issue
<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->
## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
## Impact on Existing Code
<!--- Tell us the impact on existing code as far as you understand. -->
## Screenshots (if appropriate)
+38
View File
@@ -0,0 +1,38 @@
.DS_Store
*/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
xcbaselines
profile
*.moved-aside
DerivedData
.idea/
*.hmap
*.xccheckout
*.xcuserstate
build/
## Documentation
docs/docsets/
docs/undocumented.json
## Gems
.bundle
vendor
## CocoaPods
Pods
## Carthage
Carthage/*
!Carthage/Checkouts
## Swift Package Manager
.build
+3
View File
@@ -0,0 +1,3 @@
[submodule "Carthage/Checkouts/DifferenceKit"]
path = Carthage/Checkouts/DifferenceKit
url = https://github.com/ra1028/DifferenceKit.git
+30
View File
@@ -0,0 +1,30 @@
# https://github.com/realm/jazzy
author: Ryo Aoyama
author_url: https://github.com/ra1028
github_url: https://github.com/ra1028/DiffableDataSources
module: DiffableDataSources
readme: README.md
output: docs
theme: fullwidth
clean: true
skip_undocumented: true
xcodebuild_arguments:
- -workspace
- DiffableDataSources.xcworkspace
- -scheme
- DiffableDataSources
- -sdk
- iphonesimulator
exclude:
- Sources/AppKit/CocoaCollectionViewDiffableDataSource.swift
custom_categories:
- name: DataSources
children:
- TableViewDiffableDataSource
- CollectionViewDiffableDataSource
- name: Snapshot
children:
- DiffableDataSourceSnapshot
+1
View File
@@ -0,0 +1 @@
5.0
+34
View File
@@ -0,0 +1,34 @@
# https://github.com/realm/SwiftLint
excluded:
- .build
- Carthage
- Examples
disabled_rules:
- type_name
- identifier_name
- generic_type_name
- force_cast
nesting:
type_level:
warning: 2
line_length:
warning: 200
file_length:
warning: 600
type_body_length:
warning: 400
function_body_length:
warning: 50
cyclomatic_complexity:
warning: 12
statement_position:
statement_mode: uncuddled_else
+76
View File
@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
+91
View File
@@ -0,0 +1,91 @@
# 🎈 Contributing
First of all, thanks for your interest.
There are several ways to contribute to this project. We welcome contributions in all ways.
We have made some contribution guidelines to smoothly incorporate your opinions and code into this project.
## 📝 Open Issue
When you found a bug or having a feature request, search for the issue from the existing issues and feel free to open the issue after making sure it isn't already reported.
In order to we understand your issue accurately, please include as much information as possible in the issue template.
The screenshot are also big clue to understand the issue.
If you know exactly how to fix the bug you report or implement the feature you propose, please pull request instead of an issue.
## 🚀 Pull Request
We are waiting for a pull request to make this project more better with us.
If you want to add a new feature, let's discuss about it first on issue.
### Lint
Please introduce [SwiftLint](https://github.com/realm/SwiftLint) into your environment before start writing the code.
Xcode automatically runs lint in the build phase.
The code written according to lint should match our coding style, but for particular cases where style is unknown, refer to the existing code base.
### Test
The test will tells us the validity of your code.
All codes entering the master must pass the all tests.
If you change the code or add new features, you should add tests.
### Documentation
Please write the document using [Xcode markup](https://developer.apple.com/library/archive/documentation/Xcode/Reference/xcode_markup_formatting_ref/) to the code you added.
Documentation template is inserted automatically by using Xcode shortcut **⌥⌘/**.
Our document style is slightly different from the template. The example is below.
```swift
/// The example class for documentation.
final class Foo {
/// A property value.
let prop: Int
/// Create a new foo with a param.
///
/// - Parameters:
/// - param: An Int value for prop.
init(param: Int) {
prop = param
}
/// Returns a string value concatenating `param1` and `param2`.
///
/// - Parameters:
/// - param1: An Int value for prefix.
/// - param2: A String value for suffix.
///
/// - Returns: A string concatenating given params.
func bar(param1: Int, param2: String) -> String {
return "\(param1)" + param2
}
}
```
## [Developer's Certificate of Origin 1.1](https://elinux.org/Developer_Certificate_Of_Origin)
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
+1
View File
@@ -0,0 +1 @@
github "ra1028/DifferenceKit" ~> 1.1
+1
View File
@@ -0,0 +1 @@
github "ra1028/DifferenceKit" "1.1.3"
+27
View File
@@ -0,0 +1,27 @@
Pod::Spec.new do |spec|
spec.name = 'DiffableDataSources'
spec.version = '0.1.0'
spec.author = { 'ra1028' => 'r.fe51028.r@gmail.com' }
spec.homepage = 'https://github.com/ra1028/DiffableDataSources'
spec.documentation_url = 'https://ra1028.github.io/DiffableDataSources'
spec.summary = 'A library for backporting UITableView/UICollectionViewDiffableDataSource.'
spec.source = { :git => 'https://github.com/ra1028/DiffableDataSources.git', :tag => spec.version.to_s }
spec.license = { :type => 'Apache 2.0', :file => 'LICENSE' }
spec.requires_arc = true
spec.source_files = 'Sources/**/*.swift'
spec.swift_versions = ["5.0", "5.1"]
differenekit_version = '~> 1.1'
spec.ios.dependency 'DifferenceKit/UIKitExtension', differenekit_version
spec.tvos.dependency 'DifferenceKit/UIKitExtension', differenekit_version
spec.osx.dependency 'DifferenceKit/AppKitExtension', differenekit_version
spec.ios.frameworks = 'UIKit'
spec.tvos.frameworks = 'UIKit'
spec.osx.frameworks = 'Appkit'
spec.ios.deployment_target = '9.0'
spec.tvos.deployment_target = '9.0'
spec.osx.deployment_target = '10.11'
end
@@ -0,0 +1,591 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
6B41587222B5210500183AA2 /* TableViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B41587122B5210500183AA2 /* TableViewDiffableDataSource.swift */; };
6B46555C22B6BC81005202D1 /* HashableExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B46555B22B6BC81005202D1 /* HashableExtension.swift */; };
6B46555E22B7F904005202D1 /* UniversalError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B46555D22B7F904005202D1 /* UniversalError.swift */; };
6B466B2222B969600035D72F /* CollectionViewDiffableDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B466B2122B969600035D72F /* CollectionViewDiffableDataSourceTests.swift */; };
6B466B2422B96A520035D72F /* CocoaCollectionViewDiffableDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B466B2322B96A520035D72F /* CocoaCollectionViewDiffableDataSourceTests.swift */; };
6BA3A78022B54DA400AD51ED /* CollectionViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A77F22B54DA400AD51ED /* CollectionViewDiffableDataSource.swift */; };
6BA3A79422B5A35F00AD51ED /* DiffableDataSourceCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A79322B5A35F00AD51ED /* DiffableDataSourceCore.swift */; };
6BA3A7B122B6A5CE00AD51ED /* CocoaCollectionViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A7B022B6A5CE00AD51ED /* CocoaCollectionViewDiffableDataSource.swift */; };
6BA3A7B622B820DA00AD51ED /* TableViewDiffableDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A7B522B820DA00AD51ED /* TableViewDiffableDataSourceTests.swift */; };
6BA4F52922BC0768008D5117 /* MainThreadSerialDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA4F52822BC0768008D5117 /* MainThreadSerialDispatcher.swift */; };
6BA4F52B22BC0AF3008D5117 /* MainThreadSerialDispatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA4F52A22BC0AF3008D5117 /* MainThreadSerialDispatcherTests.swift */; };
6BB762D622B455170050DC03 /* DiffableDataSources.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BB762CC22B455170050DC03 /* DiffableDataSources.framework */; };
6BB762EB22B455520050DC03 /* SnapshotStructure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB762E822B455520050DC03 /* SnapshotStructure.swift */; };
6BB762EC22B455520050DC03 /* DiffableDataSourceSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB762E922B455520050DC03 /* DiffableDataSourceSnapshot.swift */; };
6BB762F122B455590050DC03 /* DiffableDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB762EF22B455590050DC03 /* DiffableDataSourceTests.swift */; };
6BB762F722B53C1C0050DC03 /* DifferenceKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BB762F622B53C1C0050DC03 /* DifferenceKit.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
6BB762D722B455170050DC03 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6BB762C322B455170050DC03 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 6BB762CB22B455170050DC03;
remoteInfo = DiffableDataSources;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
6B41587122B5210500183AA2 /* TableViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewDiffableDataSource.swift; sourceTree = "<group>"; };
6B46555B22B6BC81005202D1 /* HashableExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashableExtension.swift; sourceTree = "<group>"; };
6B46555D22B7F904005202D1 /* UniversalError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UniversalError.swift; sourceTree = "<group>"; };
6B466B2122B969600035D72F /* CollectionViewDiffableDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewDiffableDataSourceTests.swift; sourceTree = "<group>"; };
6B466B2322B96A520035D72F /* CocoaCollectionViewDiffableDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaCollectionViewDiffableDataSourceTests.swift; sourceTree = "<group>"; };
6BA3A77F22B54DA400AD51ED /* CollectionViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewDiffableDataSource.swift; sourceTree = "<group>"; };
6BA3A79322B5A35F00AD51ED /* DiffableDataSourceCore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiffableDataSourceCore.swift; sourceTree = "<group>"; };
6BA3A7B022B6A5CE00AD51ED /* CocoaCollectionViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaCollectionViewDiffableDataSource.swift; sourceTree = "<group>"; };
6BA3A7B522B820DA00AD51ED /* TableViewDiffableDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewDiffableDataSourceTests.swift; sourceTree = "<group>"; };
6BA4F52822BC0768008D5117 /* MainThreadSerialDispatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainThreadSerialDispatcher.swift; sourceTree = "<group>"; };
6BA4F52A22BC0AF3008D5117 /* MainThreadSerialDispatcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainThreadSerialDispatcherTests.swift; sourceTree = "<group>"; };
6BB762CC22B455170050DC03 /* DiffableDataSources.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DiffableDataSources.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6BB762D522B455170050DC03 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
6BB762E822B455520050DC03 /* SnapshotStructure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotStructure.swift; sourceTree = "<group>"; };
6BB762E922B455520050DC03 /* DiffableDataSourceSnapshot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiffableDataSourceSnapshot.swift; sourceTree = "<group>"; };
6BB762EA22B455520050DC03 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6BB762EF22B455590050DC03 /* DiffableDataSourceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiffableDataSourceTests.swift; sourceTree = "<group>"; };
6BB762F022B455590050DC03 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DiffableDataSources.xcconfig; sourceTree = "<group>"; };
6BB762F622B53C1C0050DC03 /* DifferenceKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DifferenceKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6BB762C922B455170050DC03 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6BB762F722B53C1C0050DC03 /* DifferenceKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6BB762D222B455170050DC03 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6BB762D622B455170050DC03 /* DiffableDataSources.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
6B41587322B52BC100183AA2 /* UIKit */ = {
isa = PBXGroup;
children = (
6B41587122B5210500183AA2 /* TableViewDiffableDataSource.swift */,
6BA3A77F22B54DA400AD51ED /* CollectionViewDiffableDataSource.swift */,
);
path = UIKit;
sourceTree = "<group>";
};
6BA3A7AF22B6A5A200AD51ED /* AppKit */ = {
isa = PBXGroup;
children = (
6BA3A7B022B6A5CE00AD51ED /* CocoaCollectionViewDiffableDataSource.swift */,
);
path = AppKit;
sourceTree = "<group>";
};
6BB762C222B455170050DC03 = {
isa = PBXGroup;
children = (
6BB762E622B455520050DC03 /* Sources */,
6BB762EE22B455590050DC03 /* Tests */,
6BB762F322B455610050DC03 /* XCConfigs */,
6BB762CD22B455170050DC03 /* Products */,
6BB762F522B53C1C0050DC03 /* Frameworks */,
);
sourceTree = "<group>";
};
6BB762CD22B455170050DC03 /* Products */ = {
isa = PBXGroup;
children = (
6BB762CC22B455170050DC03 /* DiffableDataSources.framework */,
6BB762D522B455170050DC03 /* Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
6BB762E622B455520050DC03 /* Sources */ = {
isa = PBXGroup;
children = (
6BB762E922B455520050DC03 /* DiffableDataSourceSnapshot.swift */,
6B41587322B52BC100183AA2 /* UIKit */,
6BA3A7AF22B6A5A200AD51ED /* AppKit */,
6BB762E722B455520050DC03 /* Internal */,
6BB762EA22B455520050DC03 /* Info.plist */,
);
path = Sources;
sourceTree = "<group>";
};
6BB762E722B455520050DC03 /* Internal */ = {
isa = PBXGroup;
children = (
6BA3A79322B5A35F00AD51ED /* DiffableDataSourceCore.swift */,
6BB762E822B455520050DC03 /* SnapshotStructure.swift */,
6BA4F52822BC0768008D5117 /* MainThreadSerialDispatcher.swift */,
6B46555B22B6BC81005202D1 /* HashableExtension.swift */,
6B46555D22B7F904005202D1 /* UniversalError.swift */,
);
path = Internal;
sourceTree = "<group>";
};
6BB762EE22B455590050DC03 /* Tests */ = {
isa = PBXGroup;
children = (
6BB762EF22B455590050DC03 /* DiffableDataSourceTests.swift */,
6BA3A7B522B820DA00AD51ED /* TableViewDiffableDataSourceTests.swift */,
6B466B2122B969600035D72F /* CollectionViewDiffableDataSourceTests.swift */,
6B466B2322B96A520035D72F /* CocoaCollectionViewDiffableDataSourceTests.swift */,
6BA4F52A22BC0AF3008D5117 /* MainThreadSerialDispatcherTests.swift */,
6BB762F022B455590050DC03 /* Info.plist */,
);
path = Tests;
sourceTree = "<group>";
};
6BB762F322B455610050DC03 /* XCConfigs */ = {
isa = PBXGroup;
children = (
6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */,
);
path = XCConfigs;
sourceTree = "<group>";
};
6BB762F522B53C1C0050DC03 /* Frameworks */ = {
isa = PBXGroup;
children = (
6BB762F622B53C1C0050DC03 /* DifferenceKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
6BB762C722B455170050DC03 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
6BB762CB22B455170050DC03 /* DiffableDataSources */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6BB762E022B455170050DC03 /* Build configuration list for PBXNativeTarget "DiffableDataSources" */;
buildPhases = (
6BB762C722B455170050DC03 /* Headers */,
6BB762C822B455170050DC03 /* Sources */,
6BB762C922B455170050DC03 /* Frameworks */,
6BB762CA22B455170050DC03 /* Resources */,
6BA3A7B222B6C94100AD51ED /* SwiftLint */,
);
buildRules = (
);
dependencies = (
);
name = DiffableDataSources;
productName = DiffableDataSources;
productReference = 6BB762CC22B455170050DC03 /* DiffableDataSources.framework */;
productType = "com.apple.product-type.framework";
};
6BB762D422B455170050DC03 /* Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6BB762E322B455170050DC03 /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = (
6BB762D122B455170050DC03 /* Sources */,
6BB762D222B455170050DC03 /* Frameworks */,
6BB762D322B455170050DC03 /* Resources */,
);
buildRules = (
);
dependencies = (
6BB762D822B455170050DC03 /* PBXTargetDependency */,
);
name = Tests;
productName = DiffableDataSourcesTests;
productReference = 6BB762D522B455170050DC03 /* Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
6BB762C322B455170050DC03 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1020;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Ryo Aoyama";
TargetAttributes = {
6BB762CB22B455170050DC03 = {
CreatedOnToolsVersion = 10.2.1;
};
6BB762D422B455170050DC03 = {
CreatedOnToolsVersion = 10.2.1;
};
};
};
buildConfigurationList = 6BB762C622B455170050DC03 /* Build configuration list for PBXProject "DiffableDataSources" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 6BB762C222B455170050DC03;
productRefGroup = 6BB762CD22B455170050DC03 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
6BB762CB22B455170050DC03 /* DiffableDataSources */,
6BB762D422B455170050DC03 /* Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
6BB762CA22B455170050DC03 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
6BB762D322B455170050DC03 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
6BA3A7B222B6C94100AD51ED /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = SwiftLint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint --config .swiftlint.yml\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
6BB762C822B455170050DC03 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6BA4F52922BC0768008D5117 /* MainThreadSerialDispatcher.swift in Sources */,
6B41587222B5210500183AA2 /* TableViewDiffableDataSource.swift in Sources */,
6BA3A78022B54DA400AD51ED /* CollectionViewDiffableDataSource.swift in Sources */,
6BB762EC22B455520050DC03 /* DiffableDataSourceSnapshot.swift in Sources */,
6B46555E22B7F904005202D1 /* UniversalError.swift in Sources */,
6BA3A7B122B6A5CE00AD51ED /* CocoaCollectionViewDiffableDataSource.swift in Sources */,
6BB762EB22B455520050DC03 /* SnapshotStructure.swift in Sources */,
6BA3A79422B5A35F00AD51ED /* DiffableDataSourceCore.swift in Sources */,
6B46555C22B6BC81005202D1 /* HashableExtension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6BB762D122B455170050DC03 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6BA4F52B22BC0AF3008D5117 /* MainThreadSerialDispatcherTests.swift in Sources */,
6BA3A7B622B820DA00AD51ED /* TableViewDiffableDataSourceTests.swift in Sources */,
6BB762F122B455590050DC03 /* DiffableDataSourceTests.swift in Sources */,
6B466B2422B96A520035D72F /* CocoaCollectionViewDiffableDataSourceTests.swift in Sources */,
6B466B2222B969600035D72F /* CollectionViewDiffableDataSourceTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
6BB762D822B455170050DC03 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 6BB762CB22B455170050DC03 /* DiffableDataSources */;
targetProxy = 6BB762D722B455170050DC03 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
6BB762DE22B455170050DC03 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
6BB762DF22B455170050DC03 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
6BB762E122B455170050DC03 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ryo.DiffableDataSources;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
6BB762E222B455170050DC03 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ryo.DiffableDataSources;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
6BB762E422B455170050DC03 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Tests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ryo.DiffableDataSourcesTests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "$(inherited)";
};
name = Debug;
};
6BB762E522B455170050DC03 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6BB762F422B455610050DC03 /* DiffableDataSources.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Tests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ryo.DiffableDataSourcesTests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "$(inherited)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
6BB762C622B455170050DC03 /* Build configuration list for PBXProject "DiffableDataSources" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6BB762DE22B455170050DC03 /* Debug */,
6BB762DF22B455170050DC03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6BB762E022B455170050DC03 /* Build configuration list for PBXNativeTarget "DiffableDataSources" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6BB762E122B455170050DC03 /* Debug */,
6BB762E222B455170050DC03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6BB762E322B455170050DC03 /* Build configuration list for PBXNativeTarget "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6BB762E422B455170050DC03 /* Debug */,
6BB762E522B455170050DC03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 6BB762C322B455170050DC03 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:DiffableDataSources.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762CB22B455170050DC03"
BuildableName = "DiffableDataSources.framework"
BlueprintName = "DiffableDataSources"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762D422B455170050DC03"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762CB22B455170050DC03"
BuildableName = "DiffableDataSources.framework"
BlueprintName = "DiffableDataSources"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762CB22B455170050DC03"
BuildableName = "DiffableDataSources.framework"
BlueprintName = "DiffableDataSources"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762CB22B455170050DC03"
BuildableName = "DiffableDataSources.framework"
BlueprintName = "DiffableDataSources"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762D422B455170050DC03"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:DiffableDataSources.xcodeproj">
</FileRef>
<FileRef
location = "group:Carthage/Checkouts/DifferenceKit/DifferenceKit.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,573 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
6B02216222BA0EF500AEB14D /* InsertionSortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B02216122BA0EF500AEB14D /* InsertionSortViewController.swift */; };
6B02216422BA11D500AEB14D /* Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B02216322BA11D500AEB14D /* Extension.swift */; };
6B02216622BA177F00AEB14D /* InsertionSortViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6B02216522BA177F00AEB14D /* InsertionSortViewController.xib */; };
6B02216822BB7FA800AEB14D /* TopViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B02216722BB7FA800AEB14D /* TopViewController.swift */; };
6B02216A22BB824600AEB14D /* TopViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6B02216922BB824600AEB14D /* TopViewController.xib */; };
6B46555622B6AB0C005202D1 /* MountainsRawData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B46555522B6AB0C005202D1 /* MountainsRawData.swift */; };
6B46555822B6AB15005202D1 /* MountainsRawData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B46555722B6AB15005202D1 /* MountainsRawData.swift */; };
6B46555A22B6AC83005202D1 /* LabelItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B46555922B6AC83005202D1 /* LabelItem.swift */; };
6BA3A78222B5515D00AD51ED /* LabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A78122B5515D00AD51ED /* LabelCell.swift */; };
6BA3A78422B5516500AD51ED /* LabelCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6BA3A78322B5516500AD51ED /* LabelCell.xib */; };
6BA3A78822B5565E00AD51ED /* MountainsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6BA3A78722B5565E00AD51ED /* MountainsViewController.xib */; };
6BA3A78E22B55FB000AD51ED /* DiffableDataSources.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77B22B549B700AD51ED /* DiffableDataSources.framework */; };
6BA3A78F22B55FB000AD51ED /* DiffableDataSources.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77B22B549B700AD51ED /* DiffableDataSources.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6BA3A79022B55FB000AD51ED /* DifferenceKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77D22B549B700AD51ED /* DifferenceKit.framework */; };
6BA3A79122B55FB000AD51ED /* DifferenceKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77D22B549B700AD51ED /* DifferenceKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6BA3A79C22B69EDF00AD51ED /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A79B22B69EDF00AD51ED /* AppDelegate.swift */; };
6BA3A79E22B69EDF00AD51ED /* MountainsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3A79D22B69EDF00AD51ED /* MountainsViewController.swift */; };
6BA3A7A022B69EE200AD51ED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6BA3A79F22B69EE200AD51ED /* Assets.xcassets */; };
6BA3A7A322B69EE200AD51ED /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6BA3A7A122B69EE200AD51ED /* Main.storyboard */; };
6BA3A7A922B6A04F00AD51ED /* DiffableDataSources.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77B22B549B700AD51ED /* DiffableDataSources.framework */; };
6BA3A7AA22B6A04F00AD51ED /* DiffableDataSources.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77B22B549B700AD51ED /* DiffableDataSources.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6BA3A7AB22B6A04F00AD51ED /* DifferenceKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77D22B549B700AD51ED /* DifferenceKit.framework */; };
6BA3A7AC22B6A04F00AD51ED /* DifferenceKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BA3A77D22B549B700AD51ED /* DifferenceKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6BB7630722B545240050DC03 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7630622B545240050DC03 /* AppDelegate.swift */; };
6BB7630922B545240050DC03 /* MountainsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7630822B545240050DC03 /* MountainsViewController.swift */; };
6BB7630E22B545260050DC03 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6BB7630D22B545260050DC03 /* Assets.xcassets */; };
6BB7631122B545260050DC03 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6BB7630F22B545260050DC03 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
6BA3A79222B55FB000AD51ED /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
6BA3A79122B55FB000AD51ED /* DifferenceKit.framework in Embed Frameworks */,
6BA3A78F22B55FB000AD51ED /* DiffableDataSources.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
6BA3A7AD22B6A05000AD51ED /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
6BA3A7AC22B6A04F00AD51ED /* DifferenceKit.framework in Embed Frameworks */,
6BA3A7AA22B6A04F00AD51ED /* DiffableDataSources.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
6B02216122BA0EF500AEB14D /* InsertionSortViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsertionSortViewController.swift; sourceTree = "<group>"; };
6B02216322BA11D500AEB14D /* Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extension.swift; sourceTree = "<group>"; };
6B02216522BA177F00AEB14D /* InsertionSortViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InsertionSortViewController.xib; sourceTree = "<group>"; };
6B02216722BB7FA800AEB14D /* TopViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopViewController.swift; sourceTree = "<group>"; };
6B02216922BB824600AEB14D /* TopViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TopViewController.xib; sourceTree = "<group>"; };
6B46555522B6AB0C005202D1 /* MountainsRawData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MountainsRawData.swift; sourceTree = SOURCE_ROOT; };
6B46555722B6AB15005202D1 /* MountainsRawData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MountainsRawData.swift; sourceTree = SOURCE_ROOT; };
6B46555922B6AC83005202D1 /* LabelItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelItem.swift; sourceTree = "<group>"; };
6BA3A77B22B549B700AD51ED /* DiffableDataSources.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DiffableDataSources.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6BA3A77D22B549B700AD51ED /* DifferenceKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DifferenceKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6BA3A78122B5515D00AD51ED /* LabelCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelCell.swift; sourceTree = "<group>"; };
6BA3A78322B5516500AD51ED /* LabelCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LabelCell.xib; sourceTree = "<group>"; };
6BA3A78722B5565E00AD51ED /* MountainsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MountainsViewController.xib; sourceTree = "<group>"; };
6BA3A79922B69EDF00AD51ED /* Example-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6BA3A79B22B69EDF00AD51ED /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
6BA3A79D22B69EDF00AD51ED /* MountainsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainsViewController.swift; sourceTree = "<group>"; };
6BA3A79F22B69EE200AD51ED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
6BA3A7A222B69EE200AD51ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
6BA3A7A422B69EE200AD51ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6BA3A7A522B69EE200AD51ED /* Example_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Example_macOS.entitlements; sourceTree = "<group>"; };
6BB7630322B545240050DC03 /* Example-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6BB7630622B545240050DC03 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
6BB7630822B545240050DC03 /* MountainsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainsViewController.swift; sourceTree = "<group>"; };
6BB7630D22B545260050DC03 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
6BB7631022B545260050DC03 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
6BB7631222B545260050DC03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6BA3A79622B69EDF00AD51ED /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6BA3A7AB22B6A04F00AD51ED /* DifferenceKit.framework in Frameworks */,
6BA3A7A922B6A04F00AD51ED /* DiffableDataSources.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6BB7630022B545240050DC03 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6BA3A79022B55FB000AD51ED /* DifferenceKit.framework in Frameworks */,
6BA3A78E22B55FB000AD51ED /* DiffableDataSources.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
6BA3A79A22B69EDF00AD51ED /* Example-macOS */ = {
isa = PBXGroup;
children = (
6BA3A79D22B69EDF00AD51ED /* MountainsViewController.swift */,
6B46555922B6AC83005202D1 /* LabelItem.swift */,
6B46555722B6AB15005202D1 /* MountainsRawData.swift */,
6BA3A79B22B69EDF00AD51ED /* AppDelegate.swift */,
6BA3A7A122B69EE200AD51ED /* Main.storyboard */,
6BA3A79F22B69EE200AD51ED /* Assets.xcassets */,
6BA3A7A422B69EE200AD51ED /* Info.plist */,
6BA3A7A522B69EE200AD51ED /* Example_macOS.entitlements */,
);
path = "Example-macOS";
sourceTree = "<group>";
};
6BB762FA22B545240050DC03 = {
isa = PBXGroup;
children = (
6BB7630522B545240050DC03 /* Example-iOS */,
6BA3A79A22B69EDF00AD51ED /* Example-macOS */,
6BB7630422B545240050DC03 /* Products */,
6BB7632122B5467B0050DC03 /* Frameworks */,
);
sourceTree = "<group>";
};
6BB7630422B545240050DC03 /* Products */ = {
isa = PBXGroup;
children = (
6BB7630322B545240050DC03 /* Example-iOS.app */,
6BA3A79922B69EDF00AD51ED /* Example-macOS.app */,
);
name = Products;
sourceTree = "<group>";
};
6BB7630522B545240050DC03 /* Example-iOS */ = {
isa = PBXGroup;
children = (
6B02216722BB7FA800AEB14D /* TopViewController.swift */,
6B02216922BB824600AEB14D /* TopViewController.xib */,
6BB7630822B545240050DC03 /* MountainsViewController.swift */,
6BA3A78722B5565E00AD51ED /* MountainsViewController.xib */,
6B02216122BA0EF500AEB14D /* InsertionSortViewController.swift */,
6B02216522BA177F00AEB14D /* InsertionSortViewController.xib */,
6BA3A78122B5515D00AD51ED /* LabelCell.swift */,
6BA3A78322B5516500AD51ED /* LabelCell.xib */,
6B02216322BA11D500AEB14D /* Extension.swift */,
6B46555522B6AB0C005202D1 /* MountainsRawData.swift */,
6BB7630622B545240050DC03 /* AppDelegate.swift */,
6BB7630D22B545260050DC03 /* Assets.xcassets */,
6BB7630F22B545260050DC03 /* LaunchScreen.storyboard */,
6BB7631222B545260050DC03 /* Info.plist */,
);
path = "Example-iOS";
sourceTree = "<group>";
};
6BB7632122B5467B0050DC03 /* Frameworks */ = {
isa = PBXGroup;
children = (
6BA3A77B22B549B700AD51ED /* DiffableDataSources.framework */,
6BA3A77D22B549B700AD51ED /* DifferenceKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6BA3A79822B69EDF00AD51ED /* Example-macOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6BA3A7A822B69EE200AD51ED /* Build configuration list for PBXNativeTarget "Example-macOS" */;
buildPhases = (
6BA3A79522B69EDF00AD51ED /* Sources */,
6BA3A79622B69EDF00AD51ED /* Frameworks */,
6BA3A79722B69EDF00AD51ED /* Resources */,
6BA3A7AD22B6A05000AD51ED /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "Example-macOS";
productName = "Example-macOS";
productReference = 6BA3A79922B69EDF00AD51ED /* Example-macOS.app */;
productType = "com.apple.product-type.application";
};
6BB7630222B545240050DC03 /* Example-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6BB7631522B545260050DC03 /* Build configuration list for PBXNativeTarget "Example-iOS" */;
buildPhases = (
6BB762FF22B545240050DC03 /* Sources */,
6BB7630022B545240050DC03 /* Frameworks */,
6BB7630122B545240050DC03 /* Resources */,
6BA3A79222B55FB000AD51ED /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "Example-iOS";
productName = "DiffableDataSourcesExample-iOS";
productReference = 6BB7630322B545240050DC03 /* Example-iOS.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
6BB762FB22B545240050DC03 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1020;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Ryo Aoyama";
TargetAttributes = {
6BA3A79822B69EDF00AD51ED = {
CreatedOnToolsVersion = 10.2.1;
};
6BB7630222B545240050DC03 = {
CreatedOnToolsVersion = 10.2.1;
};
};
};
buildConfigurationList = 6BB762FE22B545240050DC03 /* Build configuration list for PBXProject "DiffableDataSourcesExamples" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 6BB762FA22B545240050DC03;
productRefGroup = 6BB7630422B545240050DC03 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
6BB7630222B545240050DC03 /* Example-iOS */,
6BA3A79822B69EDF00AD51ED /* Example-macOS */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
6BA3A79722B69EDF00AD51ED /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6BA3A7A022B69EE200AD51ED /* Assets.xcassets in Resources */,
6BA3A7A322B69EE200AD51ED /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6BB7630122B545240050DC03 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6BA3A78422B5516500AD51ED /* LabelCell.xib in Resources */,
6B02216622BA177F00AEB14D /* InsertionSortViewController.xib in Resources */,
6B02216A22BB824600AEB14D /* TopViewController.xib in Resources */,
6BA3A78822B5565E00AD51ED /* MountainsViewController.xib in Resources */,
6BB7631122B545260050DC03 /* LaunchScreen.storyboard in Resources */,
6BB7630E22B545260050DC03 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
6BA3A79522B69EDF00AD51ED /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6BA3A79E22B69EDF00AD51ED /* MountainsViewController.swift in Sources */,
6B46555A22B6AC83005202D1 /* LabelItem.swift in Sources */,
6B46555822B6AB15005202D1 /* MountainsRawData.swift in Sources */,
6BA3A79C22B69EDF00AD51ED /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6BB762FF22B545240050DC03 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6BB7630922B545240050DC03 /* MountainsViewController.swift in Sources */,
6BA3A78222B5515D00AD51ED /* LabelCell.swift in Sources */,
6B02216422BA11D500AEB14D /* Extension.swift in Sources */,
6B02216222BA0EF500AEB14D /* InsertionSortViewController.swift in Sources */,
6BB7630722B545240050DC03 /* AppDelegate.swift in Sources */,
6B46555622B6AB0C005202D1 /* MountainsRawData.swift in Sources */,
6B02216822BB7FA800AEB14D /* TopViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
6BA3A7A122B69EE200AD51ED /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
6BA3A7A222B69EE200AD51ED /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
6BB7630F22B545260050DC03 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
6BB7631022B545260050DC03 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
6BA3A7A622B69EE200AD51ED /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "Example-macOS/Example_macOS.entitlements";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "Example-macOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.DiffableDataSourcesExample-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
6BA3A7A722B69EE200AD51ED /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "Example-macOS/Example_macOS.entitlements";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "Example-macOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.DiffableDataSourcesExample-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Release;
};
6BB7631322B545260050DC03 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
6BB7631422B545260050DC03 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
6BB7631622B545260050DC03 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
GCC_OPTIMIZATION_LEVEL = s;
INFOPLIST_FILE = "Example-iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.DiffableDataSourcesExample-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = "";
};
name = Debug;
};
6BB7631722B545260050DC03 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "Example-iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.ryo.DiffableDataSourcesExample-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
6BA3A7A822B69EE200AD51ED /* Build configuration list for PBXNativeTarget "Example-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6BA3A7A622B69EE200AD51ED /* Debug */,
6BA3A7A722B69EE200AD51ED /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6BB762FE22B545240050DC03 /* Build configuration list for PBXProject "DiffableDataSourcesExamples" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6BB7631322B545260050DC03 /* Debug */,
6BB7631422B545260050DC03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6BB7631522B545260050DC03 /* Build configuration list for PBXNativeTarget "Example-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6BB7631622B545260050DC03 /* Debug */,
6BB7631722B545260050DC03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 6BB762FB22B545240050DC03 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:DiffableDataSourcesExample-iOS.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB7630222B545240050DC03"
BuildableName = "Example-iOS.app"
BlueprintName = "Example-iOS"
ReferencedContainer = "container:DiffableDataSourcesExamples.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB7630222B545240050DC03"
BuildableName = "Example-iOS.app"
BlueprintName = "Example-iOS"
ReferencedContainer = "container:DiffableDataSourcesExamples.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB7630222B545240050DC03"
BuildableName = "Example-iOS.app"
BlueprintName = "Example-iOS"
ReferencedContainer = "container:DiffableDataSourcesExamples.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB7630222B545240050DC03"
BuildableName = "Example-iOS.app"
BlueprintName = "Example-iOS"
ReferencedContainer = "container:DiffableDataSourcesExamples.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:DiffableDataSourcesExamples.xcodeproj">
</FileRef>
<FileRef
location = "group:../DiffableDataSources.xcodeproj">
</FileRef>
<FileRef
location = "group:../Carthage/Checkouts/DifferenceKit/DifferenceKit.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+17
View File
@@ -0,0 +1,17 @@
import UIKit
@UIApplicationMain
final class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
let window = UIWindow()
let navigationController = UINavigationController(rootViewController: TopViewController())
navigationController.navigationBar.tintColor = .black
window.rootViewController = navigationController
window.makeKeyAndVisible()
self.window = window
return true
}
}
@@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
+13
View File
@@ -0,0 +1,13 @@
import UIKit
extension UITableViewCell {
static var name: String {
return String(describing: self)
}
}
extension UICollectionViewCell {
static var name: String {
return String(describing: self)
}
}
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string></string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -0,0 +1,172 @@
import UIKit
import DiffableDataSources
final class InsertionSortViewController: UIViewController {
final class Section: Hashable {
var id = UUID()
var nodes: [Node]
private(set) var isSorted = false
private var currentIndex = 1
init(count: Int) {
nodes = (0..<count).map { Node(value: $0, maxValue: count) }.shuffled()
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
func sortNext() {
guard !isSorted, nodes.count > 1 else {
return isSorted = true
}
var index = currentIndex
let currentNode = nodes[index]
index -= 1
while index >= 0 && currentNode.value < nodes[index].value {
let node = nodes[index]
nodes[index] = currentNode
nodes[index + 1] = node
index -= 1
}
currentIndex += 1
if currentIndex >= nodes.count {
isSorted = true
}
}
static func == (lhs: Section, rhs: Section) -> Bool {
return lhs.id == rhs.id
}
}
struct Node: Hashable {
var id = UUID()
var value: Int
var color: UIColor
init(value: Int, maxValue: Int) {
let hue = CGFloat(value) / CGFloat(maxValue)
self.value = value
color = UIColor(hue: hue, saturation: 1, brightness: 1, alpha: 1)
id = UUID()
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
static func == (lhs: Node, rhs: Node) -> Bool {
return lhs.id == rhs.id
}
}
@IBOutlet private var collectionView: UICollectionView!
private var isSorting = false
let nodeSize = CGSize(width: 16, height: 34)
private lazy var dataSource = CollectionViewDiffableDataSource<Section, Node>(collectionView: collectionView) { collectionView, indexPath, node in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UICollectionViewCell.name, for: indexPath)
cell.backgroundColor = node.color
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Insertion Sort"
collectionView.delegate = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: UICollectionViewCell.name)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: nil, style: .plain, target: self, action: #selector(toggleSort))
updateSortButtonTitle()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
randmize(animated: false)
}
@objc func toggleSort() {
isSorting.toggle()
updateSortButtonTitle()
if isSorting {
startInsertionSort()
}
}
func updateSortButtonTitle() {
navigationItem.rightBarButtonItem?.title = isSorting ? "Stop" : "Sort"
}
func randmize(animated: Bool) {
let snapshot = DiffableDataSourceSnapshot<Section, Node>()
let rows = Int(collectionView.bounds.height / nodeSize.height) - 1
let columns = Int(collectionView.bounds.width / nodeSize.width)
for _ in 0..<rows {
let section = Section(count: columns)
snapshot.appendSections([section])
snapshot.appendItems(section.nodes)
}
dataSource.apply(snapshot, animatingDifferences: animated)
}
func startInsertionSort() {
guard isSorting else {
return
}
var isNextSortRequired = false
let snapshot = dataSource.snapshot()
for section in snapshot.sectionIdentifiers where !section.isSorted {
section.sortNext()
let items = section.nodes
snapshot.deleteItems(items)
snapshot.appendItems(items, toSection: section)
isNextSortRequired = true
}
if isNextSortRequired {
dataSource.apply(snapshot)
}
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(isNextSortRequired ? 150 : 1000)) { [weak self] in
guard let self = self else {
return
}
if !isNextSortRequired {
self.randmize(animated: false)
}
self.startInsertionSort()
}
}
}
extension InsertionSortViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return nodeSize
}
}
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="InsertionSortViewController" customModule="Example_iOS" customModuleProvider="target">
<connections>
<outlet property="collectionView" destination="6GZ-26-LaT" id="93h-pF-UdX"/>
<outlet property="view" destination="iN0-l3-epB" id="SEV-ah-gIe"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="6GZ-26-LaT">
<rect key="frame" x="0.0" y="44" width="414" height="852"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="IOA-0B-TAt">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
</collectionView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="6GZ-26-LaT" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="N1l-xD-bVR"/>
<constraint firstAttribute="trailing" secondItem="6GZ-26-LaT" secondAttribute="trailing" id="WAV-gN-b0a"/>
<constraint firstAttribute="bottom" secondItem="6GZ-26-LaT" secondAttribute="bottom" id="cwF-t5-pdY"/>
<constraint firstItem="6GZ-26-LaT" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="lef-dU-E4k"/>
</constraints>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
</view>
</objects>
</document>
+12
View File
@@ -0,0 +1,12 @@
import UIKit
final class LabelCell: UICollectionViewCell {
@IBOutlet var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
layer.borderWidth = 1
layer.borderColor = UIColor.gray.cgColor
}
}
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="pYo-4D-KR8" customClass="LabelCell" customModule="Example_iOS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="300" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO">
<rect key="frame" x="0.0" y="0.0" width="300" height="32"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qKi-9G-J20">
<rect key="frame" x="10" y="0.0" width="280" height="32"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<constraints>
<constraint firstItem="qKi-9G-J20" firstAttribute="leading" secondItem="pYo-4D-KR8" secondAttribute="leading" constant="10" id="UJN-ZW-lz4"/>
<constraint firstAttribute="trailing" secondItem="qKi-9G-J20" secondAttribute="trailing" constant="10" id="VbK-qH-sMr"/>
<constraint firstItem="qKi-9G-J20" firstAttribute="top" secondItem="pYo-4D-KR8" secondAttribute="top" id="YkZ-vn-KK6"/>
<constraint firstAttribute="bottom" secondItem="qKi-9G-J20" secondAttribute="bottom" id="au1-M8-Hh2"/>
</constraints>
<viewLayoutGuide key="safeArea" id="wQ5-Q0-9Pt"/>
<connections>
<outlet property="label" destination="qKi-9G-J20" id="hp7-fh-rao"/>
</connections>
<point key="canvasLocation" x="-1" y="74"/>
</collectionViewCell>
</objects>
</document>
@@ -0,0 +1,84 @@
import UIKit
import DiffableDataSources
final class MountainsViewController: UIViewController {
enum Section {
case main
}
struct Mountain: Hashable {
var name: String
func contains(_ filter: String) -> Bool {
guard !filter.isEmpty else {
return true
}
let lowercasedFilter = filter.lowercased()
return name.lowercased().contains(lowercasedFilter)
}
}
@IBOutlet private var searchBar: UISearchBar!
@IBOutlet private var collectionView: UICollectionView!
private lazy var dataSource = CollectionViewDiffableDataSource<Section, Mountain>(collectionView: collectionView) { collectionView, indexPath, mountain in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LabelCell.name, for: indexPath) as! LabelCell
cell.label.text = mountain.name
return cell
}
private let allMountains: [Mountain] = mountainsRawData.components(separatedBy: .newlines).map { line in
let name = line.components(separatedBy: ",")[0]
return Mountain(name: name)
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Mountains Search"
searchBar.delegate = self
collectionView.delegate = self
collectionView.register(UINib(nibName: LabelCell.name, bundle: .main), forCellWithReuseIdentifier: LabelCell.name)
search(filter: "")
}
func search(filter: String) {
let mountains = allMountains.lazy
.filter { $0.contains(filter) }
.sorted { $0.name < $1.name }
let snapshot = DiffableDataSourceSnapshot<Section, Mountain>()
snapshot.appendSections([.main])
snapshot.appendItems(mountains)
dataSource.apply(snapshot)
}
}
extension MountainsViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
search(filter: searchText)
}
}
extension MountainsViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let column = 2
let width = (collectionView.bounds.width - 10 * CGFloat(column + 1)) / CGFloat(column)
return CGSize(width: width, height: 32)
}
}
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MountainsViewController" customModule="DiffableDataSourcesExample_iOS" customModuleProvider="target">
<connections>
<outlet property="collectionView" destination="kRf-0w-rJc" id="OBe-Sd-A2L"/>
<outlet property="searchBar" destination="t4I-uz-ABD" id="NtR-qE-qZn"/>
<outlet property="view" destination="a1D-Hd-aJU" id="Oyu-9w-QKH"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="a1D-Hd-aJU">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<searchBar contentMode="redraw" translatesAutoresizingMaskIntoConstraints="NO" id="t4I-uz-ABD">
<rect key="frame" x="0.0" y="44" width="414" height="56"/>
<textInputTraits key="textInputTraits"/>
</searchBar>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="onDrag" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="kRf-0w-rJc">
<rect key="frame" x="0.0" y="120" width="414" height="776"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="vHO-Ju-ApP">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
</collectionView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="kRf-0w-rJc" secondAttribute="bottom" id="CBM-WJ-k93"/>
<constraint firstItem="t4I-uz-ABD" firstAttribute="leading" secondItem="a1D-Hd-aJU" secondAttribute="leading" id="H5j-5C-2jy"/>
<constraint firstAttribute="trailing" secondItem="kRf-0w-rJc" secondAttribute="trailing" id="Hog-jr-nJY"/>
<constraint firstItem="t4I-uz-ABD" firstAttribute="top" secondItem="ujY-YI-BSN" secondAttribute="top" id="IkY-zg-lm8"/>
<constraint firstItem="kRf-0w-rJc" firstAttribute="top" secondItem="t4I-uz-ABD" secondAttribute="bottom" constant="20" id="aJ9-Wc-4Jd"/>
<constraint firstAttribute="trailing" secondItem="t4I-uz-ABD" secondAttribute="trailing" id="d5P-My-ReY"/>
<constraint firstItem="kRf-0w-rJc" firstAttribute="leading" secondItem="a1D-Hd-aJU" secondAttribute="leading" id="esv-zM-Pc2"/>
</constraints>
<viewLayoutGuide key="safeArea" id="ujY-YI-BSN"/>
<point key="canvasLocation" x="17" y="173"/>
</view>
</objects>
</document>
@@ -0,0 +1,82 @@
import UIKit
import DiffableDataSources
final class TopViewController: UIViewController {
enum Section {
case main
}
enum Item {
case mountains
case insertionSort
}
@IBOutlet private var tableView: UITableView!
private lazy var dataSource = TableViewDiffableDataSource<Section, Item>(tableView: tableView) { tableView, indexPath, item in
let cell = tableView.dequeueReusableCell(withIdentifier: UITableViewCell.name, for: indexPath)
cell.textLabel?.text = item.title
cell.accessoryType = .disclosureIndicator
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
title = "DiffableDataSources"
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: UITableViewCell.name)
tableView.rowHeight = 60
tableView.contentInset.top = 30
reset()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let indexPath = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: indexPath, animated: true)
}
}
func reset() {
let snapshot = DiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems([.mountains, .insertionSort])
dataSource.apply(snapshot)
}
}
extension TopViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let item = dataSource.itemIdentifier(for: indexPath) else {
return
}
let viewController: UIViewController
switch item {
case .mountains:
viewController = MountainsViewController()
case .insertionSort:
viewController = InsertionSortViewController()
}
navigationController?.pushViewController(viewController, animated: true)
}
}
private extension TopViewController.Item {
var title: String {
switch self {
case .mountains:
return "🗻 Mountains"
case .insertionSort:
return "📱 Insertion Sort"
}
}
}
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TopViewController" customModule="Example_iOS" customModuleProvider="target">
<connections>
<outlet property="tableView" destination="tX9-V1-EJv" id="EHH-CF-6fE"/>
<outlet property="view" destination="Ude-8O-7bT" id="VCy-jI-QZK"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="Ude-8O-7bT">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="tX9-V1-EJv">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="tX9-V1-EJv" secondAttribute="bottom" id="0fN-0u-kPN"/>
<constraint firstItem="tX9-V1-EJv" firstAttribute="top" secondItem="Ude-8O-7bT" secondAttribute="top" id="NML-7Q-dfc"/>
<constraint firstItem="tX9-V1-EJv" firstAttribute="leading" secondItem="Ude-8O-7bT" secondAttribute="leading" id="h66-Ya-k2Y"/>
<constraint firstAttribute="trailing" secondItem="tX9-V1-EJv" secondAttribute="trailing" id="phG-hF-KAp"/>
</constraints>
<viewLayoutGuide key="safeArea" id="iZn-f5-WVt"/>
<point key="canvasLocation" x="68" y="141"/>
</view>
</objects>
</document>
+4
View File
@@ -0,0 +1,4 @@
import Cocoa
@NSApplicationMain
final class AppDelegate: NSObject, NSApplicationDelegate {}
@@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,773 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14810.11" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14810.11"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="Example-macOS" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Example-macOS" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About Example-macOS" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide Example-macOS" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit Example-macOS" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
<connections>
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
<connections>
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
<connections>
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
<items>
<menuItem title="Font" id="Gi5-1S-RQB">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
<items>
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
<connections>
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
</connections>
</menuItem>
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
</connections>
</menuItem>
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
</connections>
</menuItem>
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
<connections>
<action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
</connections>
</menuItem>
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
<menuItem title="Kern" id="jBQ-r6-VK2">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
<items>
<menuItem title="Use Default" id="GUa-eO-cwY">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
</connections>
</menuItem>
<menuItem title="Use None" id="cDB-IK-hbR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
</connections>
</menuItem>
<menuItem title="Tighten" id="46P-cB-AYj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
</connections>
</menuItem>
<menuItem title="Loosen" id="ogc-rX-tC1">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Ligatures" id="o6e-r0-MWq">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
<items>
<menuItem title="Use Default" id="agt-UL-0e3">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
</connections>
</menuItem>
<menuItem title="Use None" id="J7y-lM-qPV">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
</connections>
</menuItem>
<menuItem title="Use All" id="xQD-1f-W4t">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Baseline" id="OaQ-X3-Vso">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
<items>
<menuItem title="Use Default" id="3Om-Ey-2VK">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
</connections>
</menuItem>
<menuItem title="Superscript" id="Rqc-34-cIF">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
</connections>
</menuItem>
<menuItem title="Subscript" id="I0S-gh-46l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
</connections>
</menuItem>
<menuItem title="Raise" id="2h7-ER-AoG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
</connections>
</menuItem>
<menuItem title="Lower" id="1tx-W0-xDw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
<connections>
<action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
</connections>
</menuItem>
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Text" id="Fal-I4-PZk">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Text" id="d9c-me-L2H">
<items>
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
<connections>
<action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
</connections>
</menuItem>
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
<connections>
<action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
</connections>
</menuItem>
<menuItem title="Justify" id="J5U-5w-g23">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
</connections>
</menuItem>
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
<connections>
<action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
<menuItem title="Writing Direction" id="H1b-Si-o9J">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
<items>
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="YGs-j5-SAR">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
</connections>
</menuItem>
<menuItem id="Lbh-J2-qVU">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
</connections>
</menuItem>
<menuItem id="jFq-tB-4Kx">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="Nop-cj-93Q">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
</connections>
</menuItem>
<menuItem id="BgM-ve-c93">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
</connections>
</menuItem>
<menuItem id="RB4-Sm-HuC">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
<menuItem title="Show Ruler" id="vLm-3I-IUL">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
</connections>
</menuItem>
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
</connections>
</menuItem>
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
</connections>
</menuItem>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="Example-macOS Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Example_macOS" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
</connections>
</window>
<connections>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
</connections>
</windowController>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="250"/>
</scene>
<!--Mountains View Controller-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="MountainsViewController" customModule="Example_macOS" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView wantsLayer="YES" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4GE-cR-LXC">
<rect key="frame" x="0.0" y="0.0" width="480" height="226"/>
<clipView key="contentView" id="4a9-Kh-LYH">
<rect key="frame" x="1" y="1" width="478" height="224"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView id="dtA-VK-I9R">
<rect key="frame" x="0.0" y="0.0" width="478" height="224"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="eNu-C9-mnA">
<size key="itemSize" width="50" height="50"/>
</collectionViewFlowLayout>
<color key="primaryBackgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</collectionView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="L20-kk-UVn">
<rect key="frame" x="-100" y="-100" width="233" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="asA-yX-Sp8">
<rect key="frame" x="463" y="1" width="16" height="224"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<searchField wantsLayer="YES" verticalHuggingPriority="750" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E8d-oD-QL3">
<rect key="frame" x="0.0" y="226" width="480" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="bgu-eY-Zmy"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="YVe-iR-NNY">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<action selector="searchFieldDidChangeText:" target="XfG-lQ-9wD" id="Gr9-gO-Z7U"/>
</connections>
</searchField>
</subviews>
<constraints>
<constraint firstItem="4GE-cR-LXC" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="VIk-Ok-vIc"/>
<constraint firstItem="4GE-cR-LXC" firstAttribute="top" secondItem="E8d-oD-QL3" secondAttribute="bottom" id="XQU-W6-iZ1"/>
<constraint firstAttribute="bottom" secondItem="4GE-cR-LXC" secondAttribute="bottom" id="YzV-Nw-2Vr"/>
<constraint firstItem="E8d-oD-QL3" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="ZFg-Fj-FCw"/>
<constraint firstItem="E8d-oD-QL3" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" id="gxF-Uq-fEV"/>
<constraint firstAttribute="trailing" secondItem="E8d-oD-QL3" secondAttribute="trailing" id="iJG-BW-3qO"/>
<constraint firstAttribute="trailing" secondItem="4GE-cR-LXC" secondAttribute="trailing" id="icw-4L-Z2L"/>
</constraints>
</view>
<connections>
<outlet property="collectionView" destination="dtA-VK-I9R" id="gbo-bM-Eme"/>
<outlet property="searchField" destination="E8d-oD-QL3" id="eKx-B7-AkC"/>
</connections>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="655"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 Ryo Aoyama. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
+31
View File
@@ -0,0 +1,31 @@
import AppKit
final class LabelItem: NSCollectionViewItem {
static var itemIdentifier: NSUserInterfaceItemIdentifier {
return NSUserInterfaceItemIdentifier(String(describing: self))
}
let label = NSTextField()
override func loadView() {
view = NSView()
}
override func viewDidLoad() {
super.viewDidLoad()
label.textColor = .gray
label.font = .systemFont(ofSize: 16)
label.isEditable = false
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
let constraints = [
label.topAnchor.constraint(equalTo: view.topAnchor),
label.bottomAnchor.constraint(equalTo: view.bottomAnchor),
label.leadingAnchor.constraint(equalTo: view.leadingAnchor),
label.trailingAnchor.constraint(equalTo: view.trailingAnchor)
]
NSLayoutConstraint.activate(constraints)
}
}
@@ -0,0 +1,81 @@
import AppKit
import DiffableDataSources
final class MountainsViewController: NSViewController {
enum Section {
case main
}
struct Mountain: Hashable {
var name: String
func contains(_ filter: String) -> Bool {
guard !filter.isEmpty else {
return true
}
let lowercasedFilter = filter.lowercased()
return name.lowercased().contains(lowercasedFilter)
}
}
@IBOutlet private var searchField: NSSearchField!
@IBOutlet private var collectionView: NSCollectionView!
private lazy var dataSource = CocoaCollectionViewDiffableDataSource<Section, Mountain>(collectionView: collectionView) { collectionView, indexPath, mountain in
let item = collectionView.makeItem(withIdentifier: LabelItem.itemIdentifier, for: indexPath) as! LabelItem
item.label.stringValue = mountain.name
return item
}
private let allMountains: [Mountain] = mountainsRawData.components(separatedBy: .newlines).map { line in
let name = line.components(separatedBy: ",")[0]
return Mountain(name: name)
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Mountains Search"
collectionView.delegate = self
collectionView.register(LabelItem.self, forItemWithIdentifier: LabelItem.itemIdentifier)
search(filter: "")
}
func search(filter: String) {
let mountains = allMountains.lazy
.filter { $0.contains(filter) }
.sorted { $0.name < $1.name }
let snapshot = DiffableDataSourceSnapshot<Section, Mountain>()
snapshot.appendSections([.main])
snapshot.appendItems(mountains)
dataSource.apply(snapshot)
}
@IBAction func searchFieldDidChangeText(_ sender: NSSearchField) {
search(filter: sender.stringValue)
}
}
extension MountainsViewController: NSCollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets {
return NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
}
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
let column = 3
let width = (collectionView.bounds.width - 10 * CGFloat(column + 1)) / CGFloat(column)
return CGSize(width: width, height: 44)
}
}
+391
View File
@@ -0,0 +1,391 @@
// https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/using_collection_view_compositional_layouts_and_diffable_data_sources
let mountainsRawData = """
Mount Everest,8848
K2,8611
Kangchenjunga,8586
Lhotse,8516
Makalu,8485
Cho Oyu,8201
Dhaulagiri,8167
Manaslu,8163
Nanga Parbat,8126
Annapurna,8091
Gasherbrum I,8080
Broad Peak,8051
Gasherbrum II,8035
Shishapangma,8027
Gasherbrum III,7952
Gyachung Kang,7952
Annapurna II,7937
Gasherbrum IV,7932
Himalchuli,7893
Distaghil Sar,7885
Ngadi Chuli,7871
Nuptse,7861
Khunyang Chhish,7852
Masherbrum,7821
Nanda Devi,7816
Chomo Lonzo,7804
Batura Sar,7795
Kanjut Sar,7790
Rakaposhi,7788
Namcha Barwa,7782
Kamet,7756
Saltoro Kangri,7742
Jannu,7710
Tirich Mir,7708
Molamenqing,7703
Gurla Mandhata,7694
Saser Kangri,7672
Chogolisa,7665
Kongur Tagh,7649
Shispare,7611
Silberzacken,7597
Changtse,7583
Trivor,7577
Gangkhar Puensum,7570
Gongga Shan,7556
Annapurna III,7555
Kula Kangri,7554
Muztagh Ata,7546
Skyang Kangri,7545
Liankang Kangri,7535
Yukshin Gardan Sar,7530
Annapurna IV,7525
Mamostong Kangri,7516
Ismoil Somoni Peak,7495
Noshaq,7492
Pumari Chhish,7492
Passu Sar,7476
Malubiting,7458
Gangapurna,7455
Muchu Chhish (Batura V),7453
Jengish Chokusu,7439
K12,7428
Sia Kangri,7422
Istor-o-Nal,7403
Ghent Kangri,7401
Haramosh Peak,7397
Kabru,7394
Ultar,7388
Rimo I,7385
Sherpi Kangri,7380
Labuche Kang,7367
Kirat Chuli,7365
Skil Brum,7360
Gimmigela Chuli,7350
Bojohagur Duanasir,7329
Chamlang,7319
Jomolhari / Chomolhari,7314
Baltoro Kangri,7312
Siguang Ri,7308
The Crown,7295
Gyala Peri,7294
Porong Ri,7292
Baintha Brakk,7285
Yutmaru Sar,7283
K6,7282
Kangpenqing,7281
Mana Peak,7272
Muztagh Tower,7273
Diran,7257
Apsarasas Kangri,7245
Langtang Lirung,7227
Khartaphu,7213
Tongshanjiabu,7207
Langtang Ri,7205
Kangphu Kang,7204
Annapurna South,7219
Melungtse,7181
Liushi Shan,7167
Baruntse,7162
Pumori,7161
Hardeol,7151
Gasherbrum V,7147
Latok I,7145
Nemjung,7140
Udren Zom,7140
Chaukhamba,7138
Nun Kun,7135
Tilicho Peak,7134
Gauri Sankar,7134
Lenin Peak,7134
Api,7132
Pauhunri,7128
Trisul,7120
Korzhenevskaya,7105
Lunpo Gangri,7095
Satopanth,7075
Tirsuli,7074
Dunagiri,7066
Kangto,7060
Nyegyi Kansang,7047
Link Sar,7041
Kezhen Peak,7038
Shah Dhar,7038
Spantik,7027
Khan Tengri,7010
Machapuchare,6993
Laila Peak (Haramosh Valley),6985
Kang Guru,6981
Gasherbrum VI,6979
Karun Kuh,6977
Avicenna Peak,6974
Ulugh Muztagh,6973
Aconcagua,6962
Napko Kangri,6956
Kedarnath,6940
K7,6934
Panchchuli,6904
Thalay Sagar,6904
Lunkho e Dosare,6901
Lunag Ri,6895
Ojos del Salado,6891
Siniolchu,6888
Kanjiroba,6883
Bairiga,6882
Koyo Zom,6872
Nanda Kot,6861
Kubi Gangri,6859
Angel Sar,6858
Bhagirathi I,6856
Jethi Bahurani,6850
Chongra Peak,6830
Reo Purgyil,6816
Ama Dablam,6812
Monte Pissis,6795
Biarchedi,6781
Huascarán Sur,6768
Cerro Bonete,6759
Nevado Tres Cruces,6748
Kawagarbo,6740
Llullaillaco,6739
Cho Polu,6735
Kangju Kangri,6725
Changla,6721
Mercedario,6720
Mount Pandim,6691
Num Ri,6677
Lungser Kangri,6666
Meru Peak,6660
Gul Lasht Zom,6657
Huascarán Norte,6655
Khumbutse,6640
Mount Kailash,6638
Yerupajá,6635
Nevado Tres Cruces Central,6629
Thamserku,6623
Geladaindong Peak,6621
Incahuasi,6621
Pangpoche,6620
Manirang,6597
Nilkantha,6596
Phuparash Peak,6574
Sickle Moon Peak,6574
Buni Zom,6542
Nevado Sajama,6542
Ghamubar Zom,6518
Singu Chuli,6501
Taboche,6501
Cerro El Muerto,6488
Mera Peak,6476
Hiunchuli,6441
Cholatse,6440
Illimani,6438
Ancohuma,6427
Coropuna,6425
Antofalla,6409
Kang Yatze,6400
Huandoy,6395
Ausangate,6384
Illampu,6368
Kusum Kangguru,6367
Kinnaur Kailash,6349
Parinaquta,6348
Siula Grande,6344
Bamba Dhura,6334
Ampato,6288
Amne Machin,6282
Pomerape,6282
Salcantay,6271
Chimborazo,6267
Mount Siguniang,6250
Grid Nie Mountain,6224
Yuzhu Peak,6224
Genyen Massif,6204
Kongde Ri,6187
Aucanquilcha,6176
Imja Tse,6189
Denali (Mt. McKinley),6168
Stok Kangri,6137
Lobuche,6119
Marmolejo,6108
Laila Peak (Hushe Valley),6096
Pisang Peak,6091
Huayna Potosí,6088
Aracar,6082
Chachakumani,6074
Chachani,6057
Mianzimu,6054
Acotango,6052
Socompa,6051
Acamarachi,6046
Shayaz,6026
Hualca Hualca,6025
Uturunku,6020
Mitre Peak,6010
Laila Peak,5971
Mount Logan,5959
Alpamayo,5947
Cerro Lípez,5929
Licancabur,5920
Falak Sar,5918
Cotopaxi,5897
Mount Kilimanjaro,5895
Hkakabo Razi,5881
San José,5856
El Misti,5822
Altun Shan,5798
Cayambe,5790
Pico Cristóbal Colón,5776
Antisana,5753
Nevado Pisco,5752
Nevado Anallajsi,5750
Pokalde,5745
Ubinas,5672
Pichu Pichu,5664
Mount Elbrus,5642
Mehrbani Peak,5639
Pico de Orizaba,5636
Mount Damavand,5610
Nevado Mismi,5597
Jade Dragon Snow Mountain,5596
Lascar Volcano,5592
Mount Xuebaoding,5588
Kala Patthar,5545
Mount Saint Elias,5489
Concord Peak,5469
Machoi Peak,5458
El Plomo,5450
Bogda Feng,5445
Mount Little Xuebaoding,5443
Cerro El Plomo,5434
Popocatépetl,5426
Kolahoi Peak,5425
Chacaltaya,5421
Mount Pomiu,5413
Ritacuba Blanco,5410
Haba Xueshan,5396
Nevado del Ruiz,5389
Nevado del Huila,5364
El Altar,5320
Mount Foraker,5304
Mount Haramukh,5300
Nevado del Tolima,5276
Maipo,5264
Illiniza,5248
Sirbal Peak,5236
Sangay,5230
Iztaccíhuatl,5230
Mount Lucania,5226
Dykh-Tau,5205
Shkhara,5201
Mount Kenya,5199
Malika Parbat,5190
Amarnath Peak,5186
King Peak,5173
Boris Yeltsin Peak,5168
Koshtan-Tau,5150
Mount Ararat,5137
Mount Stanley,5109
Mount Steele,5073
Janga,5051
Mount Kazbek,5047
Tungurahua,5023
Carihuairazo,5018
Mount Bona,5005
Mount Blackburn,4996
Pico Bolívar,4981
Pik Talgar,4979
Shota Rustaveli Peak,4960
Gunshar,4950
Mount Sanford,4949
Pico Humboldt,4940
Vinson Massif,4892
Pico Bonpland,4890
Puncak Jaya,4884
Pico La Concha,4870
Gistola,4860
Tetnuldi,4858
Mount Tyree,4852
Huaynaputina,4850
Alam Kuh,4850
Mount Wood,4842
Mount Vancouver,4812
Sabalan,4811
Mont Blanc,4810
Corazón,4790
Pichincha,4784
Jimara,4780
Mount Churchill,4766
Puncak Mandala,4760
Klyuchevskaya Sopka,4750
Puncak Trikora,4750
Mont Blanc de Courmayeur,4748
Sunset Peak,4745
Mount Slaggard,4742
Pico Piedras Blancas,4740
Pico El Toro,4730
Tatakooti Peak,4725
Rumiñahui,4721
Pico El Leon,4720
Ushba,4710
Volcán Domuyo,4709
Pico Los Nevados,4700
Pico Pan de Azucar,4680
Naltar Peak,4678
Mount Fairweather,4663
Pico Mucuñuque,4660
Pico El Buitre,4650
Khazret Sultan,4643
Sierra Negra,4640
Dufourspitze (Monte Rosa),4634
Dunantspitze (Monte Rosa),4632
Nordend (Monte Rosa),4609
Mount Hubbard,4577
Nevado de Toluca,4577
Mount Meru,4566
Zumsteinspitze (Monte Rosa),4563
Signalkuppe (Monte Rosa),4554
Dom,4545
Ras Dashen,4533
Eastern Liskamm (Lyskamm),4527
Mount Bear,4521
Mount Wilhelm,4509
Mount Karisimbi,4507
Mount Walsh,4507
Belukha Mountain,4506
Weisshorn,4506
Tebulosmta,4493
Täschhorn,4491
Bazarduzu Dagi,4485
Matterhorn,4478
Mount Rutford,4477
Mont Maudit,4465
Babis Mta,4454
Mount Shani,4451
Dena,4448
Vladimir Putin Peak,4446
Mount Hunter,4442
Parrotspitze (Monte Rosa),4432
Mount Whitney,4421
Mount Alverstone,4420
University Peak,4411
Aello Peak,4403
Mount Elbert,4402
Mount Massive,4395
Mount Harvard,4395
Mount Rainier,4392
Kholeno,4387
"""
+10
View File
@@ -0,0 +1,10 @@
<H1 align="center">
DiffableDataSources Examples
</H1>
## How to Run
1. Clone the DiffableDataSources repository.
1. Checkout the dependencies using terminal command `$ make setup` at the project root directory.
1. Open example project workspace.
1. Run.
+4
View File
@@ -0,0 +1,4 @@
source "https://rubygems.org"
gem 'cocoapods', '1.7.2'
gem 'jazzy', '0.9.4'
+103
View File
@@ -0,0 +1,103 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
atomos (0.1.3)
claide (1.0.2)
cocoapods (1.7.2)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.7.2)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.10.0, < 2.0)
cocoapods-core (1.7.2)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
colored2 (3.1.2)
concurrent-ruby (1.1.5)
escape (0.0.4)
ffi (1.11.1)
fourflusher (2.3.0)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jazzy (0.9.4)
cocoapods (~> 1.0)
mustache (~> 0.99)
open4
redcarpet (~> 3.2)
rouge (>= 2.0.6, < 4.0)
sass (~> 3.4)
sqlite3 (~> 1.3)
xcinvoke (~> 0.3.0)
liferaft (0.0.6)
minitest (5.11.3)
molinillo (0.6.6)
mustache (0.99.8)
nanaimo (0.2.6)
nap (1.1.0)
netrc (0.11.0)
open4 (1.3.4)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
redcarpet (3.4.0)
rouge (3.4.1)
ruby-macho (1.4.0)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sqlite3 (1.4.1)
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
xcinvoke (0.3.0)
liferaft (~> 0.0.6)
xcodeproj (1.10.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (= 1.7.2)
jazzy (= 0.9.4)
BUNDLED WITH
2.0.1
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+17
View File
@@ -0,0 +1,17 @@
setup:
git submodule update --init --recursive
carthage-submodule:
carthage update --no-build --use-submodules
gems-install:
bundle install --path vendor/bundle
docs-gen:
bundle exec jazzy --config .jazzy.yml
lib-lint:
bundle exec pod lib lint
pod-release:
bundle exec pod trunk push --allow-warnings
+16
View File
@@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "DifferenceKit",
"repositoryURL": "https://github.com/ra1028/DifferenceKit.git",
"state": {
"branch": null,
"revision": "4eb31f8e85e4cb13732f9664d6e01e507cd592a0",
"version": "1.1.3"
}
}
]
},
"version": 1
}
+29
View File
@@ -0,0 +1,29 @@
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "DiffableDataSources",
platforms: [
.iOS(.v9), .macOS(.v10_11), .tvOS(.v9)
],
products: [
.library(name: "DiffableDataSources", targets: ["DiffableDataSources"])
],
dependencies: [
.package(url: "https://github.com/ra1028/DifferenceKit.git", .upToNextMinor(from: "1.1.0"))
],
targets: [
.target(
name: "DiffableDataSources",
dependencies: ["DifferenceKit"],
path: "Sources"
),
.testTarget(
name: "DiffableDataSourcesTests",
dependencies: ["DiffableDataSources"],
path: "Tests"
)
],
swiftLanguageVersions: [.v5]
)
+208
View File
@@ -0,0 +1,208 @@
<H1 align="center">
DiffableDataSources
</H1>
<H4 align="center">
💾 A library for backporting UITableView/UICollectionViewDiffableDataSource</br>
powered by <a href="https://github.com/ra1028/DifferenceKit">DifferenceKit</a>.
</H4>
<p align="center">
<a href="https://developer.apple.com/swift"><img alt="Swift5" src="https://img.shields.io/badge/language-Swift5-orange.svg"/></a>
<a href="https://github.com/ra1028/DiffableDataSources/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/ra1028/DiffableDataSources.svg"/></a>
<a href="https://cocoapods.org/pods/DiffableDataSources"><img alt="CocoaPods" src="https://img.shields.io/cocoapods/v/DiffableDataSources.svg"/></a>
<a href="https://github.com/Carthage/Carthage"><img alt="Carthage" src="https://img.shields.io/badge/carthage-compatible-yellow.svg"/></a>
<a href="https://swift.org/package-manager"><img alt="Swift Package Manager" src="https://img.shields.io/badge/SwiftPM-compatible-yellowgreen.svg"/></a>
</br>
<a href="https://dev.azure.com/ra1028/GitHub/_build/latest?definitionId=3&branchName=master"><img alt="Build Status" src="https://dev.azure.com/ra1028/GitHub/_apis/build/status/ra1028.DiffableDataSources?branchName=master"/></a>
<a href="https://developer.apple.com/"><img alt="Platform" src="https://img.shields.io/badge/platform-iOS%20%7C%20macOS%20%7C%20tvOS-green.svg"/></a>
<a href="https://github.com/ra1028/DiffableDataSources/blob/master/LICENSE"><img alt="Lincense" src="https://img.shields.io/badge/License-Apache%202.0-black.svg"/></a>
</p>
<p align="center">
Made with ❤️ by <a href="https://github.com/ra1028">Ryo Aoyama</a>
</p>
---
## Introduction
<img src="https://raw.githubusercontent.com/ra1028/DiffableDataSources/master/assets/insertion_sort.gif" height="400" align="right">
<img src="https://raw.githubusercontent.com/ra1028/DiffableDataSources/master/assets/mountains.gif" height="400" align="right">
Apple has announced a diffable data source at WWDC 2019.
It's a great API that easily updating our table view and collection view items using automatic diffing.
However, it's a little while before we can use it in a production service.
That because it requires the latest OS to use.
DiffableDataSources make it possible to introduce almost the same functionality from now on.
Uses a sophisticated open source [DifferenceKit](https://github.com/ra1028/DifferenceKit) for the algorithm engine.
It's extremely fast and completely avoids synchronization bugs, exceptions, and crashes.
<br clear="all">
---
## Difference from the Official
#### Spec
- Supports iOS 9.0+ / macOS 10.11+ / tvOS 9.0+
- Open sourced algorithm.
- Duplicate sections or items are allowed.
- Using `performBatchUpdates` for diffing updates.
#### Namings
`DiffableDataSources` have different class names to avoid conflicts with the official API.
Correspondence table is below.
|Official |Backported |
|:---------------------------------------------------------------------------|:------------------------------------|
|[NSDiffableDataSourceSnapshot][NSDiffableDataSourceSnapshot_doc] |DiffableDataSourceSnapshot |
|[UITableViewDiffableDataSource][UITableViewDiffableDataSource_doc] |TableViewDiffableDataSource |
|[UICollectionViewDiffableDataSource][UICollectionViewDiffableDataSource_doc]|CollectionViewDiffableDataSource |
|[NSCollectionViewDiffableDataSource][NSCollectionViewDiffableDataSource_doc]|CocoaCollectionViewDiffableDataSource|
[NSDiffableDataSourceSnapshot_doc]: https://developer.apple.com/documentation/uikit/uitableviewdiffabledatasource
[UITableViewDiffableDataSource_doc]: https://developer.apple.com/documentation/uikit/uitableviewdiffabledatasource
[UICollectionViewDiffableDataSource_doc]: https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource
[NSCollectionViewDiffableDataSource_doc]: https://developer.apple.com/documentation/appkit/nscollectionviewdiffabledatasource
---
## Getting Started
- [API Documentation](https://ra1028.github.io/DiffableDataSources)
- [Example Apps](https://github.com/ra1028/DiffableDataSources/tree/master/Examples)
- [WWDC 2019 Session](https://developer.apple.com/videos/play/wwdc2019/220)
#### Build Project
```sh
$ git clone https://github.com/ra1028/DiffableDataSources.git
$ cd DiffableDataSources/
$ make setup
$ open DiffableDataSources.xcworkspace
```
---
## Basic Usage
First, define the type representing section.
It should conforms to `Hashable` for identifies from the all sections.
Type of enum can used conveniently befause it conforms `Hashable` by default.
```swift
enum Section {
case main
}
```
Then, define the item type conforms to `Hashable`.
```swift
struct User: Hashable {
var name: String
}
```
Create a data source object, it will be set to table view automatically.
You should dequeue the non nil cells via closure.
```swift
final class UsersViewController: UIViewController {
let tableView: UITableView = ...
lazy var dataSource = TableViewDiffableDataSource<Section, User>(tableView: tableView) { tableView, indexPath, user in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = user.name
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
}
```
Manages and updates the data sources intuitively by intermediating `DiffableDataSourceSnapshot`.
The UI isn't updated until you apply the edited snapshot object.
Update the UI with diffing animation automatically calculated by applying an edited snapshot.
```swift
let users = [
User(name: "Steve Jobs"),
User(name: "Stephen Wozniak"),
User(name: "Tim Cook"),
User(name: "Jonathan Ive")
]
let snapshot = DiffableDataSourceSnapshot<Section, User>()
snapshot.appendSections([.main])
snapshot.appendItems(users)
dataSource.apply(snapshot)
```
Check the documentation for more detailed API.
<H3 align="center">
<a href="https://ra1028.github.io/DiffableDataSources">[See More Usage]</a>
</H3>
---
## Requirements
- Swift 5.0+
- iOS 9.0+
- macOS 10.11+
- tvOS 9.0+
---
## Installation
### [CocoaPods](https://cocoapods.org)
Add the following to your `Podfile`:
```ruby
pod 'DiffableDataSources'
```
### [Carthage](https://github.com/Carthage/Carthage)
Add the following to your `Cartfile`:
```
github "ra1028/DiffableDataSources"
```
### [Swift Package Manager](https://swift.org/package-manager/)
Add the following to the dependencies of your `Package.swift`:
```swift
.package(url: "https://github.com/ra1028/DiffableDataSources.git", from: "x.x.x")
```
---
## Contributing
Pull requests, bug reports and feature requests are welcome 🚀
Please see the [CONTRIBUTING](https://github.com/ra1028/DiffableDataSources/blob/master/CONTRIBUTING.md) file for learn how to contribute to DiffableDataSources.
---
## Relations
#### [DifferenceKit](https://github.com/ra1028/DifferenceKit)
A fast and flexible O(n) difference algorithm framework for Swift collection.
#### [Carbon](https://github.com/ra1028/Carbon)
A declarative library for building component-based user interfaces in UITableView and UICollectionView.
---
## License
DiffableDataSources is released under the [Apache 2.0 License](https://github.com/ra1028/DiffableDataSources/blob/master/LICENSE).
@@ -0,0 +1,111 @@
#if os(macOS)
import AppKit
import DifferenceKit
/// A class for backporting `NSCollectionViewDiffableDataSource` introduced in macOS 10.15+.
/// Represents the data model object for `NSCollectionView` that can be applies the
/// changes with automatic diffing.
open class CocoaCollectionViewDiffableDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable>: NSObject, NSCollectionViewDataSource {
/// The type of closure providing the item.
public typealias ItemProvider = (NSCollectionView, IndexPath, ItemIdentifierType) -> NSCollectionViewItem?
private weak var collectionView: NSCollectionView?
private let itemProvider: ItemProvider
private let core = DiffableDataSourceCore<SectionIdentifierType, ItemIdentifierType>()
/// Creates a new data source.
///
/// - Parameters:
/// - collectionView: A collection view instance to be managed.
/// - itemProvider: A closure to make the item.
public init(collectionView: NSCollectionView, itemProvider: @escaping ItemProvider) {
self.collectionView = collectionView
self.itemProvider = itemProvider
super.init()
collectionView.dataSource = self
}
/// Applies given snapshot to perform automatic diffing update.
///
/// - Parameters:
/// - snapshot: A snapshot object to be applied to data model.
/// - animatingDifferences: A Boolean value indicating whether to update with
/// diffing animation.
public func apply(_ snapshot: DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool = true) {
core.apply(
snapshot,
view: collectionView,
animatingDifferences: animatingDifferences,
performUpdates: { collectionView, changeset, setSections in
collectionView.reload(using: changeset, setData: setSections)
})
}
/// Returns a new snapshot object of current state.
///
/// - Returns: A new snapshot object of current state.
public func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
return core.snapshot()
}
/// Returns an item identifier for given index path.
///
/// - Parameters:
/// - indexPath: An index path for the item identifier.
///
/// - Returns: An item identifier for given index path.
public func itemIdentifier(for indexPath: IndexPath) -> ItemIdentifierType? {
return core.itemIdentifier(for: indexPath)
}
/// Returns an index path for given item identifier.
///
/// - Parameters:
/// - itemIdentifier: An identifier of item.
///
/// - Returns: An index path for given item identifier.
public func indexPath(for itemIdentifier: ItemIdentifierType) -> IndexPath? {
return core.indexPath(for: itemIdentifier)
}
/// Returns the number of sections in the data source.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
///
/// - Returns: The number of sections in the data source.
public func numberOfSections(in collectionView: NSCollectionView) -> Int {
return core.numberOfSections()
}
/// Returns the number of items in the specified section.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - section: An index of section.
///
/// - Returns: The number of items in the specified section.
public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return core.numberOfItems(inSection: section)
}
/// Returns an item at specified index path.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - indexPath: An index path for item.
///
/// - Returns: An item at specified index path.
open func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let itemIdentifier = core.unsafeItemIdentifier(for: indexPath)
guard let item = itemProvider(collectionView, indexPath, itemIdentifier) else {
universalError("NSCollectionView dataSource returned a nil item at index path: \(indexPath), collectionView: \(collectionView), itemIdentifier: \(itemIdentifier)")
}
return item
}
}
#endif
+204
View File
@@ -0,0 +1,204 @@
/// A class for backporting `NSDiffableDataSourceSnapshot` introduced in iOS 13.0+, macOS 10.15+, tvOS 13.0+.
/// Represents the mutable state of diffable data source of UI.
public class DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable> {
internal let structure = SnapshotStructure<SectionIdentifierType, ItemIdentifierType>()
/// Creates a new empty snapshot object.
public init() {}
/// The number of item identifiers in the snapshot.
public var numberOfItems: Int {
return itemIdentifiers.count
}
/// The number of section identifiers in the snapshot.
public var numberOfSections: Int {
return sectionIdentifiers.count
}
/// All section identifiers in the snapshot.
public var sectionIdentifiers: [SectionIdentifierType] {
return structure.allSectionIDs
}
/// All item identifiers in the snapshot.
public var itemIdentifiers: [ItemIdentifierType] {
return structure.allItemIDs
}
/// Returns the number of item identifiers in the specified section.
///
/// - Parameters:
/// - identifier: An identifier of section.
///
/// - Returns: The number of item identifiers in the specified section.
public func numberOfItems(inSection identifier: SectionIdentifierType) -> Int {
return itemIdentifiers(inSection: identifier).count
}
/// Returns the item identifiers in the specified section.
///
/// - Parameters:
/// - identifier: An identifier of section.
///
/// - Returns: The item identifiers in the specified section.
public func itemIdentifiers(inSection identifier: SectionIdentifierType) -> [ItemIdentifierType] {
return structure.items(in: identifier)
}
/// Returns a section identifier containing the specified item.
///
/// - Parameters:
/// - identifier: An identifier of item.
///
/// - Returns: A section identifier containing the specified item.
public func sectionIdentifier(containingItem identifier: ItemIdentifierType) -> SectionIdentifierType? {
return structure.section(containing: identifier)
}
/// Returns an index of the specified item.
///
/// - Parameters:
/// - identifier: An identifier of item.
///
/// - Returns: An index of the specified item.
public func indexOfItem(_ identifier: ItemIdentifierType) -> Int? {
return itemIdentifiers.firstIndex { $0.isEqualHash(to: identifier) }
}
/// Returns an index of the specified section.
///
/// - Parameters:
/// - identifier: An identifier of section.
///
/// - Returns: An index of the specified section.
public func indexOfSection(_ identifier: SectionIdentifierType) -> Int? {
return sectionIdentifiers.firstIndex { $0.isEqualHash(to: identifier) }
}
/// Appends the given item identifiers to the specified section or last section.
///
/// - Parameters:
/// - identifiers: The item identifiers to be appended.
/// - sectionIdentifier: An identifier of section to append the given identiciers.
public func appendItems(_ identifiers: [ItemIdentifierType], toSection sectionIdentifier: SectionIdentifierType? = nil) {
structure.append(itemIDs: identifiers, to: sectionIdentifier)
}
/// Inserts the given item identifiers before the specified item.
///
/// - Parameters:
/// - identifiers: The item identifiers to be inserted.
/// - beforeIdentifier: An identifier of item.
public func insertItems(_ identifiers: [ItemIdentifierType], beforeItem beforeIdentifier: ItemIdentifierType) {
structure.insert(itemIDs: identifiers, before: beforeIdentifier)
}
/// Inserts the given item identifiers after the specified item.
///
/// - Parameters:
/// - identifiers: The item identifiers to be inserted.
/// - afterIdentifier: An identifier of item.
public func insertItems(_ identifiers: [ItemIdentifierType], afterItem afterIdentifier: ItemIdentifierType) {
structure.insert(itemIDs: identifiers, after: afterIdentifier)
}
/// Deletes the specified items.
///
/// - Parameters:
/// - identifiers: The item identifiers to be deleted.
public func deleteItems(_ identifiers: [ItemIdentifierType]) {
structure.remove(itemIDs: identifiers)
}
/// Deletes the all items in the snapshot.
public func deleteAllItems() {
structure.removeAllItems()
}
/// Moves the given item identifier before the specified item.
///
/// - Parameters:
/// - identifier: An item identifier to be moved.
/// - toIdentifier: An identifier of item.
public func moveItem(_ identifier: ItemIdentifierType, beforeItem toIdentifier: ItemIdentifierType) {
structure.move(itemID: identifier, before: toIdentifier)
}
/// Moves the given item identifier after the specified item.
///
/// - Parameters:
/// - identifier: An item identifier to be moved.
/// - toIdentifier: An identifier of item.
public func moveItem(_ identifier: ItemIdentifierType, afterItem toIdentifier: ItemIdentifierType) {
structure.move(itemID: identifier, after: toIdentifier)
}
/// Reloads the specified items.
///
/// - Parameters:
/// - identifiers: The item identifiers to be reloaded.
public func reloadItems(_ identifiers: [ItemIdentifierType]) {
structure.update(itemIDs: identifiers)
}
/// Appends the given section identifiers to the end of sections.
///
/// - Parameters:
/// - identifiers: The section identifiers to be appended.
public func appendSections(_ identifiers: [SectionIdentifierType]) {
structure.append(sectionIDs: identifiers)
}
/// Inserts the given section identifiers before the specified section.
///
/// - Parameters:
/// - identifiers: The section identifiers to be inserted.
/// - toIdentifier: An identifier of setion.
public func insertSections(_ identifiers: [SectionIdentifierType], beforeSection toIdentifier: SectionIdentifierType) {
structure.insert(sectionIDs: identifiers, before: toIdentifier)
}
/// Inserts the given section identifiers after the specified section.
///
/// - Parameters:
/// - identifiers: The section identifiers to be inserted.
/// - toIdentifier: An identifier of setion.
public func insertSections(_ identifiers: [SectionIdentifierType], afterSection toIdentifier: SectionIdentifierType) {
structure.insert(sectionIDs: identifiers, after: toIdentifier)
}
/// Deletes the specified sections.
///
/// - Parameters:
/// - identifiers: The section identifiers to be deleted.
public func deleteSections(_ identifiers: [SectionIdentifierType]) {
structure.remove(sectionIDs: identifiers)
}
/// Moves the given section identifier before the specified section.
///
/// - Parameters:
/// - identifier: A section identifier to be moved.
/// - toIdentifier: An identifier of section.
public func moveSection(_ identifier: SectionIdentifierType, beforeSection toIdentifier: SectionIdentifierType) {
structure.move(sectionID: identifier, before: toIdentifier)
}
/// Moves the given section identifier after the specified section.
///
/// - Parameters:
/// - identifier: A section identifier to be moved.
/// - toIdentifier: An identifier of section.
public func moveSection(_ identifier: SectionIdentifierType, afterSection toIdentifier: SectionIdentifierType) {
structure.move(sectionID: identifier, after: toIdentifier)
}
/// Reloads the specified sections.
///
/// - Parameters:
/// - identifiers: The section identifiers to be reloaded.
public func reloadSections(_ identifiers: [SectionIdentifierType]) {
structure.update(sectionIDs: identifiers)
}
}
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>
@@ -0,0 +1,98 @@
import Foundation
import QuartzCore
import DifferenceKit
final class DiffableDataSourceCore<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable> {
typealias Section = SnapshotStructure<SectionIdentifierType, ItemIdentifierType>.Section
private let dispatcher = MainThreadSerialDispatcher()
private var currentSnapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
private var sections: [Section] = []
func apply<View: AnyObject>(
_ snapshot: DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>,
view: View?,
animatingDifferences: Bool,
performUpdates: @escaping (View, StagedChangeset<[Section]>, @escaping ([Section]) -> Void) -> Void
) {
dispatcher.dispatch { [weak self] in
guard let self = self else {
return
}
self.currentSnapshot = snapshot
let newSections = snapshot.structure.sections
guard let view = view else {
return self.sections = newSections
}
func performDiffingUpdates() {
let changeset = StagedChangeset(source: self.sections, target: newSections)
performUpdates(view, changeset) { sections in
self.sections = sections
}
}
if animatingDifferences {
performDiffingUpdates()
}
else {
CATransaction.begin()
CATransaction.setDisableActions(true)
performDiffingUpdates()
CATransaction.commit()
}
}
}
func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
let snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
snapshot.structure.sections = currentSnapshot.structure.sections
return snapshot
}
func itemIdentifier(for indexPath: IndexPath) -> ItemIdentifierType? {
guard 0..<sections.endIndex ~= indexPath.section else {
return nil
}
let items = sections[indexPath.section].elements
guard 0..<items.endIndex ~= indexPath.item else {
return nil
}
return items[indexPath.item].differenceIdentifier
}
func unsafeItemIdentifier(for indexPath: IndexPath, file: StaticString = #file, line: UInt = #line) -> ItemIdentifierType {
guard let itemIdentifier = itemIdentifier(for: indexPath) else {
universalError("Item not found at the specified index path(\(indexPath)).")
}
return itemIdentifier
}
func indexPath(for itemIdentifier: ItemIdentifierType) -> IndexPath? {
let indexPathMap: [ItemIdentifierType: IndexPath] = sections.enumerated()
.reduce(into: [:]) { result, section in
for (itemIndex, item) in section.element.elements.enumerated() {
result[item.differenceIdentifier] = IndexPath(
item: itemIndex,
section: section.offset
)
}
}
return indexPathMap[itemIdentifier]
}
func numberOfSections() -> Int {
return sections.count
}
func numberOfItems(inSection section: Int) -> Int {
return sections[section].elements.count
}
}
+5
View File
@@ -0,0 +1,5 @@
extension Hashable {
func isEqualHash(to other: Self) -> Bool {
return hashValue == other.hashValue && self == other
}
}
@@ -0,0 +1,33 @@
import Foundation
final class MainThreadSerialDispatcher {
private let executingCount = UnsafeMutablePointer<Int32>.allocate(capacity: 1)
init() {
executingCount.initialize(to: 0)
}
deinit {
executingCount.deinitialize(count: 1)
executingCount.deallocate()
}
func dispatch(_ action: @escaping () -> Void) {
let count = OSAtomicIncrement32(executingCount)
if Thread.isMainThread && count == 1 {
action()
OSAtomicDecrement32(executingCount)
}
else {
DispatchQueue.main.async { [weak self] in
guard let self = self else {
return
}
action()
OSAtomicDecrement32(self.executingCount)
}
}
}
}
+294
View File
@@ -0,0 +1,294 @@
import Foundation
import DifferenceKit
final class SnapshotStructure<SectionID: Hashable, ItemID: Hashable> {
struct Item: Differentiable, Equatable {
var differenceIdentifier: ItemID
var isReloaded: Bool
init(id: ItemID, isReloaded: Bool) {
self.differenceIdentifier = id
self.isReloaded = isReloaded
}
init(id: ItemID) {
self.init(id: id, isReloaded: false)
}
func isContentEqual(to source: Item) -> Bool {
return !isReloaded && differenceIdentifier == source.differenceIdentifier
}
}
struct Section: DifferentiableSection, Equatable {
var differenceIdentifier: SectionID
var elements: [Item] = []
var isReloaded: Bool
init(id: SectionID, items: [Item], isReloaded: Bool) {
self.differenceIdentifier = id
self.elements = items
self.isReloaded = isReloaded
}
init(id: SectionID) {
self.init(id: id, items: [], isReloaded: false)
}
init<C: Collection>(source: Section, elements: C) where C.Element == Item {
self.init(id: source.differenceIdentifier, items: Array(elements), isReloaded: source.isReloaded)
}
func isContentEqual(to source: Section) -> Bool {
return !isReloaded && differenceIdentifier == source.differenceIdentifier
}
}
var sections: [Section] = []
var allSectionIDs: [SectionID] {
return sections.map { $0.differenceIdentifier }
}
var allItemIDs: [ItemID] {
return sections.lazy
.flatMap { $0.elements }
.map { $0.differenceIdentifier }
}
func items(in sectionID: SectionID, file: StaticString = #file, line: UInt = #line) -> [ItemID] {
guard let sectionIndex = sectionIndex(of: sectionID) else {
specifiedSectionIsNotFound(sectionID, file: file, line: line)
}
return sections[sectionIndex].elements.map { $0.differenceIdentifier }
}
func section(containing itemID: ItemID) -> SectionID? {
return itemPositionMap()[itemID]?.section.differenceIdentifier
}
func append(itemIDs: [ItemID], to sectionID: SectionID? = nil, file: StaticString = #file, line: UInt = #line) {
let index: Array<Section>.Index
if let sectionID = sectionID {
guard let sectionIndex = sectionIndex(of: sectionID) else {
specifiedSectionIsNotFound(sectionID, file: file, line: line)
}
index = sectionIndex
}
else {
guard !sections.isEmpty else {
thereAreCurrentlyNoSections(file: file, line: line)
}
index = sections.index(before: sections.endIndex)
}
let items = itemIDs.lazy.map(Item.init)
sections[index].elements.append(contentsOf: items)
}
func insert(itemIDs: [ItemID], before beforeItemID: ItemID, file: StaticString = #file, line: UInt = #line) {
guard let itemPosition = itemPositionMap()[beforeItemID] else {
specifiedItemIsNotFound(beforeItemID, file: file, line: line)
}
let items = itemIDs.lazy.map(Item.init)
sections[itemPosition.sectionIndex].elements.insert(contentsOf: items, at: itemPosition.itemRelativeIndex)
}
func insert(itemIDs: [ItemID], after afterItemID: ItemID, file: StaticString = #file, line: UInt = #line) {
guard let itemPosition = itemPositionMap()[afterItemID] else {
specifiedItemIsNotFound(afterItemID, file: file, line: line)
}
let itemIndex = sections[itemPosition.sectionIndex].elements.index(after: itemPosition.itemRelativeIndex)
let items = itemIDs.lazy.map(Item.init)
sections[itemPosition.sectionIndex].elements.insert(contentsOf: items, at: itemIndex)
}
func remove(itemIDs: [ItemID]) {
let itemPositionMap = self.itemPositionMap()
var removeIndexSetMap = [Int: IndexSet]()
for itemID in itemIDs {
guard let itemPosition = itemPositionMap[itemID] else {
continue
}
removeIndexSetMap[itemPosition.sectionIndex, default: []].insert(itemPosition.itemRelativeIndex)
}
for (sectionIndex, removeIndexSet) in removeIndexSetMap {
for range in removeIndexSet.rangeView.reversed() {
sections[sectionIndex].elements.removeSubrange(range)
}
}
}
func removeAllItems() {
for sectionIndex in sections.indices {
sections[sectionIndex].elements.removeAll()
}
}
func move(itemID: ItemID, before beforeItemID: ItemID, file: StaticString = #file, line: UInt = #line) {
guard let removed = remove(itemID: itemID) else {
specifiedItemIsNotFound(itemID, file: file, line: line)
}
guard let itemPosition = itemPositionMap()[beforeItemID] else {
specifiedItemIsNotFound(beforeItemID, file: file, line: line)
}
sections[itemPosition.sectionIndex].elements.insert(removed, at: itemPosition.itemRelativeIndex)
}
func move(itemID: ItemID, after afterItemID: ItemID, file: StaticString = #file, line: UInt = #line) {
guard let removed = remove(itemID: itemID) else {
specifiedItemIsNotFound(itemID, file: file, line: line)
}
guard let itemPosition = itemPositionMap()[afterItemID] else {
specifiedItemIsNotFound(afterItemID, file: file, line: line)
}
let itemIndex = sections[itemPosition.sectionIndex].elements.index(after: itemPosition.itemRelativeIndex)
sections[itemPosition.sectionIndex].elements.insert(removed, at: itemIndex)
}
func update(itemIDs: [ItemID], file: StaticString = #file, line: UInt = #line) {
let itemPositionMap = self.itemPositionMap()
for itemID in itemIDs {
guard let itemPosition = itemPositionMap[itemID] else {
specifiedItemIsNotFound(itemID, file: file, line: line)
}
sections[itemPosition.sectionIndex].elements[itemPosition.itemRelativeIndex].isReloaded = true
}
}
func append(sectionIDs: [SectionID]) {
let newSections = sectionIDs.lazy.map(Section.init)
sections.append(contentsOf: newSections)
}
func insert(sectionIDs: [SectionID], before beforeSectionID: SectionID, file: StaticString = #file, line: UInt = #line) {
guard let sectionIndex = sectionIndex(of: beforeSectionID) else {
specifiedSectionIsNotFound(beforeSectionID, file: file, line: line)
}
let newSections = sectionIDs.lazy.map(Section.init)
sections.insert(contentsOf: newSections, at: sectionIndex)
}
func insert(sectionIDs: [SectionID], after afterSectionID: SectionID, file: StaticString = #file, line: UInt = #line) {
guard let beforeIndex = sectionIndex(of: afterSectionID) else {
specifiedSectionIsNotFound(afterSectionID, file: file, line: line)
}
let sectionIndex = sections.index(after: beforeIndex)
let newSections = sectionIDs.lazy.map(Section.init)
sections.insert(contentsOf: newSections, at: sectionIndex)
}
func remove(sectionIDs: [SectionID]) {
for sectionID in sectionIDs {
remove(sectionID: sectionID)
}
}
func move(sectionID: SectionID, before beforeSectionID: SectionID, file: StaticString = #file, line: UInt = #line) {
guard let removed = remove(sectionID: sectionID) else {
specifiedSectionIsNotFound(sectionID, file: file, line: line)
}
guard let sectionIndex = sectionIndex(of: beforeSectionID) else {
specifiedSectionIsNotFound(beforeSectionID, file: file, line: line)
}
sections.insert(removed, at: sectionIndex)
}
func move(sectionID: SectionID, after afterSectionID: SectionID, file: StaticString = #file, line: UInt = #line) {
guard let removed = remove(sectionID: sectionID) else {
specifiedSectionIsNotFound(sectionID, file: file, line: line)
}
guard let beforeIndex = sectionIndex(of: afterSectionID) else {
specifiedSectionIsNotFound(afterSectionID, file: file, line: line)
}
let sectionIndex = sections.index(after: beforeIndex)
sections.insert(removed, at: sectionIndex)
}
func update(sectionIDs: [SectionID]) {
for sectionID in sectionIDs {
guard let sectionIndex = sectionIndex(of: sectionID) else {
continue
}
sections[sectionIndex].isReloaded = true
}
}
}
private extension SnapshotStructure {
struct ItemPosition {
var item: Item
var itemRelativeIndex: Int
var section: Section
var sectionIndex: Int
}
func sectionIndex(of sectionID: SectionID) -> Array<Section>.Index? {
return sections.firstIndex { $0.differenceIdentifier.isEqualHash(to: sectionID) }
}
@discardableResult
func remove(itemID: ItemID) -> Item? {
guard let itemPosition = itemPositionMap()[itemID] else {
return nil
}
return sections[itemPosition.sectionIndex].elements.remove(at: itemPosition.itemRelativeIndex)
}
@discardableResult
func remove(sectionID: SectionID) -> Section? {
guard let sectionIndex = sectionIndex(of: sectionID) else {
return nil
}
return sections.remove(at: sectionIndex)
}
func itemPositionMap() -> [ItemID: ItemPosition] {
return sections.enumerated().reduce(into: [:]) { result, section in
for (itemRelativeIndex, item) in section.element.elements.enumerated() {
result[item.differenceIdentifier] = ItemPosition(
item: item,
itemRelativeIndex: itemRelativeIndex,
section: section.element,
sectionIndex: section.offset
)
}
}
}
func specifiedItemIsNotFound(_ id: ItemID, file: StaticString, line: UInt) -> Never {
universalError("Specified item\(id) is not found.", file: file, line: line)
}
func specifiedSectionIsNotFound(_ id: SectionID, file: StaticString, line: UInt) -> Never {
universalError("Specified section\(id) is not found.", file: file, line: line)
}
func thereAreCurrentlyNoSections(file: StaticString, line: UInt) -> Never {
universalError("There are currently no sections.", file: file, line: line)
}
}
+3
View File
@@ -0,0 +1,3 @@
func universalError(_ message: String, file: StaticString = #file, line: UInt = #line) -> Never {
fatalError("[DiffableDataSources] \(message)", file: file, line: line)
}
@@ -0,0 +1,133 @@
#if os(iOS) || os(tvOS)
import UIKit
import DifferenceKit
/// A class for backporting `UICollectionViewDiffableDataSource` introduced in iOS 13.0+, tvOS 13.0+.
/// Represents the data model object for `UICollectionView` that can be applies the
/// changes with automatic diffing.
open class CollectionViewDiffableDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable>: NSObject, UICollectionViewDataSource {
/// The type of closure providing the cell.
public typealias CellProvider = (UICollectionView, IndexPath, ItemIdentifierType) -> UICollectionViewCell?
/// The type of closure providing the supplementary view for element of kind.
public typealias SupplementaryViewProvider = (UICollectionView, String, IndexPath) -> UICollectionReusableView?
/// A closure to dequeue the views for element of kind.
public var supplementaryViewProvider: SupplementaryViewProvider?
private weak var collectionView: UICollectionView?
private let cellProvider: CellProvider
private let core = DiffableDataSourceCore<SectionIdentifierType, ItemIdentifierType>()
/// Creates a new data source.
///
/// - Parameters:
/// - collectionView: A collection view instance to be managed.
/// - cellProvider: A closure to dequeue the cell for items.
public init(collectionView: UICollectionView, cellProvider: @escaping CellProvider) {
self.collectionView = collectionView
self.cellProvider = cellProvider
super.init()
collectionView.dataSource = self
}
/// Applies given snapshot to perform automatic diffing update.
///
/// - Parameters:
/// - snapshot: A snapshot object to be applied to data model.
/// - animatingDifferences: A Boolean value indicating whether to update with
/// diffing animation.
public func apply(_ snapshot: DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool = true) {
core.apply(
snapshot,
view: collectionView,
animatingDifferences: animatingDifferences,
performUpdates: { collectionView, changeset, setSections in
collectionView.reload(using: changeset, setData: setSections)
})
}
/// Returns a new snapshot object of current state.
///
/// - Returns: A new snapshot object of current state.
public func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
return core.snapshot()
}
/// Returns an item identifier for given index path.
///
/// - Parameters:
/// - indexPath: An index path for the item identifier.
///
/// - Returns: An item identifier for given index path.
public func itemIdentifier(for indexPath: IndexPath) -> ItemIdentifierType? {
return core.itemIdentifier(for: indexPath)
}
/// Returns an index path for given item identifier.
///
/// - Parameters:
/// - itemIdentifier: An identifier of item.
///
/// - Returns: An index path for given item identifier.
public func indexPath(for itemIdentifier: ItemIdentifierType) -> IndexPath? {
return core.indexPath(for: itemIdentifier)
}
/// Returns the number of sections in the data source.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
///
/// - Returns: The number of sections in the data source.
public func numberOfSections(in collectionView: UICollectionView) -> Int {
return core.numberOfSections()
}
/// Returns the number of items in the specified section.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - section: An index of section.
///
/// - Returns: The number of items in the specified section.
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return core.numberOfItems(inSection: section)
}
/// Returns a cell for item at specified index path.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - indexPath: An index path for cell.
///
/// - Returns: A cell for row at specified index path.
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let itemIdentifier = core.unsafeItemIdentifier(for: indexPath)
guard let cell = cellProvider(collectionView, indexPath, itemIdentifier) else {
universalError("UICollectionView dataSource returned a nil cell for item at index path: \(indexPath), collectionView: \(collectionView), itemIdentifier: \(itemIdentifier)")
}
return cell
}
/// Returns a supplementary view for element of kind at specified index path.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - kind: The kind of element to be display.
/// - indexPath: An index path for supplementary view.
///
/// - Returns: A supplementary view for element of kind at specified index path.
open func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
guard let view = supplementaryViewProvider?(collectionView, kind, indexPath) else {
return UICollectionReusableView()
}
return view
}
}
#endif
@@ -0,0 +1,114 @@
#if os(iOS) || os(tvOS)
import UIKit
import DifferenceKit
/// A class for backporting `UITableViewDiffableDataSource` introduced in iOS 13.0+, tvOS 13.0+.
/// Represents the data model object for `UITableView` that can be applies the
/// changes with automatic diffing.
open class TableViewDiffableDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable>: NSObject, UITableViewDataSource {
/// The type of closure providing the cell.
public typealias CellProvider = (UITableView, IndexPath, ItemIdentifierType) -> UITableViewCell?
/// The default animation to updating the views.
public var defaultRowAnimation: UITableView.RowAnimation = .automatic
private weak var tableView: UITableView?
private let cellProvider: CellProvider
private let core = DiffableDataSourceCore<SectionIdentifierType, ItemIdentifierType>()
/// Creates a new data source.
///
/// - Parameters:
/// - tableView: A table view instance to be managed.
/// - cellProvider: A closure to dequeue the cell for rows.
public init(tableView: UITableView, cellProvider: @escaping CellProvider) {
self.tableView = tableView
self.cellProvider = cellProvider
super.init()
tableView.dataSource = self
}
/// Applies given snapshot to perform automatic diffing update.
///
/// - Parameters:
/// - snapshot: A snapshot object to be applied to data model.
/// - animatingDifferences: A Boolean value indicating whether to update with
/// diffing animation.
public func apply(_ snapshot: DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool = true) {
core.apply(
snapshot,
view: tableView,
animatingDifferences: animatingDifferences,
performUpdates: { tableView, changeset, setSections in
tableView.reload(using: changeset, with: self.defaultRowAnimation, setData: setSections)
})
}
/// Returns a new snapshot object of current state.
///
/// - Returns: A new snapshot object of current state.
public func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
return core.snapshot()
}
/// Returns an item identifier for given index path.
///
/// - Parameters:
/// - indexPath: An index path for the item identifier.
///
/// - Returns: An item identifier for given index path.
public func itemIdentifier(for indexPath: IndexPath) -> ItemIdentifierType? {
return core.itemIdentifier(for: indexPath)
}
/// Returns an index path for given item identifier.
///
/// - Parameters:
/// - itemIdentifier: An identifier of item.
///
/// - Returns: An index path for given item identifier.
public func indexPath(for itemIdentifier: ItemIdentifierType) -> IndexPath? {
return core.indexPath(for: itemIdentifier)
}
/// Returns the number of sections in the data source.
///
/// - Parameters:
/// - tableView: A table view instance managed by `self`.
///
/// - Returns: The number of sections in the data source.
public func numberOfSections(in tableView: UITableView) -> Int {
return core.numberOfSections()
}
/// Returns the number of items in the specified section.
///
/// - Parameters:
/// - tableView: A table view instance managed by `self`.
/// - section: An index of section.
///
/// - Returns: The number of items in the specified section.
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return core.numberOfItems(inSection: section)
}
/// Returns a cell for row at specified index path.
///
/// - Parameters:
/// - tableView: A table view instance managed by `self`.
/// - indexPath: An index path for cell.
///
/// - Returns: A cell for row at specified index path.
open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let itemIdentifier = core.unsafeItemIdentifier(for: indexPath)
guard let cell = cellProvider(tableView, indexPath, itemIdentifier) else {
universalError("UITableView dataSource returned a nil cell for row at index path: \(indexPath), tableView: \(tableView), itemIdentifier: \(itemIdentifier)")
}
return cell
}
}
#endif
@@ -0,0 +1,185 @@
#if os(macOS)
import XCTest
import AppKit
@testable import DiffableDataSources
final class CocoaCollectionViewDiffableDataSourceTests: XCTestCase {
func testInit() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
XCTAssertTrue(collectionView.dataSource === dataSource)
}
func testApply() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 0)
snapshot.appendSections([0])
snapshot.appendItems([0])
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 1)
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 1)
snapshot.appendItems([1])
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 2)
}
func testSnapshot() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
let snapshot1 = dataSource.snapshot()
XCTAssertEqual(snapshot1.sectionIdentifiers, [])
XCTAssertEqual(snapshot1.itemIdentifiers, [])
dataSource.snapshot().appendSections([0, 1, 2])
let snapshot2 = dataSource.snapshot()
XCTAssertEqual(snapshot2.sectionIdentifiers, [])
XCTAssertEqual(snapshot2.itemIdentifiers, [])
let snapshotToApply = DiffableDataSourceSnapshot<Int, Int>()
snapshotToApply.appendSections([0, 1, 2])
snapshotToApply.appendItems([0, 1, 2])
dataSource.apply(snapshotToApply)
let snapshot3 = dataSource.snapshot()
XCTAssertEqual(snapshot3.sectionIdentifiers, [0, 1, 2])
XCTAssertEqual(snapshot3.itemIdentifiers, [0, 1, 2])
dataSource.snapshot().appendSections([3, 4, 5])
let snapshot4 = dataSource.snapshot()
XCTAssertEqual(snapshot4.sectionIdentifiers, [0, 1, 2])
XCTAssertEqual(snapshot4.itemIdentifiers, [0, 1, 2])
snapshot4.appendSections([3, 4, 5])
snapshot4.appendItems([3, 4, 5])
dataSource.apply(snapshot4)
let snapshot5 = dataSource.snapshot()
XCTAssertEqual(snapshot5.sectionIdentifiers, [0, 1, 2, 3, 4, 5])
XCTAssertEqual(snapshot5.itemIdentifiers, [0, 1, 2, 3, 4, 5])
}
func testItemIdentifier() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.itemIdentifier(for: IndexPath(item: 1, section: 0)), 1)
XCTAssertEqual(dataSource.itemIdentifier(for: IndexPath(item: 100, section: 100)), nil)
}
func testIndexPath() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.indexPath(for: 2), IndexPath(item: 2, section: 0))
XCTAssertEqual(dataSource.indexPath(for: 100), nil)
}
func testNumberOfSections() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
XCTAssertEqual(dataSource.numberOfSections(in: collectionView), 0)
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.numberOfSections(in: collectionView), 3)
}
func testNumberOfRowsInSection() {
let collectionView = MockCollectionView()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
NSCollectionViewItem()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.collectionView(collectionView, numberOfItemsInSection: 0), 3)
}
func testCellForRowAt() {
let collectionView = MockCollectionView()
let item = NSCollectionViewItem()
let dataSource = CocoaCollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
item
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(
dataSource.collectionView(collectionView, itemForRepresentedObjectAt: IndexPath(item: 1, section: 0)),
item
)
}
}
final class MockCollectionView: NSCollectionView {
var isPerformBatchUpdatesCalledCount = 0
init() {
super.init(frame: .zero)
let window = NSWindow()
window.contentView = self
}
@available(*, unavailable)
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func performBatchUpdates(_ updates: (() -> Void)?, completionHandler: ((Bool) -> Void)? = nil) {
isPerformBatchUpdatesCalledCount += 1
updates?()
completionHandler?(true)
}
override func insertItems(at indexPaths: Set<IndexPath>) {}
}
#endif
@@ -0,0 +1,186 @@
#if os(iOS) || os(tvOS)
import XCTest
import UIKit
@testable import DiffableDataSources
final class CollectionViewDiffableDataSourceTests: XCTestCase {
func testInit() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
XCTAssertTrue(collectionView.dataSource === dataSource)
}
func testApply() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 0)
snapshot.appendSections([0])
snapshot.appendItems([0])
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 1)
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 1)
snapshot.appendItems([1])
dataSource.apply(snapshot)
XCTAssertEqual(collectionView.isPerformBatchUpdatesCalledCount, 2)
}
func testSnapshot() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
let snapshot1 = dataSource.snapshot()
XCTAssertEqual(snapshot1.sectionIdentifiers, [])
XCTAssertEqual(snapshot1.itemIdentifiers, [])
dataSource.snapshot().appendSections([0, 1, 2])
let snapshot2 = dataSource.snapshot()
XCTAssertEqual(snapshot2.sectionIdentifiers, [])
XCTAssertEqual(snapshot2.itemIdentifiers, [])
let snapshotToApply = DiffableDataSourceSnapshot<Int, Int>()
snapshotToApply.appendSections([0, 1, 2])
snapshotToApply.appendItems([0, 1, 2])
dataSource.apply(snapshotToApply)
let snapshot3 = dataSource.snapshot()
XCTAssertEqual(snapshot3.sectionIdentifiers, [0, 1, 2])
XCTAssertEqual(snapshot3.itemIdentifiers, [0, 1, 2])
dataSource.snapshot().appendSections([3, 4, 5])
let snapshot4 = dataSource.snapshot()
XCTAssertEqual(snapshot4.sectionIdentifiers, [0, 1, 2])
XCTAssertEqual(snapshot4.itemIdentifiers, [0, 1, 2])
snapshot4.appendSections([3, 4, 5])
snapshot4.appendItems([3, 4, 5])
dataSource.apply(snapshot4)
let snapshot5 = dataSource.snapshot()
XCTAssertEqual(snapshot5.sectionIdentifiers, [0, 1, 2, 3, 4, 5])
XCTAssertEqual(snapshot5.itemIdentifiers, [0, 1, 2, 3, 4, 5])
}
func testItemIdentifier() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.itemIdentifier(for: IndexPath(item: 1, section: 0)), 1)
XCTAssertEqual(dataSource.itemIdentifier(for: IndexPath(item: 100, section: 100)), nil)
}
func testIndexPath() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.indexPath(for: 2), IndexPath(item: 2, section: 0))
XCTAssertEqual(dataSource.indexPath(for: 100), nil)
}
func testNumberOfSections() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
XCTAssertEqual(dataSource.numberOfSections(in: collectionView), 0)
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.numberOfSections(in: collectionView), 3)
}
func testNumberOfRowsInSection() {
let collectionView = MockCollectionView()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
UICollectionViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.collectionView(collectionView, numberOfItemsInSection: 0), 3)
}
func testCellForRowAt() {
let collectionView = MockCollectionView()
let cell = UICollectionViewCell()
let dataSource = CollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) { _, _, _ in
cell
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(
dataSource.collectionView(collectionView, cellForItemAt: IndexPath(item: 1, section: 0)),
cell
)
}
}
final class MockCollectionView: UICollectionView {
var isPerformBatchUpdatesCalledCount = 0
init() {
super.init(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
let window = UIWindow()
window.addSubview(self)
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil) {
isPerformBatchUpdatesCalledCount += 1
updates?()
completion?(true)
}
override func insertSections(_ sections: IndexSet) {}
override func insertItems(at indexPaths: [IndexPath]) {}
}
#endif
+895
View File
@@ -0,0 +1,895 @@
import XCTest
@testable import DiffableDataSources
// swiftlint:disable file_length
// swiftlint:disable type_body_length
final class DiffableDataSourceSnapshotTests: XCTestCase {
func testAppendSections() {
typealias Test = (initial: [Int], append: [Int], expected: [Int])
let tests: [Test] = [
([0, 1], [], [0, 1]),
([], [0, 1, 2], [0, 1, 2]),
([0, 1], [2, 3, 4], [0, 1, 2, 3, 4]),
([0, 1], [4, 3, 2], [0, 1, 4, 3, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.appendSections(test.append)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testAppendSectionsDuplication() {
typealias Test = (initial: [Int], append: [Int], expected: [Int])
let tests: [Test] = [
([0, 1], [0], [0, 1, 0]),
([0, 1], [0, 1], [0, 1, 0, 1]),
([0, 1], [2, 2], [0, 1, 2, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.appendSections(test.append)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testInsertSectionsBeforeSection() {
typealias Test = (initial: [Int], insert: [Int], before: Int, expected: [Int])
let tests: [Test] = [
([0, 1], [3, 4], 1, [0, 3, 4, 1]),
([0, 1], [3, 4], 0, [3, 4, 0, 1]),
([0, 1, 2], [3, 4], 2, [0, 1, 3, 4, 2]),
([0, 1, 2], [], 2, [0, 1, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.insertSections(test.insert, beforeSection: test.before)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testInsertSectionsBeforeSectionDuplication() {
typealias Test = (initial: [Int], insert: [Int], before: Int, expected: [Int])
let tests: [Test] = [
([0, 1], [1], 0, [1, 0, 1]),
([0, 1], [2, 2], 1, [0, 2, 2, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.insertSections(test.insert, beforeSection: test.before)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testInsertSectionsAfterSection() {
typealias Test = (initial: [Int], insert: [Int], after: Int, expected: [Int])
let tests: [Test] = [
([0, 1], [3, 4], 1, [0, 1, 3, 4]),
([0, 1], [3, 4], 0, [0, 3, 4, 1]),
([0, 1, 2], [3, 4], 2, [0, 1, 2, 3, 4]),
([0, 1, 2], [], 2, [0, 1, 2]),
([0], [1], 0, [0, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.insertSections(test.insert, afterSection: test.after)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testInsertSectionsAfterSectionDuplication() {
typealias Test = (initial: [Int], insert: [Int], after: Int, expected: [Int])
let tests: [Test] = [
([0, 1], [1], 0, [0, 1, 1]),
([0, 1], [2, 2], 1, [0, 1, 2, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.insertSections(test.insert, afterSection: test.after)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testDeleteSections() {
typealias Test = (initial: [Int], delete: [Int], expected: [Int])
let tests: [Test] = [
([0, 1], [1], [0]),
([0, 1], [0], [1]),
([0, 1, 2], [1], [0, 2]),
([0, 1], [1], [0]),
([], [1], []),
([0, 1], [100], [0, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.deleteSections(test.delete)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testMoveSectionBeforeSection() {
typealias Test = (initial: [Int], move: Int, before: Int, expected: [Int])
let tests: [Test] = [
([0, 1], 1, 0, [1, 0]),
([0, 1, 2], 2, 0, [2, 0, 1]),
([0, 1, 2], 0, 2, [1, 0, 2]),
([0, 1, 2], 1, 2, [0, 1, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.moveSection(test.move, beforeSection: test.before)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testMoveSectionAfterSection() {
typealias Test = (initial: [Int], move: Int, after: Int, expected: [Int])
let tests: [Test] = [
([0, 1], 0, 1, [1, 0]),
([0, 1, 2], 2, 0, [0, 2, 1]),
([0, 1, 2], 0, 2, [1, 2, 0]),
([0, 1, 2], 1, 0, [0, 1, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.moveSection(test.move, afterSection: test.after)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testReloadSections() {
typealias Section = SnapshotStructure<Int, Int>.Section
typealias Test = (initial: [Int], reload: [Int], sections: [Section])
let tests: [Test] = [
([], [], []),
([0], [1], [
Section(id: 0, items: [], isReloaded: false)
]
),
([0], [0], [
Section(id: 0, items: [], isReloaded: true)
]
),
([0, 1, 2], [2], [
Section(id: 0, items: [], isReloaded: false),
Section(id: 1, items: [], isReloaded: false),
Section(id: 2, items: [], isReloaded: true)
]
),
([2, 1, 0], [0, 1], [
Section(id: 2, items: [], isReloaded: false),
Section(id: 1, items: [], isReloaded: true),
Section(id: 0, items: [], isReloaded: true)
]
)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
snapshot.reloadSections(test.reload)
XCTAssertEqual(snapshot.sectionIdentifiers, test.initial)
XCTAssertEqual(snapshot.structure.sections, test.sections)
}
}
func testAppendItems() {
typealias Test = (initial: [Int], append: [Int], expected: [Int])
let tests: [Test] = [
([0, 1], [2, 3], [0, 1, 2, 3]),
([], [2, 3], [2, 3]),
([1], [0], [1, 0])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1])
snapshot.appendItems(test.initial)
snapshot.appendItems(test.append)
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expected)
}
}
func testAppendItemsDuplication() {
typealias Test = (initial: [Int], append: [Int], expected: [Int])
let tests: [Test] = [
([1], [1, 2], [1, 1, 2]),
([1], [2, 2], [1, 2, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1])
snapshot.appendItems(test.initial)
snapshot.appendItems(test.append)
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expected)
}
}
func testAppendItemsToSection() {
typealias Test = (initial: [[Int]], append: [Int], section: Int, expected: [[Int]])
let tests: [Test] = [
([[], [0, 1]], [2, 3], 1, [[], [0, 1, 2, 3]]),
([[], []], [2, 3], 1, [[], [2, 3]]),
([[], [1]], [0], 1, [[], [1, 0]]),
([[], [1]], [2], 0, [[2], [1]]),
([[], [1]], [2, 3], 0, [[2, 3], [1]]),
([[], []], [0], 0, [[0], []])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items)
}
snapshot.appendItems(test.append, toSection: test.section)
for (section, items) in test.expected.enumerated() {
XCTAssertEqual(snapshot.itemIdentifiers(inSection: section), items)
}
}
}
func testAppendItemsToSectionDuplication() {
typealias Test = (initial: [[Int]], append: [Int], section: Int, expected: [[Int]])
let tests: [Test] = [
([[], [1]], [1, 2], 1, [[], [1, 1, 2]]),
([[], [1]], [2, 2], 1, [[], [1, 2, 2]])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items)
}
snapshot.appendItems(test.append, toSection: test.section)
for (section, items) in test.expected.enumerated() {
XCTAssertEqual(snapshot.itemIdentifiers(inSection: section), items)
}
}
}
func testInsertItemsBeforeItem() {
typealias Test = (initial: [Int], insert: [Int], before: Int, expected: [Int])
let tests: [Test] = [
([0, 1], [2, 3], 1, [0, 2, 3, 1]),
([0, 1], [2, 3], 0, [2, 3, 0, 1]),
([0, 1, 2], [3, 4], 1, [0, 3, 4, 1, 2]),
([0, 1, 2], [], 1, [0, 1, 2]),
([0], [1], 0, [1, 0])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1])
snapshot.appendItems(test.initial)
snapshot.insertItems(test.insert, beforeItem: test.before)
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expected)
}
}
func testInsertItemsBeforeItemDuplication() {
typealias Test = (initial: [Int], insert: [Int], before: Int, expected: [Int])
let tests: [Test] = [
([1], [1, 2], 1, [1, 2, 1]),
([1], [2, 2], 1, [2, 2, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1])
snapshot.appendItems(test.initial)
snapshot.insertItems(test.insert, beforeItem: test.before)
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expected)
}
}
func testInsertItemsAfterItem() {
typealias Test = (initial: [Int], insert: [Int], after: Int, expected: [Int])
let tests: [Test] = [
([0, 1], [2, 3], 1, [0, 1, 2, 3]),
([0, 1], [2, 3], 0, [0, 2, 3, 1]),
([0, 1, 2], [3, 4], 1, [0, 1, 3, 4, 2]),
([0, 1, 2], [], 1, [0, 1, 2]),
([0], [1], 0, [0, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1])
snapshot.appendItems(test.initial)
snapshot.insertItems(test.insert, afterItem: test.after)
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expected)
}
}
func testInsertItemsAfterItemDuplication() {
typealias Test = (initial: [Int], insert: [Int], after: Int, expected: [Int])
let tests: [Test] = [
([1], [1, 2], 1, [1, 1, 2]),
([1], [2, 2], 1, [1, 2, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1])
snapshot.appendItems(test.initial)
snapshot.insertItems(test.insert, afterItem: test.after)
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expected)
}
}
func testDeleteItems() {
typealias Test = (initial: [[Int]], delete: [Int], expected: [[Int]])
let tests: [Test] = [
([[], [0, 1]], [0], [[], [1]]),
([[0, 1], [2, 3]], [0, 2], [[1], [3]]),
([[], []], [100], [[], []]),
([[0, 1], [2, 3]], [0, 1], [[], [2, 3]]),
([[0, 1], [2, 3]], [0], [[1], [2, 3]]),
([[0, 1], [2, 3]], [0, 1, 2, 3], [[], []]),
([[0, 1], [2, 3]], [0, 1, 2, 3, 4, 5], [[], []])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
snapshot.deleteItems(test.delete)
for (section, items) in test.expected.enumerated() {
XCTAssertEqual(snapshot.itemIdentifiers(inSection: section), items)
}
}
}
func testDeleteAllItems() {
typealias Test = [[Int]]
let tests: [Test] = [
([[], [0, 1]]),
([[0], [1]]),
([[], []]),
([[0, 1], [2, 3]]),
([[0, 1, 2], []]),
([[], [0, 1, 2]])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
snapshot.deleteAllItems()
XCTAssertEqual(snapshot.itemIdentifiers, [])
}
}
func testMoveItemsBeforeItem() {
typealias Test = (initial: [[Int]], move: Int, before: Int, expected: [[Int]])
let tests: [Test] = [
([[0, 1], [2, 3]], 0, 2, [[1], [0, 2, 3]]),
([[0, 1], [2, 3]], 1, 0, [[1, 0], [2, 3]]),
([[0, 1], [2, 3]], 3, 0, [[3, 0, 1], [2]]),
([[0, 1], [2, 3]], 2, 3, [[0, 1], [2, 3]]),
([[0], [1]], 0, 1, [[], [0, 1]]),
([[0], [1]], 1, 0, [[1, 0], []]),
([[], [0, 1]], 1, 0, [[], [1, 0]])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
snapshot.moveItem(test.move, beforeItem: test.before)
for (section, items) in test.expected.enumerated() {
XCTAssertEqual(snapshot.itemIdentifiers(inSection: section), items)
}
}
}
func testMoveItemsAfterItem() {
typealias Test = (initial: [[Int]], move: Int, after: Int, expected: [[Int]])
let tests: [Test] = [
([[0, 1], [2, 3]], 0, 2, [[1], [2, 0, 3]]),
([[0, 1], [2, 3]], 1, 0, [[0, 1], [2, 3]]),
([[0, 1], [2, 3]], 3, 0, [[0, 3, 1], [2]]),
([[0, 1], [2, 3]], 2, 3, [[0, 1], [3, 2]]),
([[0], [1]], 0, 1, [[], [1, 0]]),
([[0], [1]], 1, 0, [[0, 1], []]),
([[], [0, 1]], 1, 0, [[], [0, 1]])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
snapshot.moveItem(test.move, afterItem: test.after)
for (section, items) in test.expected.enumerated() {
XCTAssertEqual(snapshot.itemIdentifiers(inSection: section), items)
}
}
}
func testReloadItems() {
typealias Section = SnapshotStructure<Int, Int>.Section
typealias Item = SnapshotStructure<Int, Int>.Item
typealias Test = (initial: [[Int]], reload: [Int], sections: [Section])
let tests: [Test] = [
([[], []], [], [
Section(id: 0, items: [], isReloaded: false),
Section(id: 1, items: [], isReloaded: false)
]
),
([[], [0]], [0], [
Section(id: 0, items: [], isReloaded: false),
Section(
id: 1,
items: [
Item(id: 0, isReloaded: true)
],
isReloaded: false
)
]
),
([[0, 1], [2]], [1, 2], [
Section(
id: 0,
items: [
Item(id: 0, isReloaded: false),
Item(id: 1, isReloaded: true)
],
isReloaded: false
),
Section(
id: 1,
items: [
Item(id: 2, isReloaded: true)
],
isReloaded: false
)
]
),
([[0, 1], [2, 3]], [0, 2, 3], [
Section(
id: 0,
items: [
Item(id: 0, isReloaded: true),
Item(id: 1, isReloaded: false)
],
isReloaded: false
),
Section(
id: 1,
items: [
Item(id: 2, isReloaded: true),
Item(id: 3, isReloaded: true)
],
isReloaded: false
)
]
)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
snapshot.reloadItems(test.reload)
XCTAssertEqual(snapshot.itemIdentifiers, test.initial.flatMap { $0 })
XCTAssertEqual(snapshot.structure.sections, test.sections)
}
}
func testNumberOfItems() {
typealias Test = (initial: [[Int]], expected: Int)
let tests: [Test] = [
([[0, 1], [2, 3]], 4),
([[0, 1], []], 2),
([[], [2, 3]], 2),
([[], []], 0)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.numberOfItems, test.expected)
}
}
func testNumberOfItemsDuplication() {
typealias Test = (initial: [[Int]], expected: Int)
let tests: [Test] = [
([[0, 1], [1, 2]], 4),
([[0, 0], []], 2)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.numberOfItems, test.expected)
}
}
func testNumberOfSections() {
typealias Test = (initial: [Int], expected: Int)
let tests: [Test] = [
([], 0),
([0, 1, 2], 3)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
XCTAssertEqual(snapshot.numberOfSections, test.expected)
}
}
func testNumberOfSectionsDuplication() {
typealias Test = (initial: [Int], expected: Int)
let tests: [Test] = [
([0, 0], 2),
([0, 1, 1], 3)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
XCTAssertEqual(snapshot.numberOfSections, test.expected)
}
}
func testItemIdentifiers() {
typealias Test = (initial: [[Int]], expected: [Int])
let tests: [Test] = [
([[0, 1], [2, 3]], [0, 1, 2, 3]),
([[0, 1], []], [0, 1]),
([[], [2, 3]], [2, 3]),
([[], []], [])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.itemIdentifiers, test.expected)
}
}
func testItemIdentifiersDuplication() {
typealias Test = (initial: [[Int]], expected: [Int])
let tests: [Test] = [
([[0, 1], [1, 2]], [0, 1, 1, 2]),
([[0, 0], [1, 2]], [0, 0, 1, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.itemIdentifiers, test.expected)
}
}
func testSectionIdentifiers() {
typealias Test = (initial: [Int], expected: [Int])
let tests: [Test] = [
([], []),
([0, 1], [0, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testSectionIdentifiersDuplication() {
typealias Test = (initial: [Int], expected: [Int])
let tests: [Test] = [
([0, 0], [0, 0]),
([0, 1, 1], [0, 1, 1])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
XCTAssertEqual(snapshot.sectionIdentifiers, test.expected)
}
}
func testNumberOfItemsInSection() {
typealias Test = (initial: [[Int]], expectedInRight: Int)
let tests: [Test] = [
([[0, 1], [2, 3]], 2),
([[0, 1], []], 0),
([[], [2, 3]], 2),
([[], []], 0)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.numberOfItems(inSection: 1), test.expectedInRight)
}
}
func testNumberOfItemsInSectionDuplication() {
typealias Test = (initial: [[Int]], expectedInRight: Int)
let tests: [Test] = [
([[0], [1, 1]], 2),
([[0, 1], [1, 2]], 2)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.numberOfItems(inSection: 1), test.expectedInRight)
}
}
func testItemIdentifiersInSection() {
typealias Test = (initial: [[Int]], expectedInRight: [Int])
let tests: [Test] = [
([[0, 1], [2, 3]], [2, 3]),
([[0, 1], []], []),
([[], [2, 3]], [2, 3]),
([[], []], [])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expectedInRight)
}
}
func testItemIdentifiersInSectionDuplication() {
typealias Test = (initial: [[Int]], expectedInRight: [Int])
let tests: [Test] = [
([[0, 1], [1, 2]], [1, 2]),
([[0, 1], [2, 2]], [2, 2])
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.itemIdentifiers(inSection: 1), test.expectedInRight)
}
}
func testSectionIdentifiersContainingItem() {
typealias Test = (initial: [[Int]], item: Int, expected: Int?)
let tests: [Test] = [
([[0, 1], [2, 3]], 2, 1),
([[0, 1], []], 0, 0),
([[], [2, 3]], 2, 1),
([[], []], 0, nil),
([[0], [1]], 2, nil)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.sectionIdentifier(containingItem: test.item), test.expected)
}
}
func testSectionIdentifiersContainingDulication() {
typealias Test = (initial: [[Int]], item: Int, expected: Int?)
let tests: [Test] = [
([[0, 1], [1, 2]], 2, 1),
([[0, 1], [1, 2]], 1, 1)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.sectionIdentifier(containingItem: test.item), test.expected)
}
}
func testIndexOfItem() {
typealias Test = (initial: [[Int]], item: Int, expectedIndex: Int?)
let tests: [Test] = [
([[0, 1], [2, 3]], 2, 2),
([[0, 1], []], 0, 0),
([[], [2, 3]], 2, 0),
([[], []], 0, nil),
([[0], [1]], 2, nil)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.indexOfItem(test.item), test.expectedIndex)
}
}
func testIndexOfItemDuplication() {
typealias Test = (initial: [[Int]], item: Int, expectedIndex: Int?)
let tests: [Test] = [
([[0, 1], [1, 2]], 2, 3),
([[0, 1], [1, 2]], 1, 1)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
for (section, items) in test.initial.enumerated() {
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)
}
XCTAssertEqual(snapshot.indexOfItem(test.item), test.expectedIndex)
}
}
func testIndexOfSection() {
typealias Test = (initial: [Int], section: Int, expectedIndex: Int?)
let tests: [Test] = [
([0, 1, 2], 1, 1),
([0, 1, 2], 2, 2),
([0, 1, 2], 3, nil),
([], 0, nil)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
XCTAssertEqual(snapshot.indexOfSection(test.section), test.expectedIndex)
}
}
func testIndexOfSectionDuplication() {
typealias Test = (initial: [Int], section: Int, expectedIndex: Int?)
let tests: [Test] = [
([0, 1, 1, 2], 1, 1),
([0, 1, 1, 2], 2, 3)
]
for test in tests {
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections(test.initial)
XCTAssertEqual(snapshot.indexOfSection(test.section), test.expectedIndex)
}
}
}
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
@@ -0,0 +1,58 @@
import XCTest
@testable import DiffableDataSources
final class MainThreadSerialDispatcherTests: XCTestCase {
func testMainThread() {
let dispatcher = MainThreadSerialDispatcher()
let queue = DispatchQueue.global()
let expectation = self.expectation(description: "testMainThread")
queue.async {
dispatcher.dispatch {
XCTAssertTrue(Thread.isMainThread)
expectation.fulfill()
}
}
waitForExpectations(timeout: 1)
}
func testMainThreadSerial() {
let dispatcher = MainThreadSerialDispatcher()
let queue = DispatchQueue.global()
let expectation = self.expectation(description: "testMainThreadSerial")
var array = [Int]()
let group = DispatchGroup()
queue.async(group: group) {
dispatcher.dispatch {
array.append(0)
}
}
group.wait()
queue.async(group: group) {
dispatcher.dispatch {
array.append(1)
}
dispatcher.dispatch {
array.append(2)
}
}
group.wait()
dispatcher.dispatch {
array.append(3)
expectation.fulfill()
}
waitForExpectations(timeout: 1) { _ in
XCTAssertEqual(array, [0, 1, 2, 3])
}
}
}
@@ -0,0 +1,186 @@
#if os(iOS) || os(tvOS)
import XCTest
import UIKit
@testable import DiffableDataSources
final class TableViewDiffableDataSourceTests: XCTestCase {
func testInit() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
XCTAssertTrue(tableView.dataSource === dataSource)
}
func testApply() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
dataSource.apply(snapshot)
XCTAssertEqual(tableView.isPerformBatchUpdatesCalledCount, 0)
snapshot.appendSections([0])
snapshot.appendItems([0])
dataSource.apply(snapshot)
XCTAssertEqual(tableView.isPerformBatchUpdatesCalledCount, 1)
dataSource.apply(snapshot)
XCTAssertEqual(tableView.isPerformBatchUpdatesCalledCount, 1)
snapshot.appendItems([1])
dataSource.apply(snapshot)
XCTAssertEqual(tableView.isPerformBatchUpdatesCalledCount, 2)
}
func testSnapshot() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
let snapshot1 = dataSource.snapshot()
XCTAssertEqual(snapshot1.sectionIdentifiers, [])
XCTAssertEqual(snapshot1.itemIdentifiers, [])
dataSource.snapshot().appendSections([0, 1, 2])
let snapshot2 = dataSource.snapshot()
XCTAssertEqual(snapshot2.sectionIdentifiers, [])
XCTAssertEqual(snapshot2.itemIdentifiers, [])
let snapshotToApply = DiffableDataSourceSnapshot<Int, Int>()
snapshotToApply.appendSections([0, 1, 2])
snapshotToApply.appendItems([0, 1, 2])
dataSource.apply(snapshotToApply)
let snapshot3 = dataSource.snapshot()
XCTAssertEqual(snapshot3.sectionIdentifiers, [0, 1, 2])
XCTAssertEqual(snapshot3.itemIdentifiers, [0, 1, 2])
dataSource.snapshot().appendSections([3, 4, 5])
let snapshot4 = dataSource.snapshot()
XCTAssertEqual(snapshot4.sectionIdentifiers, [0, 1, 2])
XCTAssertEqual(snapshot4.itemIdentifiers, [0, 1, 2])
snapshot4.appendSections([3, 4, 5])
snapshot4.appendItems([3, 4, 5])
dataSource.apply(snapshot4)
let snapshot5 = dataSource.snapshot()
XCTAssertEqual(snapshot5.sectionIdentifiers, [0, 1, 2, 3, 4, 5])
XCTAssertEqual(snapshot5.itemIdentifiers, [0, 1, 2, 3, 4, 5])
}
func testItemIdentifier() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.itemIdentifier(for: IndexPath(item: 1, section: 0)), 1)
XCTAssertEqual(dataSource.itemIdentifier(for: IndexPath(item: 100, section: 100)), nil)
}
func testIndexPath() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.indexPath(for: 2), IndexPath(item: 2, section: 0))
XCTAssertEqual(dataSource.indexPath(for: 100), nil)
}
func testNumberOfSections() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
XCTAssertEqual(dataSource.numberOfSections(in: tableView), 0)
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.numberOfSections(in: tableView), 3)
}
func testNumberOfRowsInSection() {
let tableView = MockTableView()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
UITableViewCell()
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(dataSource.tableView(tableView, numberOfRowsInSection: 0), 3)
}
func testCellForRowAt() {
let tableView = MockTableView()
let cell = UITableViewCell()
let dataSource = TableViewDiffableDataSource<Int, Int>(tableView: tableView) { _, _, _ in
cell
}
let snapshot = DiffableDataSourceSnapshot<Int, Int>()
snapshot.appendSections([0, 1, 2])
snapshot.appendItems([0, 1, 2], toSection: 0)
dataSource.apply(snapshot)
XCTAssertEqual(
dataSource.tableView(tableView, cellForRowAt: IndexPath(item: 1, section: 0)),
cell
)
}
}
final class MockTableView: UITableView {
var isPerformBatchUpdatesCalledCount = 0
init() {
super.init(frame: .zero, style: .plain)
let window = UIWindow()
window.addSubview(self)
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil) {
isPerformBatchUpdatesCalledCount += 1
updates?()
completion?(true)
}
override func insertSections(_ sections: IndexSet, with animation: RowAnimation) {}
override func insertRows(at indexPaths: [IndexPath], with animation: RowAnimation) {}
}
#endif
+22
View File
@@ -0,0 +1,22 @@
MACOSX_DEPLOYMENT_TARGET = 10.11
IPHONEOS_DEPLOYMENT_TARGET = 9.0
TVOS_DEPLOYMENT_TARGET = 9.0
SDKROOT =
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator
TARGETED_DEVICE_FAMILY = 1,2,3
VALID_ARCHS[sdk=macosx*] = i386 x86_64
VALID_ARCHS[sdk=iphoneos*] = arm64 armv7 armv7s
VALID_ARCHS[sdk=iphonesimulator*] = i386 x86_64
VALID_ARCHS[sdk=appletv*] = arm64
VALID_ARCHS[sdk=appletvsimulator*] = x86_64
CODE_SIGN_IDENTITY =
CODE_SIGN_STYLE = Manual
INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks
SKIP_INSTALL = YES
DYLIB_COMPATIBILITY_VERSION = 1
DYLIB_CURRENT_VERSION = 1
DYLIB_INSTALL_NAME_BASE = @rpath
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks
DEFINES_MODULE = NO
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

+41
View File
@@ -0,0 +1,41 @@
trigger:
- master
jobs:
- job: macOS
pool:
vmImage: 'macOS 10.14'
strategy:
maxParallel: 10
matrix:
xcode10_2:
DEVELOPER_DIR: /Applications/Xcode_10.2.app
steps:
- checkout: self
submodules: true
- script: xcodebuild -version
displayName: xcodebuild -version
condition: succeededOrFailed()
- script: |
set -o pipefail &&
xcodebuild build-for-testing test-without-building -workspace DiffableDataSources.xcworkspace -scheme DiffableDataSources -configuration Release ENABLE_TESTABILITY=YES |
xcpretty -c -r junit -o build/reports/xcodebuild-macOS.xml
displayName: xcodebuild test maxOS
condition: succeededOrFailed()
- script: |
set -o pipefail &&
xcodebuild build-for-testing test-without-building -workspace DiffableDataSources.xcworkspace -scheme DiffableDataSources -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone Xs' ENABLE_TESTABILITY=YES |
xcpretty -c -r junit -o build/reports/xcodebuild-iOS.xml
displayName: xcodebuild test iOS
condition: succeededOrFailed()
- script: |
set -o pipefail &&
xcodebuild build-for-testing test-without-building -workspace DiffableDataSources.xcworkspace -scheme DiffableDataSources -configuration Release -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' ENABLE_TESTABILITY=YES |
xcpretty -c -r junit -o build/reports/xcodebuild-tvOS.xml
displayName: xcodebuild test tvOS
condition: succeededOrFailed()
- task: PublishTestResults@2
inputs:
testRunner: JUnit
testResultsFiles: build/reports/**
condition: succeededOrFailed()
@@ -0,0 +1,686 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>CollectionViewDiffableDataSource Class Reference</title>
<link rel="stylesheet" type="text/css" href="../css/jazzy.css" />
<link rel="stylesheet" type="text/css" href="../css/highlight.css" />
<meta charset="utf-8">
<script src="../js/jquery.min.js" defer></script>
<script src="../js/jazzy.js" defer></script>
<script src="../js/lunr.min.js" defer></script>
<script src="../js/typeahead.jquery.js" defer></script>
<script src="../js/jazzy.search.js" defer></script>
</head>
<body>
<a name="//apple_ref/swift/Class/CollectionViewDiffableDataSource" class="dashAnchor"></a>
<a title="CollectionViewDiffableDataSource Class Reference"></a>
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
DiffableDataSources Docs
</a>
(100% documented)
</p>
<p class="header-col--secondary">
<form role="search" action="../search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
</form>
</p>
<p class="header-col header-col--secondary">
<a class="header-link" href="https://github.com/ra1028/DiffableDataSources">
<img class="header-icon" src="../img/gh.png"/>
View on GitHub
</a>
</p>
</header>
<p class="breadcrumbs">
<a class="breadcrumb" href="../index.html">DiffableDataSources Reference</a>
<img class="carat" src="../img/carat.png" />
CollectionViewDiffableDataSource Class Reference
</p>
<div class="content-wrapper">
<nav class="navigation">
<ul class="nav-groups">
<li class="nav-group-name">
<a class="nav-group-name-link" href="../DataSources.html">DataSources</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="../Classes/TableViewDiffableDataSource.html">TableViewDiffableDataSource</a>
</li>
<li class="nav-group-task">
<a class="nav-group-task-link" href="../Classes/CollectionViewDiffableDataSource.html">CollectionViewDiffableDataSource</a>
</li>
</ul>
</li>
<li class="nav-group-name">
<a class="nav-group-name-link" href="../Snapshot.html">Snapshot</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="../Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a>
</li>
</ul>
</li>
</ul>
</nav>
<article class="main-content">
<section class="section">
<div class="section-content">
<h1>CollectionViewDiffableDataSource</h1>
<div class="declaration">
<div class="language">
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">class</span> <span class="kt">CollectionViewDiffableDataSource</span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span> <span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UICollectionViewDataSource</span> <span class="k">where</span> <span class="kt">SectionIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span></code></pre>
</div>
</div>
<p>A class for backporting <code>UICollectionViewDiffableDataSource</code> introduced in iOS 13.0+, tvOS 13.0+.
Represents the data model object for <code>UICollectionView</code> that can be applies the
changes with automatic diffing.</p>
</div>
</section>
<section class="section">
<div class="section-content">
<div class="task-group">
<ul class="item-container">
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC12CellProvidera"></a>
<a name="//apple_ref/swift/Alias/CellProvider" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC12CellProvidera">CellProvider</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>The type of closure providing the cell.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">typealias</span> <span class="kt">CellProvider</span> <span class="o">=</span> <span class="p">(</span><span class="kt">UICollectionView</span><span class="p">,</span> <span class="kt">IndexPath</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UICollectionViewCell</span><span class="p">?</span></code></pre>
</div>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC013SupplementaryE8Providera"></a>
<a name="//apple_ref/swift/Alias/SupplementaryViewProvider" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC013SupplementaryE8Providera">SupplementaryViewProvider</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>The type of closure providing the supplementary view for element of kind.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">typealias</span> <span class="kt">SupplementaryViewProvider</span> <span class="o">=</span> <span class="p">(</span><span class="kt">UICollectionView</span><span class="p">,</span> <span class="kt">String</span><span class="p">,</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UICollectionReusableView</span><span class="p">?</span></code></pre>
</div>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC013supplementaryE8ProviderSo020UICollectionReusableE0CSgSo0iE0C_SS10Foundation9IndexPathVtcSgvp"></a>
<a name="//apple_ref/swift/Property/supplementaryViewProvider" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC013supplementaryE8ProviderSo020UICollectionReusableE0CSgSo0iE0C_SS10Foundation9IndexPathVtcSgvp">supplementaryViewProvider</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>A closure to dequeue the views for element of kind.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="k">var</span> <span class="nv">supplementaryViewProvider</span><span class="p">:</span> <span class="kt">CollectionViewDiffableDataSource</span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;.</span><span class="kt"><a href="../Classes/CollectionViewDiffableDataSource.html#/s:19DiffableDataSources014CollectionViewaB6SourceC013SupplementaryE8Providera">SupplementaryViewProvider</a></span><span class="p">?</span></code></pre>
</div>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE012cellProviderACyxq_GSo012UICollectionE0C_So0jE4CellCSgAH_10Foundation9IndexPathVq_tctcfc"></a>
<a name="//apple_ref/swift/Method/init(collectionView:cellProvider:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE012cellProviderACyxq_GSo012UICollectionE0C_So0jE4CellCSgAH_10Foundation9IndexPathVq_tctcfc">init(collectionView:cellProvider:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Creates a new data source.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">collectionView</span><span class="p">:</span> <span class="kt">UICollectionView</span><span class="p">,</span> <span class="nv">cellProvider</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="kt"><a href="../Classes/CollectionViewDiffableDataSource.html#/s:19DiffableDataSources014CollectionViewaB6SourceC12CellProvidera">CellProvider</a></span><span class="p">)</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>collectionView</em>
</code>
</td>
<td>
<div>
<p>A collection view instance to be managed.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>cellProvider</em>
</code>
</td>
<td>
<div>
<p>A closure to dequeue the cell for items.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC5apply_20animatingDifferencesyAA0abF8SnapshotCyxq_G_SbtF"></a>
<a name="//apple_ref/swift/Method/apply(_:animatingDifferences:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC5apply_20animatingDifferencesyAA0abF8SnapshotCyxq_G_SbtF">apply(_:animatingDifferences:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Applies given snapshot to perform automatic diffing update.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">apply</span><span class="p">(</span><span class="n">_</span> <span class="nv">snapshot</span><span class="p">:</span> <span class="kt"><a href="../Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a></span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">animatingDifferences</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">true</span><span class="p">)</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>snapshot</em>
</code>
</td>
<td>
<div>
<p>A snapshot object to be applied to data model.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>animatingDifferences</em>
</code>
</td>
<td>
<div>
<p>A Boolean value indicating whether to update with
diffing animation.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC8snapshotAA0abF8SnapshotCyxq_GyF"></a>
<a name="//apple_ref/swift/Method/snapshot()" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC8snapshotAA0abF8SnapshotCyxq_GyF">snapshot()</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns a new snapshot object of current state.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">snapshot</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt"><a href="../Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a></span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span></code></pre>
</div>
</div>
<div>
<h4>Return Value</h4>
<p>A new snapshot object of current state.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC14itemIdentifier3forq_Sg10Foundation9IndexPathV_tF"></a>
<a name="//apple_ref/swift/Method/itemIdentifier(for:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC14itemIdentifier3forq_Sg10Foundation9IndexPathV_tF">itemIdentifier(for:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns an item identifier for given index path.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">itemIdentifier</span><span class="p">(</span><span class="k">for</span> <span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">ItemIdentifierType</span><span class="p">?</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>indexPath</em>
</code>
</td>
<td>
<div>
<p>An index path for the item identifier.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>An item identifier for given index path.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC9indexPath3for10Foundation05IndexH0VSgq__tF"></a>
<a name="//apple_ref/swift/Method/indexPath(for:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC9indexPath3for10Foundation05IndexH0VSgq__tF">indexPath(for:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns an index path for given item identifier.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">indexPath</span><span class="p">(</span><span class="k">for</span> <span class="nv">itemIdentifier</span><span class="p">:</span> <span class="kt">ItemIdentifierType</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">IndexPath</span><span class="p">?</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>itemIdentifier</em>
</code>
</td>
<td>
<div>
<p>An identifier of item.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>An index path for given item identifier.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC16numberOfSections2inSiSo012UICollectionE0C_tF"></a>
<a name="//apple_ref/swift/Method/numberOfSections(in:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC16numberOfSections2inSiSo012UICollectionE0C_tF">numberOfSections(in:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns the number of sections in the data source.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">numberOfSections</span><span class="p">(</span><span class="k">in</span> <span class="nv">collectionView</span><span class="p">:</span> <span class="kt">UICollectionView</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>collectionView</em>
</code>
</td>
<td>
<div>
<p>A collection view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>The number of sections in the data source.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE0_22numberOfItemsInSectionSiSo012UICollectionE0C_SitF"></a>
<a name="//apple_ref/swift/Method/collectionView(_:numberOfItemsInSection:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE0_22numberOfItemsInSectionSiSo012UICollectionE0C_SitF">collectionView(_:numberOfItemsInSection:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns the number of items in the specified section.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">collectionView</span><span class="p">(</span><span class="n">_</span> <span class="nv">collectionView</span><span class="p">:</span> <span class="kt">UICollectionView</span><span class="p">,</span> <span class="n">numberOfItemsInSection</span> <span class="nv">section</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>collectionView</em>
</code>
</td>
<td>
<div>
<p>A collection view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>section</em>
</code>
</td>
<td>
<div>
<p>An index of section.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>The number of items in the specified section.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE0_13cellForItemAtSo012UICollectionE4CellCSo0lE0C_10Foundation9IndexPathVtF"></a>
<a name="//apple_ref/swift/Method/collectionView(_:cellForItemAt:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE0_13cellForItemAtSo012UICollectionE4CellCSo0lE0C_10Foundation9IndexPathVtF">collectionView(_:cellForItemAt:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns a cell for item at specified index path.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">func</span> <span class="nf">collectionView</span><span class="p">(</span><span class="n">_</span> <span class="nv">collectionView</span><span class="p">:</span> <span class="kt">UICollectionView</span><span class="p">,</span> <span class="n">cellForItemAt</span> <span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UICollectionViewCell</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>collectionView</em>
</code>
</td>
<td>
<div>
<p>A collection view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>indexPath</em>
</code>
</td>
<td>
<div>
<p>An index path for cell.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>A cell for row at specified index path.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE0_33viewForSupplementaryElementOfKind2atSo020UICollectionReusableE0CSo0oE0C_SS10Foundation9IndexPathVtF"></a>
<a name="//apple_ref/swift/Method/collectionView(_:viewForSupplementaryElementOfKind:at:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC010collectionE0_33viewForSupplementaryElementOfKind2atSo020UICollectionReusableE0CSo0oE0C_SS10Foundation9IndexPathVtF">collectionView(_:viewForSupplementaryElementOfKind:at:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns a supplementary view for element of kind at specified index path.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">func</span> <span class="nf">collectionView</span><span class="p">(</span><span class="n">_</span> <span class="nv">collectionView</span><span class="p">:</span> <span class="kt">UICollectionView</span><span class="p">,</span> <span class="n">viewForSupplementaryElementOfKind</span> <span class="nv">kind</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="n">at</span> <span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UICollectionReusableView</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>collectionView</em>
</code>
</td>
<td>
<div>
<p>A collection view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>kind</em>
</code>
</td>
<td>
<div>
<p>The kind of element to be display.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>indexPath</em>
</code>
</td>
<td>
<div>
<p>An index path for supplementary view.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>A supplementary view for element of kind at specified index path.</p>
</div>
</section>
</div>
</li>
</ul>
</div>
</div>
</section>
</article>
</div>
<section class="footer">
<p>&copy; 2019 <a class="link" href="https://github.com/ra1028" target="_blank" rel="external">Ryo Aoyama</a>. All rights reserved. (Last updated: 2019-06-24)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.9.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external">Realm</a> project.</p>
</section>
</body>
</div>
</html>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,585 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>TableViewDiffableDataSource Class Reference</title>
<link rel="stylesheet" type="text/css" href="../css/jazzy.css" />
<link rel="stylesheet" type="text/css" href="../css/highlight.css" />
<meta charset="utf-8">
<script src="../js/jquery.min.js" defer></script>
<script src="../js/jazzy.js" defer></script>
<script src="../js/lunr.min.js" defer></script>
<script src="../js/typeahead.jquery.js" defer></script>
<script src="../js/jazzy.search.js" defer></script>
</head>
<body>
<a name="//apple_ref/swift/Class/TableViewDiffableDataSource" class="dashAnchor"></a>
<a title="TableViewDiffableDataSource Class Reference"></a>
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
DiffableDataSources Docs
</a>
(100% documented)
</p>
<p class="header-col--secondary">
<form role="search" action="../search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
</form>
</p>
<p class="header-col header-col--secondary">
<a class="header-link" href="https://github.com/ra1028/DiffableDataSources">
<img class="header-icon" src="../img/gh.png"/>
View on GitHub
</a>
</p>
</header>
<p class="breadcrumbs">
<a class="breadcrumb" href="../index.html">DiffableDataSources Reference</a>
<img class="carat" src="../img/carat.png" />
TableViewDiffableDataSource Class Reference
</p>
<div class="content-wrapper">
<nav class="navigation">
<ul class="nav-groups">
<li class="nav-group-name">
<a class="nav-group-name-link" href="../DataSources.html">DataSources</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="../Classes/TableViewDiffableDataSource.html">TableViewDiffableDataSource</a>
</li>
<li class="nav-group-task">
<a class="nav-group-task-link" href="../Classes/CollectionViewDiffableDataSource.html">CollectionViewDiffableDataSource</a>
</li>
</ul>
</li>
<li class="nav-group-name">
<a class="nav-group-name-link" href="../Snapshot.html">Snapshot</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="../Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a>
</li>
</ul>
</li>
</ul>
</nav>
<article class="main-content">
<section class="section">
<div class="section-content">
<h1>TableViewDiffableDataSource</h1>
<div class="declaration">
<div class="language">
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">class</span> <span class="kt">TableViewDiffableDataSource</span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span> <span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UITableViewDataSource</span> <span class="k">where</span> <span class="kt">SectionIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span></code></pre>
</div>
</div>
<p>A class for backporting <code>UITableViewDiffableDataSource</code> introduced in iOS 13.0+, tvOS 13.0+.
Represents the data model object for <code>UITableView</code> that can be applies the
changes with automatic diffing.</p>
</div>
</section>
<section class="section">
<div class="section-content">
<div class="task-group">
<ul class="item-container">
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC12CellProvidera"></a>
<a name="//apple_ref/swift/Alias/CellProvider" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC12CellProvidera">CellProvider</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>The type of closure providing the cell.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">typealias</span> <span class="kt">CellProvider</span> <span class="o">=</span> <span class="p">(</span><span class="kt">UITableView</span><span class="p">,</span> <span class="kt">IndexPath</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UITableViewCell</span><span class="p">?</span></code></pre>
</div>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC19defaultRowAnimationSo07UITableehI0Vvp"></a>
<a name="//apple_ref/swift/Property/defaultRowAnimation" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC19defaultRowAnimationSo07UITableehI0Vvp">defaultRowAnimation</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>The default animation to updating the views.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="k">var</span> <span class="nv">defaultRowAnimation</span><span class="p">:</span> <span class="kt">UITableView</span><span class="o">.</span><span class="kt">RowAnimation</span></code></pre>
</div>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC05tableE012cellProviderACyxq_GSo07UITableE0C_So0jE4CellCSgAH_10Foundation9IndexPathVq_tctcfc"></a>
<a name="//apple_ref/swift/Method/init(tableView:cellProvider:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC05tableE012cellProviderACyxq_GSo07UITableE0C_So0jE4CellCSgAH_10Foundation9IndexPathVq_tctcfc">init(tableView:cellProvider:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Creates a new data source.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">,</span> <span class="nv">cellProvider</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="kt"><a href="../Classes/TableViewDiffableDataSource.html#/s:19DiffableDataSources09TableViewaB6SourceC12CellProvidera">CellProvider</a></span><span class="p">)</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>tableView</em>
</code>
</td>
<td>
<div>
<p>A table view instance to be managed.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>cellProvider</em>
</code>
</td>
<td>
<div>
<p>A closure to dequeue the cell for rows.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC5apply_20animatingDifferencesyAA0abF8SnapshotCyxq_G_SbtF"></a>
<a name="//apple_ref/swift/Method/apply(_:animatingDifferences:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC5apply_20animatingDifferencesyAA0abF8SnapshotCyxq_G_SbtF">apply(_:animatingDifferences:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Applies given snapshot to perform automatic diffing update.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">apply</span><span class="p">(</span><span class="n">_</span> <span class="nv">snapshot</span><span class="p">:</span> <span class="kt"><a href="../Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a></span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">animatingDifferences</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">true</span><span class="p">)</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>snapshot</em>
</code>
</td>
<td>
<div>
<p>A snapshot object to be applied to data model.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>animatingDifferences</em>
</code>
</td>
<td>
<div>
<p>A Boolean value indicating whether to update with
diffing animation.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC8snapshotAA0abF8SnapshotCyxq_GyF"></a>
<a name="//apple_ref/swift/Method/snapshot()" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC8snapshotAA0abF8SnapshotCyxq_GyF">snapshot()</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns a new snapshot object of current state.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">snapshot</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt"><a href="../Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a></span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span></code></pre>
</div>
</div>
<div>
<h4>Return Value</h4>
<p>A new snapshot object of current state.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC14itemIdentifier3forq_Sg10Foundation9IndexPathV_tF"></a>
<a name="//apple_ref/swift/Method/itemIdentifier(for:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC14itemIdentifier3forq_Sg10Foundation9IndexPathV_tF">itemIdentifier(for:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns an item identifier for given index path.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">itemIdentifier</span><span class="p">(</span><span class="k">for</span> <span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">ItemIdentifierType</span><span class="p">?</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>indexPath</em>
</code>
</td>
<td>
<div>
<p>An index path for the item identifier.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>An item identifier for given index path.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC9indexPath3for10Foundation05IndexH0VSgq__tF"></a>
<a name="//apple_ref/swift/Method/indexPath(for:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC9indexPath3for10Foundation05IndexH0VSgq__tF">indexPath(for:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns an index path for given item identifier.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">indexPath</span><span class="p">(</span><span class="k">for</span> <span class="nv">itemIdentifier</span><span class="p">:</span> <span class="kt">ItemIdentifierType</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">IndexPath</span><span class="p">?</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>itemIdentifier</em>
</code>
</td>
<td>
<div>
<p>An identifier of item.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>An index path for given item identifier.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC16numberOfSections2inSiSo07UITableE0C_tF"></a>
<a name="//apple_ref/swift/Method/numberOfSections(in:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC16numberOfSections2inSiSo07UITableE0C_tF">numberOfSections(in:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns the number of sections in the data source.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">numberOfSections</span><span class="p">(</span><span class="k">in</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>tableView</em>
</code>
</td>
<td>
<div>
<p>A table view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>The number of sections in the data source.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC05tableE0_21numberOfRowsInSectionSiSo07UITableE0C_SitF"></a>
<a name="//apple_ref/swift/Method/tableView(_:numberOfRowsInSection:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC05tableE0_21numberOfRowsInSectionSiSo07UITableE0C_SitF">tableView(_:numberOfRowsInSection:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns the number of items in the specified section.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="n">_</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">,</span> <span class="n">numberOfRowsInSection</span> <span class="nv">section</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>tableView</em>
</code>
</td>
<td>
<div>
<p>A table view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>section</em>
</code>
</td>
<td>
<div>
<p>An index of section.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>The number of items in the specified section.</p>
</div>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC05tableE0_12cellForRowAtSo07UITableE4CellCSo0lE0C_10Foundation9IndexPathVtF"></a>
<a name="//apple_ref/swift/Method/tableView(_:cellForRowAt:)" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC05tableE0_12cellForRowAtSo07UITableE4CellCSo0lE0C_10Foundation9IndexPathVtF">tableView(_:cellForRowAt:)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>Returns a cell for row at specified index path.</p>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="n">_</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">,</span> <span class="n">cellForRowAt</span> <span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UITableViewCell</span></code></pre>
</div>
</div>
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
<tr>
<td>
<code>
<em>tableView</em>
</code>
</td>
<td>
<div>
<p>A table view instance managed by <code>self</code>.</p>
</div>
</td>
</tr>
<tr>
<td>
<code>
<em>indexPath</em>
</code>
</td>
<td>
<div>
<p>An index path for cell.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h4>Return Value</h4>
<p>A cell for row at specified index path.</p>
</div>
</section>
</div>
</li>
</ul>
</div>
</div>
</section>
</article>
</div>
<section class="footer">
<p>&copy; 2019 <a class="link" href="https://github.com/ra1028" target="_blank" rel="external">Ryo Aoyama</a>. All rights reserved. (Last updated: 2019-06-24)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.9.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external">Realm</a> project.</p>
</section>
</body>
</div>
</html>
+164
View File
@@ -0,0 +1,164 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>DataSources Reference</title>
<link rel="stylesheet" type="text/css" href="css/jazzy.css" />
<link rel="stylesheet" type="text/css" href="css/highlight.css" />
<meta charset="utf-8">
<script src="js/jquery.min.js" defer></script>
<script src="js/jazzy.js" defer></script>
<script src="js/lunr.min.js" defer></script>
<script src="js/typeahead.jquery.js" defer></script>
<script src="js/jazzy.search.js" defer></script>
</head>
<body>
<a name="//apple_ref/swift/Section/DataSources" class="dashAnchor"></a>
<a title="DataSources Reference"></a>
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="index.html">
DiffableDataSources Docs
</a>
(100% documented)
</p>
<p class="header-col--secondary">
<form role="search" action="search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
</form>
</p>
<p class="header-col header-col--secondary">
<a class="header-link" href="https://github.com/ra1028/DiffableDataSources">
<img class="header-icon" src="img/gh.png"/>
View on GitHub
</a>
</p>
</header>
<p class="breadcrumbs">
<a class="breadcrumb" href="index.html">DiffableDataSources Reference</a>
<img class="carat" src="img/carat.png" />
DataSources Reference
</p>
<div class="content-wrapper">
<nav class="navigation">
<ul class="nav-groups">
<li class="nav-group-name">
<a class="nav-group-name-link" href="DataSources.html">DataSources</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/TableViewDiffableDataSource.html">TableViewDiffableDataSource</a>
</li>
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/CollectionViewDiffableDataSource.html">CollectionViewDiffableDataSource</a>
</li>
</ul>
</li>
<li class="nav-group-name">
<a class="nav-group-name-link" href="Snapshot.html">Snapshot</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a>
</li>
</ul>
</li>
</ul>
</nav>
<article class="main-content">
<section class="section">
<div class="section-content">
<h1>DataSources</h1>
</div>
</section>
<section class="section">
<div class="section-content">
<div class="task-group">
<ul class="item-container">
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources09TableViewaB6SourceC"></a>
<a name="//apple_ref/swift/Class/TableViewDiffableDataSource" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources09TableViewaB6SourceC">TableViewDiffableDataSource</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>A class for backporting <code>UITableViewDiffableDataSource</code> introduced in iOS 13.0+, tvOS 13.0+.
Represents the data model object for <code>UITableView</code> that can be applies the
changes with automatic diffing.</p>
<a href="Classes/TableViewDiffableDataSource.html" class="slightly-smaller">See more</a>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">class</span> <span class="kt">TableViewDiffableDataSource</span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span> <span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UITableViewDataSource</span> <span class="k">where</span> <span class="kt">SectionIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span></code></pre>
</div>
</div>
</section>
</div>
</li>
</ul>
</div>
<div class="task-group">
<ul class="item-container">
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources014CollectionViewaB6SourceC"></a>
<a name="//apple_ref/swift/Class/CollectionViewDiffableDataSource" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources014CollectionViewaB6SourceC">CollectionViewDiffableDataSource</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>A class for backporting <code>UICollectionViewDiffableDataSource</code> introduced in iOS 13.0+, tvOS 13.0+.
Represents the data model object for <code>UICollectionView</code> that can be applies the
changes with automatic diffing.</p>
<a href="Classes/CollectionViewDiffableDataSource.html" class="slightly-smaller">See more</a>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">open</span> <span class="kd">class</span> <span class="kt">CollectionViewDiffableDataSource</span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span> <span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UICollectionViewDataSource</span> <span class="k">where</span> <span class="kt">SectionIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span></code></pre>
</div>
</div>
</section>
</div>
</li>
</ul>
</div>
</div>
</section>
</article>
</div>
<section class="footer">
<p>&copy; 2019 <a class="link" href="https://github.com/ra1028" target="_blank" rel="external">Ryo Aoyama</a>. All rights reserved. (Last updated: 2019-06-24)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.9.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external">Realm</a> project.</p>
</section>
</body>
</div>
</html>
+129
View File
@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Snapshot Reference</title>
<link rel="stylesheet" type="text/css" href="css/jazzy.css" />
<link rel="stylesheet" type="text/css" href="css/highlight.css" />
<meta charset="utf-8">
<script src="js/jquery.min.js" defer></script>
<script src="js/jazzy.js" defer></script>
<script src="js/lunr.min.js" defer></script>
<script src="js/typeahead.jquery.js" defer></script>
<script src="js/jazzy.search.js" defer></script>
</head>
<body>
<a name="//apple_ref/swift/Section/Snapshot" class="dashAnchor"></a>
<a title="Snapshot Reference"></a>
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="index.html">
DiffableDataSources Docs
</a>
(100% documented)
</p>
<p class="header-col--secondary">
<form role="search" action="search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
</form>
</p>
<p class="header-col header-col--secondary">
<a class="header-link" href="https://github.com/ra1028/DiffableDataSources">
<img class="header-icon" src="img/gh.png"/>
View on GitHub
</a>
</p>
</header>
<p class="breadcrumbs">
<a class="breadcrumb" href="index.html">DiffableDataSources Reference</a>
<img class="carat" src="img/carat.png" />
Snapshot Reference
</p>
<div class="content-wrapper">
<nav class="navigation">
<ul class="nav-groups">
<li class="nav-group-name">
<a class="nav-group-name-link" href="DataSources.html">DataSources</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/TableViewDiffableDataSource.html">TableViewDiffableDataSource</a>
</li>
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/CollectionViewDiffableDataSource.html">CollectionViewDiffableDataSource</a>
</li>
</ul>
</li>
<li class="nav-group-name">
<a class="nav-group-name-link" href="Snapshot.html">Snapshot</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a>
</li>
</ul>
</li>
</ul>
</nav>
<article class="main-content">
<section class="section">
<div class="section-content">
<h1>Snapshot</h1>
</div>
</section>
<section class="section">
<div class="section-content">
<div class="task-group">
<ul class="item-container">
<li class="item">
<div>
<code>
<a name="/s:19DiffableDataSources0aB14SourceSnapshotC"></a>
<a name="//apple_ref/swift/Class/DiffableDataSourceSnapshot" class="dashAnchor"></a>
<a class="token" href="#/s:19DiffableDataSources0aB14SourceSnapshotC">DiffableDataSourceSnapshot</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>A class for backporting <code>NSDiffableDataSourceSnapshot</code> introduced in iOS 13.0+, macOS 10.15+, tvOS 13.0+.
Represents the mutable state of diffable data source of UI.</p>
<a href="Classes/DiffableDataSourceSnapshot.html" class="slightly-smaller">See more</a>
</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">class</span> <span class="kt">DiffableDataSourceSnapshot</span><span class="o">&lt;</span><span class="kt">SectionIdentifierType</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span><span class="o">&gt;</span> <span class="k">where</span> <span class="kt">SectionIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span><span class="p">,</span> <span class="kt">ItemIdentifierType</span> <span class="p">:</span> <span class="kt">Hashable</span></code></pre>
</div>
</div>
</section>
</div>
</li>
</ul>
</div>
</div>
</section>
</article>
</div>
<section class="footer">
<p>&copy; 2019 <a class="link" href="https://github.com/ra1028" target="_blank" rel="external">Ryo Aoyama</a>. All rights reserved. (Last updated: 2019-06-24)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.9.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external">Realm</a> project.</p>
</section>
</body>
</div>
</html>
+28
View File
@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="136" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="a">
<rect width="136" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#555" d="M0 0h93v20H0z"/>
<path fill="#4c1" d="M93 0h43v20H93z"/>
<path fill="url(#b)" d="M0 0h136v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
<text x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="830">
documentation
</text>
<text x="475" y="140" transform="scale(.1)" textLength="830">
documentation
</text>
<text x="1135" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">
100%
</text>
<text x="1135" y="140" transform="scale(.1)" textLength="330">
100%
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+200
View File
@@ -0,0 +1,200 @@
/* Credit to https://gist.github.com/wataru420/2048287 */
.highlight {
/* Comment */
/* Error */
/* Keyword */
/* Operator */
/* Comment.Multiline */
/* Comment.Preproc */
/* Comment.Single */
/* Comment.Special */
/* Generic.Deleted */
/* Generic.Deleted.Specific */
/* Generic.Emph */
/* Generic.Error */
/* Generic.Heading */
/* Generic.Inserted */
/* Generic.Inserted.Specific */
/* Generic.Output */
/* Generic.Prompt */
/* Generic.Strong */
/* Generic.Subheading */
/* Generic.Traceback */
/* Keyword.Constant */
/* Keyword.Declaration */
/* Keyword.Pseudo */
/* Keyword.Reserved */
/* Keyword.Type */
/* Literal.Number */
/* Literal.String */
/* Name.Attribute */
/* Name.Builtin */
/* Name.Class */
/* Name.Constant */
/* Name.Entity */
/* Name.Exception */
/* Name.Function */
/* Name.Namespace */
/* Name.Tag */
/* Name.Variable */
/* Operator.Word */
/* Text.Whitespace */
/* Literal.Number.Float */
/* Literal.Number.Hex */
/* Literal.Number.Integer */
/* Literal.Number.Oct */
/* Literal.String.Backtick */
/* Literal.String.Char */
/* Literal.String.Doc */
/* Literal.String.Double */
/* Literal.String.Escape */
/* Literal.String.Heredoc */
/* Literal.String.Interpol */
/* Literal.String.Other */
/* Literal.String.Regex */
/* Literal.String.Single */
/* Literal.String.Symbol */
/* Name.Builtin.Pseudo */
/* Name.Variable.Class */
/* Name.Variable.Global */
/* Name.Variable.Instance */
/* Literal.Number.Integer.Long */ }
.highlight .c {
color: #999988;
font-style: italic; }
.highlight .err {
color: #a61717;
background-color: #e3d2d2; }
.highlight .k {
color: #000000;
font-weight: bold; }
.highlight .o {
color: #000000;
font-weight: bold; }
.highlight .cm {
color: #999988;
font-style: italic; }
.highlight .cp {
color: #999999;
font-weight: bold; }
.highlight .c1 {
color: #999988;
font-style: italic; }
.highlight .cs {
color: #999999;
font-weight: bold;
font-style: italic; }
.highlight .gd {
color: #000000;
background-color: #ffdddd; }
.highlight .gd .x {
color: #000000;
background-color: #ffaaaa; }
.highlight .ge {
color: #000000;
font-style: italic; }
.highlight .gr {
color: #aa0000; }
.highlight .gh {
color: #999999; }
.highlight .gi {
color: #000000;
background-color: #ddffdd; }
.highlight .gi .x {
color: #000000;
background-color: #aaffaa; }
.highlight .go {
color: #888888; }
.highlight .gp {
color: #555555; }
.highlight .gs {
font-weight: bold; }
.highlight .gu {
color: #aaaaaa; }
.highlight .gt {
color: #aa0000; }
.highlight .kc {
color: #000000;
font-weight: bold; }
.highlight .kd {
color: #000000;
font-weight: bold; }
.highlight .kp {
color: #000000;
font-weight: bold; }
.highlight .kr {
color: #000000;
font-weight: bold; }
.highlight .kt {
color: #445588; }
.highlight .m {
color: #009999; }
.highlight .s {
color: #d14; }
.highlight .na {
color: #008080; }
.highlight .nb {
color: #0086B3; }
.highlight .nc {
color: #445588;
font-weight: bold; }
.highlight .no {
color: #008080; }
.highlight .ni {
color: #800080; }
.highlight .ne {
color: #990000;
font-weight: bold; }
.highlight .nf {
color: #990000; }
.highlight .nn {
color: #555555; }
.highlight .nt {
color: #000080; }
.highlight .nv {
color: #008080; }
.highlight .ow {
color: #000000;
font-weight: bold; }
.highlight .w {
color: #bbbbbb; }
.highlight .mf {
color: #009999; }
.highlight .mh {
color: #009999; }
.highlight .mi {
color: #009999; }
.highlight .mo {
color: #009999; }
.highlight .sb {
color: #d14; }
.highlight .sc {
color: #d14; }
.highlight .sd {
color: #d14; }
.highlight .s2 {
color: #d14; }
.highlight .se {
color: #d14; }
.highlight .sh {
color: #d14; }
.highlight .si {
color: #d14; }
.highlight .sx {
color: #d14; }
.highlight .sr {
color: #009926; }
.highlight .s1 {
color: #d14; }
.highlight .ss {
color: #990073; }
.highlight .bp {
color: #999999; }
.highlight .vc {
color: #008080; }
.highlight .vg {
color: #008080; }
.highlight .vi {
color: #008080; }
.highlight .il {
color: #009999; }
+368
View File
@@ -0,0 +1,368 @@
*, *:before, *:after {
box-sizing: inherit; }
body {
margin: 0;
background: #fff;
color: #333;
font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
letter-spacing: .2px;
-webkit-font-smoothing: antialiased;
box-sizing: border-box; }
h1 {
font-size: 2rem;
font-weight: 700;
margin: 1.275em 0 0.6em; }
h2 {
font-size: 1.75rem;
font-weight: 700;
margin: 1.275em 0 0.3em; }
h3 {
font-size: 1.5rem;
font-weight: 700;
margin: 1em 0 0.3em; }
h4 {
font-size: 1.25rem;
font-weight: 700;
margin: 1.275em 0 0.85em; }
h5 {
font-size: 1rem;
font-weight: 700;
margin: 1.275em 0 0.85em; }
h6 {
font-size: 1rem;
font-weight: 700;
margin: 1.275em 0 0.85em;
color: #777; }
p {
margin: 0 0 1em; }
ul, ol {
padding: 0 0 0 2em;
margin: 0 0 0.85em; }
blockquote {
margin: 0 0 0.85em;
padding: 0 15px;
color: #858585;
border-left: 4px solid #e5e5e5; }
img {
max-width: 100%; }
a {
color: #4183c4;
text-decoration: none; }
a:hover, a:focus {
outline: 0;
text-decoration: underline; }
table {
background: #fff;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
overflow: auto;
margin: 0 0 0.85em; }
tr:nth-child(2n) {
background-color: #fbfbfb; }
th, td {
padding: 6px 13px;
border: 1px solid #ddd; }
pre {
margin: 0 0 1.275em;
padding: .85em 1em;
overflow: auto;
background: #f7f7f7;
font-size: .85em;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
code {
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
p > code, li > code {
background: #f7f7f7;
padding: .2em; }
p > code:before, p > code:after, li > code:before, li > code:after {
letter-spacing: -.2em;
content: "\00a0"; }
pre code {
padding: 0;
white-space: pre; }
.content-wrapper {
display: flex;
flex-direction: column; }
@media (min-width: 768px) {
.content-wrapper {
flex-direction: row; } }
.header {
display: flex;
padding: 8px;
font-size: 0.875em;
background: #444;
color: #999; }
.header-col {
margin: 0;
padding: 0 8px; }
.header-col--primary {
flex: 1; }
.header-link {
color: #fff; }
.header-icon {
padding-right: 6px;
vertical-align: -4px;
height: 16px; }
.breadcrumbs {
font-size: 0.875em;
padding: 8px 16px;
margin: 0;
background: #fbfbfb;
border-bottom: 1px solid #ddd; }
.carat {
height: 10px;
margin: 0 5px; }
.navigation {
order: 2; }
@media (min-width: 768px) {
.navigation {
order: 1;
width: 25%;
max-width: 300px;
padding-bottom: 64px;
overflow: hidden;
word-wrap: normal;
background: #fbfbfb;
border-right: 1px solid #ddd; } }
.nav-groups {
list-style-type: none;
padding-left: 0; }
.nav-group-name {
border-bottom: 1px solid #ddd;
padding: 8px 0 8px 16px; }
.nav-group-name-link {
color: #333; }
.nav-group-tasks {
margin: 8px 0;
padding: 0 0 0 8px; }
.nav-group-task {
font-size: 1em;
list-style-type: none;
white-space: nowrap; }
.nav-group-task-link {
color: #808080; }
.main-content {
order: 1; }
@media (min-width: 768px) {
.main-content {
order: 2;
flex: 1;
padding-bottom: 60px; } }
.section {
padding: 0 32px;
border-bottom: 1px solid #ddd; }
.section-content {
max-width: 834px;
margin: 0 auto;
padding: 16px 0; }
.section-name {
color: #666;
display: block; }
.declaration .highlight {
overflow-x: initial;
padding: 8px 0;
margin: 0;
background-color: transparent;
border: none; }
.task-group-section {
border-top: 1px solid #ddd; }
.task-group {
padding-top: 0px; }
.task-name-container a[name]:before {
content: "";
display: block; }
.item-container {
padding: 0; }
.item {
padding-top: 8px;
width: 100%;
list-style-type: none; }
.item a[name]:before {
content: "";
display: block; }
.item .token {
padding-left: 3px;
margin-left: 0px;
font-size: 1rem; }
.item .declaration-note {
font-size: .85em;
color: #808080;
font-style: italic; }
.pointer-container {
border-bottom: 1px solid #ddd;
left: -23px;
padding-bottom: 13px;
position: relative;
width: 110%; }
.pointer {
left: 21px;
top: 7px;
display: block;
position: absolute;
width: 12px;
height: 12px;
border-left: 1px solid #ddd;
border-top: 1px solid #ddd;
background: #fff;
transform: rotate(45deg); }
.height-container {
display: none;
position: relative;
width: 100%;
overflow: hidden; }
.height-container .section {
background: #fff;
border: 1px solid #ddd;
border-top-width: 0;
padding-top: 10px;
padding-bottom: 5px;
padding: 8px 16px; }
.aside, .language {
padding: 6px 12px;
margin: 12px 0;
border-left: 5px solid #dddddd;
overflow-y: hidden; }
.aside .aside-title, .language .aside-title {
font-size: 9px;
letter-spacing: 2px;
text-transform: uppercase;
padding-bottom: 0;
margin: 0;
color: #aaa;
-webkit-user-select: none; }
.aside p:last-child, .language p:last-child {
margin-bottom: 0; }
.language {
border-left: 5px solid #cde9f4; }
.language .aside-title {
color: #4183c4; }
.aside-warning {
border-left: 5px solid #ff6666; }
.aside-warning .aside-title {
color: #ff0000; }
.graybox {
border-collapse: collapse;
width: 100%; }
.graybox p {
margin: 0;
word-break: break-word;
min-width: 50px; }
.graybox td {
border: 1px solid #ddd;
padding: 5px 25px 5px 10px;
vertical-align: middle; }
.graybox tr td:first-of-type {
text-align: right;
padding: 7px;
vertical-align: top;
word-break: normal;
width: 40px; }
.slightly-smaller {
font-size: 0.9em; }
.footer {
padding: 8px 16px;
background: #444;
color: #ddd;
font-size: 0.8em; }
.footer p {
margin: 8px 0; }
.footer a {
color: #fff; }
html.dash .header, html.dash .breadcrumbs, html.dash .navigation {
display: none; }
html.dash .height-container {
display: block; }
form[role=search] input {
font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 24px;
padding: 0 10px;
margin: 0;
border: none;
border-radius: 1em; }
.loading form[role=search] input {
background: white url(../img/spinner.gif) center right 4px no-repeat; }
form[role=search] .tt-menu {
margin: 0;
min-width: 300px;
background: #fbfbfb;
color: #333;
border: 1px solid #ddd; }
form[role=search] .tt-highlight {
font-weight: bold; }
form[role=search] .tt-suggestion {
font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
padding: 0 8px; }
form[role=search] .tt-suggestion span {
display: table-cell;
white-space: nowrap; }
form[role=search] .tt-suggestion .doc-parent-name {
width: 100%;
text-align: right;
font-weight: normal;
font-size: 0.9em;
padding-left: 16px; }
form[role=search] .tt-suggestion:hover,
form[role=search] .tt-suggestion.tt-cursor {
cursor: pointer;
background-color: #4183c4;
color: #fff; }
form[role=search] .tt-suggestion:hover .doc-parent-name,
form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
color: #fff; }
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+293
View File
@@ -0,0 +1,293 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>DiffableDataSources Reference</title>
<link rel="stylesheet" type="text/css" href="css/jazzy.css" />
<link rel="stylesheet" type="text/css" href="css/highlight.css" />
<meta charset="utf-8">
<script src="js/jquery.min.js" defer></script>
<script src="js/jazzy.js" defer></script>
<script src="js/lunr.min.js" defer></script>
<script src="js/typeahead.jquery.js" defer></script>
<script src="js/jazzy.search.js" defer></script>
</head>
<body>
<a title="DiffableDataSources Reference"></a>
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="index.html">
DiffableDataSources Docs
</a>
(100% documented)
</p>
<p class="header-col--secondary">
<form role="search" action="search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
</form>
</p>
<p class="header-col header-col--secondary">
<a class="header-link" href="https://github.com/ra1028/DiffableDataSources">
<img class="header-icon" src="img/gh.png"/>
View on GitHub
</a>
</p>
</header>
<p class="breadcrumbs">
<a class="breadcrumb" href="index.html">DiffableDataSources Reference</a>
<img class="carat" src="img/carat.png" />
DiffableDataSources Reference
</p>
<div class="content-wrapper">
<nav class="navigation">
<ul class="nav-groups">
<li class="nav-group-name">
<a class="nav-group-name-link" href="DataSources.html">DataSources</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/TableViewDiffableDataSource.html">TableViewDiffableDataSource</a>
</li>
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/CollectionViewDiffableDataSource.html">CollectionViewDiffableDataSource</a>
</li>
</ul>
</li>
<li class="nav-group-name">
<a class="nav-group-name-link" href="Snapshot.html">Snapshot</a>
<ul class="nav-group-tasks">
<li class="nav-group-task">
<a class="nav-group-task-link" href="Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a>
</li>
</ul>
</li>
</ul>
</nav>
<article class="main-content">
<section class="section">
<div class="section-content">
<H1 align="center">
DiffableDataSources
</H1>
<H4 align="center">
💾 A library for backporting UITableView/UICollectionViewDiffableDataSource</br>
powered by <a href="https://github.com/ra1028/DifferenceKit">DifferenceKit</a>.
</H4>
<p align="center">
<a href="https://developer.apple.com/swift"><img alt="Swift5" src="https://img.shields.io/badge/language-Swift5-orange.svg"/></a>
<a href="https://github.com/ra1028/DiffableDataSources/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/ra1028/DiffableDataSources.svg"/></a>
<a href="https://cocoapods.org/pods/DiffableDataSources"><img alt="CocoaPods" src="https://img.shields.io/cocoapods/v/DiffableDataSources.svg"/></a>
<a href="https://github.com/Carthage/Carthage"><img alt="Carthage" src="https://img.shields.io/badge/carthage-compatible-yellow.svg"/></a>
<a href="https://swift.org/package-manager"><img alt="Swift Package Manager" src="https://img.shields.io/badge/SwiftPM-compatible-yellowgreen.svg"/></a>
</br>
<a href="https://dev.azure.com/ra1028/GitHub/_build/latest?definitionId=3&branchName=master"><img alt="Build Status" src="https://dev.azure.com/ra1028/GitHub/_apis/build/status/ra1028.DiffableDataSources?branchName=master"/></a>
<a href="https://developer.apple.com/"><img alt="Platform" src="https://img.shields.io/badge/platform-iOS%20%7C%20macOS%20%7C%20tvOS-green.svg"/></a>
<a href="https://github.com/ra1028/DiffableDataSources/blob/master/LICENSE"><img alt="Lincense" src="https://img.shields.io/badge/License-Apache%202.0-black.svg"/></a>
</p>
<p align="center">
Made with ❤️ by <a href="https://github.com/ra1028">Ryo Aoyama</a>
</p>
<hr>
<h2 id='introduction' class='heading'>Introduction</h2>
<p><img src="https://raw.githubusercontent.com/ra1028/DiffableDataSources/master/assets/insertion_sort.gif" height="400" align="right">
<img src="https://raw.githubusercontent.com/ra1028/DiffableDataSources/master/assets/mountains.gif" height="400" align="right"></p>
<p>Apple has announced a diffable data source at WWDC 2019.<br>
It&rsquo;s a great API that easily updating our table view and collection view items using automatic diffing.<br>
However, it&rsquo;s a little while before we can use it in a production service.<br>
That because it requires the latest OS to use.<br>
DiffableDataSources make it possible to introduce almost the same functionality from now on. </p>
<p>Uses a sophisticated open source <a href="https://github.com/ra1028/DifferenceKit">DifferenceKit</a> for the algorithm engine.<br>
It&rsquo;s extremely fast and completely avoids synchronization bugs, exceptions, and crashes. </p>
<p><br clear="all"></p>
<hr>
<h2 id='difference-from-the-official' class='heading'>Difference from the Official</h2>
<h4 id='spec' class='heading'>Spec</h4>
<ul>
<li>Supports iOS 9.0+ / macOS 10.11+ / tvOS 9.0+</li>
<li>Open sourced algorithm.</li>
<li>Duplicate sections or items are allowed.<br></li>
<li>Using <code>performBatchUpdates</code> for diffing updates.</li>
</ul>
<h4 id='namings' class='heading'>Namings</h4>
<p><code>DiffableDataSources</code> have different class names to avoid conflicts with the official API.<br>
Correspondence table is below. </p>
<table><thead>
<tr>
<th style="text-align: left">Official</th>
<th style="text-align: left">Backported</th>
</tr>
</thead><tbody>
<tr>
<td style="text-align: left"><a href="https://developer.apple.com/documentation/uikit/uitableviewdiffabledatasource">NSDiffableDataSourceSnapshot</a></td>
<td style="text-align: left">DiffableDataSourceSnapshot</td>
</tr>
<tr>
<td style="text-align: left"><a href="https://developer.apple.com/documentation/uikit/uitableviewdiffabledatasource">UITableViewDiffableDataSource</a></td>
<td style="text-align: left">TableViewDiffableDataSource</td>
</tr>
<tr>
<td style="text-align: left"><a href="https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource">UICollectionViewDiffableDataSource</a></td>
<td style="text-align: left">CollectionViewDiffableDataSource</td>
</tr>
<tr>
<td style="text-align: left"><a href="https://developer.apple.com/documentation/appkit/nscollectionviewdiffabledatasource">NSCollectionViewDiffableDataSource</a></td>
<td style="text-align: left">CocoaCollectionViewDiffableDataSource</td>
</tr>
</tbody></table>
<hr>
<h2 id='getting-started' class='heading'>Getting Started</h2>
<ul>
<li><a href="https://ra1028.github.io/DiffableDataSources">API Documentation</a></li>
<li><a href="https://github.com/ra1028/DiffableDataSources/tree/master/Examples">Example Apps</a></li>
<li><a href="https://developer.apple.com/videos/play/wwdc2019/220">WWDC 2019 Session</a></li>
</ul>
<h4 id='build-project' class='heading'>Build Project</h4>
<pre class="highlight shell"><code><span class="nv">$ </span>git clone https://github.com/ra1028/DiffableDataSources.git
<span class="nv">$ </span><span class="nb">cd </span>DiffableDataSources/
<span class="nv">$ </span>make setup
<span class="nv">$ </span>open DiffableDataSources.xcworkspace
</code></pre>
<hr>
<h2 id='basic-usage' class='heading'>Basic Usage</h2>
<p>First, define the type representing section.<br>
It should conforms to <code>Hashable</code> for identifies from the all sections.<br>
Type of enum can used conveniently befause it conforms <code>Hashable</code> by default. </p>
<pre class="highlight swift"><code><span class="kd">enum</span> <span class="kt">Section</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">main</span>
<span class="p">}</span>
</code></pre>
<p>Then, define the item type conforms to <code>Hashable</code>. </p>
<pre class="highlight swift"><code><span class="kd">struct</span> <span class="kt">User</span><span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{</span>
<span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
</code></pre>
<p>Create a data source object, it will be set to table view automatically.<br>
You should dequeue the non nil cells via closure. </p>
<pre class="highlight swift"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">UsersViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span> <span class="o">=</span> <span class="o">...</span>
<span class="kd">lazy</span> <span class="k">var</span> <span class="nv">dataSource</span> <span class="o">=</span> <span class="kt">TableViewDiffableDataSource</span><span class="o">&lt;</span><span class="kt">Section</span><span class="p">,</span> <span class="kt">User</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">tableView</span><span class="p">:</span> <span class="n">tableView</span><span class="p">)</span> <span class="p">{</span> <span class="n">tableView</span><span class="p">,</span> <span class="n">indexPath</span><span class="p">,</span> <span class="n">user</span> <span class="k">in</span>
<span class="k">let</span> <span class="nv">cell</span> <span class="o">=</span> <span class="n">tableView</span><span class="o">.</span><span class="nf">dequeueReusableCell</span><span class="p">(</span><span class="nv">withIdentifier</span><span class="p">:</span> <span class="s">"Cell"</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">indexPath</span><span class="p">)</span>
<span class="n">cell</span><span class="o">.</span><span class="n">textLabel</span><span class="p">?</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">user</span><span class="o">.</span><span class="n">name</span>
<span class="k">return</span> <span class="n">cell</span>
<span class="p">}</span>
<span class="k">override</span> <span class="kd">func</span> <span class="nf">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
<span class="k">super</span><span class="o">.</span><span class="nf">viewDidLoad</span><span class="p">()</span>
<span class="n">tableView</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="kt">UITableViewCell</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">forCellReuseIdentifier</span><span class="p">:</span> <span class="s">"Cell"</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<p>Manages and updates the data sources intuitively by intermediating <code><a href="Classes/DiffableDataSourceSnapshot.html">DiffableDataSourceSnapshot</a></code>.<br>
The UI isn&rsquo;t updated until you apply the edited snapshot object.<br>
Update the UI with diffing animation automatically calculated by applying an edited snapshot. </p>
<pre class="highlight swift"><code><span class="k">let</span> <span class="nv">users</span> <span class="o">=</span> <span class="p">[</span>
<span class="kt">User</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"Steve Jobs"</span><span class="p">),</span>
<span class="kt">User</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"Stephen Wozniak"</span><span class="p">),</span>
<span class="kt">User</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"Tim Cook"</span><span class="p">),</span>
<span class="kt">User</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"Jonathan Ive"</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">let</span> <span class="nv">snapshot</span> <span class="o">=</span> <span class="kt">DiffableDataSourceSnapshot</span><span class="o">&lt;</span><span class="kt">Section</span><span class="p">,</span> <span class="kt">User</span><span class="o">&gt;</span><span class="p">()</span>
<span class="n">snapshot</span><span class="o">.</span><span class="nf">appendSections</span><span class="p">([</span><span class="o">.</span><span class="n">main</span><span class="p">])</span>
<span class="n">snapshot</span><span class="o">.</span><span class="nf">appendItems</span><span class="p">(</span><span class="n">users</span><span class="p">)</span>
<span class="n">dataSource</span><span class="o">.</span><span class="nf">apply</span><span class="p">(</span><span class="n">snapshot</span><span class="p">)</span>
</code></pre>
<p>Check the documentation for more detailed API. </p>
<H3 align="center">
<a href="https://ra1028.github.io/DiffableDataSources">[See More Usage]</a>
</H3>
<hr>
<h2 id='requirements' class='heading'>Requirements</h2>
<ul>
<li>Swift 5.0+</li>
<li>iOS 9.0+</li>
<li>macOS 10.11+</li>
<li>tvOS 9.0+</li>
</ul>
<hr>
<h2 id='installation' class='heading'>Installation</h2>
<h3 id='a-href-https-cocoapods-org-cocoapods-a' class='heading'><a href="https://cocoapods.org">CocoaPods</a></h3>
<p>Add the following to your <code>Podfile</code>:</p>
<pre class="highlight ruby"><code><span class="n">pod</span> <span class="s1">'DiffableDataSources'</span>
</code></pre>
<h3 id='a-href-https-github-com-carthage-carthage-carthage-a' class='heading'><a href="https://github.com/Carthage/Carthage">Carthage</a></h3>
<p>Add the following to your <code>Cartfile</code>:</p>
<pre class="highlight plaintext"><code>github "ra1028/DiffableDataSources"
</code></pre>
<h3 id='a-href-https-swift-org-package-manager-swift-package-manager-a' class='heading'><a href="https://swift.org/package-manager/">Swift Package Manager</a></h3>
<p>Add the following to the dependencies of your <code>Package.swift</code>:</p>
<pre class="highlight swift"><code><span class="o">.</span><span class="nf">package</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="s">"https://github.com/ra1028/DiffableDataSources.git"</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="s">"x.x.x"</span><span class="p">)</span>
</code></pre>
<hr>
<h2 id='contributing' class='heading'>Contributing</h2>
<p>Pull requests, bug reports and feature requests are welcome 🚀<br>
Please see the <a href="https://github.com/ra1028/DiffableDataSources/blob/master/CONTRIBUTING.md">CONTRIBUTING</a> file for learn how to contribute to DiffableDataSources. </p>
<hr>
<h2 id='relations' class='heading'>Relations</h2>
<h4 id='a-href-https-github-com-ra1028-differencekit-differencekit-a' class='heading'><a href="https://github.com/ra1028/DifferenceKit">DifferenceKit</a></h4>
<p>A fast and flexible O(n) difference algorithm framework for Swift collection.</p>
<h4 id='a-href-https-github-com-ra1028-carbon-carbon-a' class='heading'><a href="https://github.com/ra1028/Carbon">Carbon</a></h4>
<p>A declarative library for building component-based user interfaces in UITableView and UICollectionView.</p>
<hr>
<h2 id='license' class='heading'>License</h2>
<p>DiffableDataSources is released under the <a href="https://github.com/ra1028/DiffableDataSources/blob/master/LICENSE">Apache 2.0 License</a>. </p>
</div>
</section>
</article>
</div>
<section class="footer">
<p>&copy; 2019 <a class="link" href="https://github.com/ra1028" target="_blank" rel="external">Ryo Aoyama</a>. All rights reserved. (Last updated: 2019-06-24)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.9.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external">Realm</a> project.</p>
</section>
</body>
</div>
</html>
+43
View File
@@ -0,0 +1,43 @@
window.jazzy = {'docset': false}
if (typeof window.dash != 'undefined') {
document.documentElement.className += ' dash'
window.jazzy.docset = true
}
if (navigator.userAgent.match(/xcode/i)) {
document.documentElement.className += ' xcode'
window.jazzy.docset = true
}
// On doc load, toggle the URL hash discussion if present
$(document).ready(function() {
if (!window.jazzy.docset) {
var linkToHash = $('a[href="' + window.location.hash +'"]');
linkToHash.trigger("click");
}
});
// On token click, toggle its discussion and animate token.marginLeft
$(".token").click(function(event) {
if (window.jazzy.docset) {
return;
}
var link = $(this);
var animationDuration = 300;
$content = link.parent().parent().next();
$content.slideToggle(animationDuration);
// Keeps the document from jumping to the hash.
var href = $(this).attr('href');
if (history.pushState) {
history.pushState({}, '', href);
} else {
location.hash = href;
}
event.preventDefault();
});
// Dumb down quotes within code blocks that delimit strings instead of quotations
// https://github.com/realm/jazzy/issues/714
$("code q").replaceWith(function () {
return ["\"", $(this).contents(), "\""];
});
+62
View File
@@ -0,0 +1,62 @@
$(function(){
var searchIndex = lunr(function() {
this.ref('url');
this.field('name');
});
var $typeahead = $('[data-typeahead]');
var $form = $typeahead.parents('form');
var searchURL = $form.attr('action');
function displayTemplate(result) {
return result.name;
}
function suggestionTemplate(result) {
var t = '<div class="list-group-item clearfix">';
t += '<span class="doc-name">' + result.name + '</span>';
if (result.parent_name) {
t += '<span class="doc-parent-name label">' + result.parent_name + '</span>';
}
t += '</div>';
return t;
}
$typeahead.one('focus', function() {
$form.addClass('loading');
$.getJSON(searchURL).then(function(searchData) {
$.each(searchData, function (url, doc) {
searchIndex.add({url: url, name: doc.name});
});
$typeahead.typeahead(
{
highlight: true,
minLength: 3
},
{
limit: 10,
display: displayTemplate,
templates: { suggestion: suggestionTemplate },
source: function(query, sync) {
var results = searchIndex.search(query).map(function(result) {
var doc = searchData[result.ref];
doc.url = result.ref;
return doc;
});
sync(results);
}
}
);
$form.removeClass('loading');
$typeahead.trigger('focus');
});
});
var baseURL = searchURL.slice(0, -"search.json".length);
$typeahead.on('typeahead:select', function(e, result) {
window.location = baseURL + result.url;
});
});
Vendored Executable
+4
View File
File diff suppressed because one or more lines are too long
Vendored Executable
+6
View File
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+1
View File
File diff suppressed because one or more lines are too long