],
14 | animation: UITableView.RowAnimation = .automatic,
15 | section: Int = 0,
16 | updateDataSource: (() -> Void),
17 | completion: (() -> Void)? = nil) {
18 | guard !changes.isEmpty else {
19 | completion?()
20 | return
21 | }
22 |
23 | if superview == nil {
24 | updateDataSource()
25 | reloadData()
26 | completion?()
27 | return
28 | }
29 |
30 | setNeedsLayout()
31 | layoutIfNeeded()
32 |
33 | let manager = IndexPathManager()
34 | let result = manager.process(changes, section: section)
35 |
36 | if #available(iOS 11, tvOS 11, *) {
37 | performBatchUpdates({
38 | updateDataSource()
39 | validateUpdates(result.insert, animation: animation, then: insertRows)
40 | validateUpdates(result.updates, animation: animation, then: reloadRows)
41 | validateUpdates(result.deletions, animation: animation, then: deleteRows)
42 | if !result.moves.isEmpty {
43 | result.moves.forEach { moveRow(at: $0.from, to: $0.to) }
44 | }
45 | }, completion: { _ in
46 | completion?()
47 | })
48 | } else {
49 | beginUpdates()
50 | updateDataSource()
51 | validateUpdates(result.insert, animation: animation, then: insertRows)
52 | validateUpdates(result.updates, animation: animation, then: reloadRows)
53 | validateUpdates(result.deletions, animation: animation, then: deleteRows)
54 | if !result.moves.isEmpty {
55 | result.moves.forEach { moveRow(at: $0.from, to: $0.to) }
56 | }
57 | endUpdates()
58 | completion?()
59 | }
60 | }
61 |
62 | private func validateUpdates(_ collection: [IndexPath],
63 | animation: UITableView.RowAnimation,
64 | then: ([IndexPath], UITableView.RowAnimation) -> Void) {
65 | if !collection.isEmpty { then(collection, animation) }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Differific.xcodeproj/xcshareddata/xcschemes/Differific-watchOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Tests/macOS/NSTableViewExtensionsTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | import Differific
3 |
4 | class NSTableViewExtensionsTests: XCTestCase {
5 | class DataSourceMock: NSObject, NSTableViewDataSource {
6 | var models = [String]()
7 |
8 | init(models: [String] = []) {
9 | self.models = models
10 | }
11 |
12 | func numberOfRows(in tableView: NSTableView) -> Int {
13 | return models.count
14 | }
15 | }
16 |
17 | func testReloadWithInsertions() {
18 | let dataSource = DataSourceMock()
19 | let tableView = NSTableView()
20 | tableView.dataSource = dataSource
21 |
22 | let old = dataSource.models
23 | let new = ["Foo", "Bar", "Baz"]
24 | let manager = DiffManager()
25 | let changes = manager.diff(old, new)
26 |
27 | var ranBefore: Bool = false
28 | var ranCompletion: Bool = false
29 |
30 | tableView.reload(with: changes, animation: .effectFade, updateDataSource: {
31 | dataSource.models = new
32 | ranBefore = true
33 | }) {
34 | ranCompletion = true
35 | }
36 |
37 | XCTAssertTrue(ranBefore)
38 | XCTAssertTrue(ranCompletion)
39 | }
40 |
41 | func testReloadWithMove() {
42 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
43 | let tableView = NSTableView()
44 | tableView.dataSource = dataSource
45 |
46 | let old = dataSource.models
47 | let new = ["Baz", "Bar", "Foo"]
48 | let manager = DiffManager()
49 | let changes = manager.diff(old, new)
50 |
51 | var ranBefore: Bool = false
52 | var ranCompletion: Bool = false
53 |
54 | tableView.reload(with: changes, animation: .effectFade, updateDataSource: {
55 | dataSource.models = new
56 | ranBefore = true
57 | }) {
58 | ranCompletion = true
59 | }
60 |
61 | XCTAssertTrue(ranBefore)
62 | XCTAssertTrue(ranCompletion)
63 | }
64 |
65 | func testReloadWithDeletions() {
66 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
67 | let tableView = NSTableView()
68 | tableView.dataSource = dataSource
69 |
70 | let old = dataSource.models
71 | let new = [String]()
72 | let manager = DiffManager()
73 | let changes = manager.diff(old, new)
74 |
75 | var ranBefore: Bool = false
76 | var ranCompletion: Bool = false
77 |
78 | tableView.reload(with: changes, animation: .effectFade, updateDataSource: {
79 | dataSource.models = new
80 | ranBefore = true
81 | }) {
82 | ranCompletion = true
83 | }
84 |
85 | XCTAssertTrue(ranBefore)
86 | XCTAssertTrue(ranCompletion)
87 | }
88 |
89 | func testReloadWithEmptyChanges() {
90 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
91 | let tableView = NSTableView()
92 | tableView.dataSource = dataSource
93 |
94 | let old = dataSource.models
95 | let new = ["Foo", "Bar", "Baz"]
96 | let manager = DiffManager()
97 | let changes = manager.diff(old, new)
98 |
99 | var ranBefore: Bool = false
100 | var ranCompletion: Bool = false
101 |
102 | tableView.reload(with: changes, animation: .effectFade, updateDataSource: {
103 | dataSource.models = new
104 | ranBefore = true
105 | }) {
106 | ranCompletion = true
107 | }
108 |
109 | XCTAssertFalse(ranBefore)
110 | XCTAssertTrue(ranCompletion)
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Differific
2 |
3 |
4 |
5 | [](https://travis-ci.org/zenangst/Differific)
6 | [](http://cocoadocs.org/docsets/Differific)
7 | [](https://github.com/Carthage/Carthage)
8 | [](https://codecov.io/gh/zenangst/Differific)
9 | [](http://cocoadocs.org/docsets/Differific)
10 | [](http://cocoadocs.org/docsets/Differific)
11 | 
12 |
13 |
14 |
15 | ## Description
16 |
17 |
18 |
19 | **Differific** is a diffing tool that helps you compare Hashable objects using the Paul Heckel's diffing algorithm. Creating a changeset is seamless for all your diffing needs. The library also includes some convenience extensions to make life easier when updating data sources.
20 |
21 | The library is based and highly influenced by Matias Cudich's ([@mcudich](https://github.com/mcudich)) [HeckelDiff](https://github.com/mcudich/HeckelDiff) library that aims to solve the same issue. Versions prior to 0.3.0 was based on [DeepDiff](https://github.com/onmyway133/DeepDiff).
22 | For more information about how the algorithm works and the performance of the algorithm, head over to [DeepDiff](https://github.com/onmyway133/DeepDiff/blob/master/README.md#among-different-frameworks). For the time being, both frameworks are very similar; this is subject to change when the frameworks evolve.
23 |
24 | ## Features
25 |
26 | - [x] 🍩Built-in extensions for updating table & collection views.
27 | - [x] 🎩Customizable diffing.
28 | - [x] 🏎High performance.
29 | - [x] 📱iOS support.
30 | - [x] 💻macOS support.
31 | - [x] 📺tvOS support.
32 |
33 | ## Usage
34 |
35 | ### Diffing two collections
36 |
37 | ```swift
38 | let old = ["Foo", "Bar"]
39 | let new = ["Foo", "Bar", "Baz"]
40 | let manager = DiffManager()
41 | let changes = manager.diff(old, new)
42 | ```
43 |
44 | ### Updating a table or collection view
45 |
46 | ```swift
47 | // uiElement is either your table view or collection view.
48 | let old = dataSource.models
49 | let new = newCollection
50 | let changes = DiffManager().diff(old, new)
51 | uiElement.reload(with: changes, before: { dataSource.models = new })
52 | ```
53 |
54 |
55 | ## Installation
56 |
57 | **Differific** is available through [CocoaPods](http://cocoapods.org). To install
58 | it, simply add the following line to your Podfile:
59 |
60 | ```ruby
61 | pod 'Differific'
62 | ```
63 |
64 | **Differific** is also available through [Carthage](https://github.com/Carthage/Carthage).
65 | To install just write into your Cartfile:
66 |
67 | ```ruby
68 | github "zenangst/Differific"
69 | ```
70 |
71 | **Differific** can also be installed manually. Just download and drop `Sources` folders in your project.
72 |
73 | ## Author
74 |
75 | - Christoffer Winterkvist, christoffer@winterkvist.com
76 | - Khoa Pham, onmyway133@gmail.com
77 |
78 | ## Contributing
79 |
80 | We would love you to contribute to **Differific**, check the [CONTRIBUTING](https://github.com/zenangst/Differific/blob/master/CONTRIBUTING.md) file for more info.
81 |
82 | ## License
83 |
84 | **Differific** is available under the MIT license. See the [LICENSE](https://github.com/zenangst/Differific/blob/master/LICENSE.md) file for more info.
85 |
--------------------------------------------------------------------------------
/Tests/iOS+tvOS/UITableViewExtensionsTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | import Differific
3 |
4 | class UITableViewExtensionsTests: XCTestCase {
5 | class DataSourceMock: NSObject, UITableViewDataSource {
6 | var models = [String]()
7 |
8 | init(models: [String] = []) {
9 | self.models = models
10 | }
11 |
12 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
13 | return models.count
14 | }
15 |
16 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
17 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
18 | return cell
19 | }
20 | }
21 |
22 | func testReloadWithInsertions() {
23 | let dataSource = DataSourceMock()
24 | let tableView = UITableView()
25 | tableView.dataSource = dataSource
26 | tableView.register(UITableViewCell.self,
27 | forCellReuseIdentifier: "cell")
28 |
29 | let old = dataSource.models
30 | let new = ["Foo", "Bar", "Baz"]
31 | let manager = DiffManager()
32 | let changes = manager.diff(old, new)
33 |
34 | var ranBefore: Bool = false
35 | var ranCompletion: Bool = false
36 |
37 | tableView.reload(with: changes, updateDataSource: {
38 | dataSource.models = new
39 | ranBefore = true
40 | }) {
41 | ranCompletion = true
42 | }
43 |
44 | XCTAssertTrue(ranBefore)
45 | XCTAssertTrue(ranCompletion)
46 | }
47 |
48 | func testReloadWithMove() {
49 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
50 | let tableView = UITableView()
51 | tableView.dataSource = dataSource
52 | tableView.register(UITableViewCell.self,
53 | forCellReuseIdentifier: "cell")
54 |
55 | let old = dataSource.models
56 | let new = ["Baz", "Bar", "Foo"]
57 | let manager = DiffManager()
58 | let changes = manager.diff(old, new)
59 |
60 | var ranBefore: Bool = false
61 | var ranCompletion: Bool = false
62 |
63 | tableView.reload(with: changes, updateDataSource: {
64 | dataSource.models = new
65 | ranBefore = true
66 | }) {
67 | ranCompletion = true
68 | }
69 |
70 | XCTAssertTrue(ranBefore)
71 | XCTAssertTrue(ranCompletion)
72 | }
73 |
74 | func testReloadWithDeletions() {
75 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
76 | let tableView = UITableView()
77 | tableView.dataSource = dataSource
78 | tableView.register(UITableViewCell.self,
79 | forCellReuseIdentifier: "cell")
80 |
81 | let old = dataSource.models
82 | let new = [String]()
83 | let manager = DiffManager()
84 | let changes = manager.diff(old, new)
85 |
86 | var ranBefore: Bool = false
87 | var ranCompletion: Bool = false
88 |
89 | tableView.reload(with: changes, updateDataSource: {
90 | dataSource.models = new
91 | ranBefore = true
92 | }) {
93 | ranCompletion = true
94 | }
95 |
96 | XCTAssertTrue(ranBefore)
97 | XCTAssertTrue(ranCompletion)
98 | }
99 |
100 | func testReloadWithEmptyChanges() {
101 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
102 | let tableView = UITableView()
103 | tableView.dataSource = dataSource
104 | tableView.register(UITableViewCell.self,
105 | forCellReuseIdentifier: "cell")
106 |
107 | let old = dataSource.models
108 | let new = ["Foo", "Bar", "Baz"]
109 | let manager = DiffManager()
110 | let changes = manager.diff(old, new)
111 |
112 | var ranBefore: Bool = false
113 | var ranCompletion: Bool = false
114 |
115 | tableView.reload(with: changes, updateDataSource: {
116 | dataSource.models = new
117 | ranBefore = true
118 | }) {
119 | ranCompletion = true
120 | }
121 |
122 | XCTAssertFalse(ranBefore)
123 | XCTAssertTrue(ranCompletion)
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/Example/DifferificDemo/DifferificDemo.xcodeproj/xcshareddata/xcschemes/DifferificDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
84 |
90 |
91 |
92 |
93 |
95 |
96 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Differific.xcodeproj/xcshareddata/xcschemes/Differific-iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
65 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
84 |
90 |
91 |
92 |
93 |
95 |
96 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Differific.xcodeproj/xcshareddata/xcschemes/Differific-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
65 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
84 |
90 |
91 |
92 |
93 |
95 |
96 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Differific.xcodeproj/xcshareddata/xcschemes/Differific-macOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
48 |
54 |
55 |
56 |
57 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
79 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
98 |
104 |
105 |
106 |
107 |
109 |
110 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/Tests/iOS+tvOS/UICollectionViewExtensionsTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | import Differific
3 |
4 | class UICollectionViewExtensionsTests: XCTestCase {
5 | class DataSourceMock: NSObject, UICollectionViewDataSource {
6 | var models: [String]
7 |
8 | init(models: [String] = []) {
9 | self.models = models
10 | }
11 |
12 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
13 | return models.count
14 | }
15 |
16 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
17 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
18 | return cell
19 | }
20 | }
21 |
22 | func testReloadWithInsertions() {
23 | let dataSource = DataSourceMock(models: [])
24 | let layout = UICollectionViewFlowLayout()
25 | layout.itemSize = CGSize(width: 250, height: 250)
26 | let collectionView = UICollectionView(frame: .init(origin: .zero, size: layout.itemSize),
27 | collectionViewLayout: layout)
28 | collectionView.dataSource = dataSource
29 | collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
30 |
31 | let old = dataSource.models
32 | let new = ["Foo", "Bar", "Baz"]
33 | let manager = DiffManager()
34 | let changes = manager.diff(old, new)
35 | var ranBefore: Bool = false
36 | var ranCompletion: Bool = false
37 |
38 | collectionView.reload(with: changes, updateDataSource: {
39 | dataSource.models = new
40 | ranBefore = true
41 | }) {
42 | ranCompletion = true
43 | }
44 |
45 | XCTAssertTrue(ranBefore)
46 | XCTAssertTrue(ranCompletion)
47 | }
48 |
49 | func testReloadWithMove() {
50 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
51 | let layout = UICollectionViewFlowLayout()
52 | layout.itemSize = CGSize(width: 250, height: 250)
53 | let collectionView = UICollectionView(frame: .init(origin: .zero, size: layout.itemSize),
54 | collectionViewLayout: layout)
55 | collectionView.dataSource = dataSource
56 | collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
57 |
58 | let old = dataSource.models
59 | let new = ["Baz", "Bar", "Foo"]
60 | let manager = DiffManager()
61 | let changes = manager.diff(old, new)
62 |
63 | var ranBefore: Bool = false
64 | var ranCompletion: Bool = false
65 |
66 | collectionView.reload(with: changes, updateDataSource: {
67 | dataSource.models = new
68 | ranBefore = true
69 | }) {
70 | ranCompletion = true
71 | }
72 |
73 | XCTAssertTrue(ranBefore)
74 | XCTAssertTrue(ranCompletion)
75 | }
76 |
77 | func testReloadWithDeletions() {
78 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
79 | let layout = UICollectionViewFlowLayout()
80 | layout.itemSize = CGSize(width: 250, height: 250)
81 | let collectionView = UICollectionView(frame: .init(origin: .zero, size: layout.itemSize),
82 | collectionViewLayout: layout)
83 | collectionView.dataSource = dataSource
84 | collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
85 |
86 | let old = dataSource.models
87 | let new = [String]()
88 | let manager = DiffManager()
89 | let changes = manager.diff(old, new)
90 |
91 | var ranBefore: Bool = false
92 | var ranCompletion: Bool = false
93 |
94 | collectionView.reload(with: changes, updateDataSource: {
95 | dataSource.models = new
96 | ranBefore = true
97 | }) {
98 | ranCompletion = true
99 | }
100 |
101 | XCTAssertTrue(ranBefore)
102 | XCTAssertTrue(ranCompletion)
103 | }
104 |
105 | func testReloadWithEmptyChanges() {
106 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
107 | let layout = UICollectionViewFlowLayout()
108 | layout.itemSize = CGSize(width: 250, height: 250)
109 | let collectionView = UICollectionView(frame: .init(origin: .zero, size: layout.itemSize),
110 | collectionViewLayout: layout)
111 | collectionView.dataSource = dataSource
112 | collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
113 |
114 | let old = dataSource.models
115 | let new = ["Foo", "Bar", "Baz"]
116 | let manager = DiffManager()
117 | let changes = manager.diff(old, new)
118 |
119 | var ranBefore: Bool = false
120 | var ranCompletion: Bool = false
121 |
122 | collectionView.reload(with: changes, updateDataSource: {
123 | dataSource.models = new
124 | ranBefore = true
125 | }) {
126 | ranCompletion = true
127 | }
128 |
129 | XCTAssertFalse(ranBefore)
130 | XCTAssertTrue(ranCompletion)
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/Tests/macOS/NSCollectionViewExtensionTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | import Differific
3 |
4 | class NSCollectionViewExtensionsTests: XCTestCase {
5 | class DataSourceMock: NSObject, NSCollectionViewDataSource {
6 | var models: [String]
7 |
8 | init(models: [String] = []) {
9 | self.models = models
10 | }
11 |
12 | func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
13 | return models.count
14 | }
15 |
16 | func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
17 | let cell = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier.init("cell"), for: indexPath)
18 | return cell
19 | }
20 | }
21 |
22 | func testReloadWithInsertions() {
23 | let dataSource = DataSourceMock(models: [])
24 | let layout = NSCollectionViewFlowLayout()
25 | layout.itemSize = CGSize(width: 250, height: 250)
26 |
27 | let collectionView = NSCollectionView(frame: .init(origin: .zero, size: layout.itemSize))
28 | collectionView.collectionViewLayout = layout
29 | collectionView.dataSource = dataSource
30 | collectionView.register(NSCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier.init("cell"))
31 |
32 | let old = dataSource.models
33 | let new = ["Foo", "Bar", "Baz"]
34 | let manager = DiffManager()
35 | let changes = manager.diff(old, new)
36 | var ranBefore: Bool = false
37 | var ranCompletion: Bool = false
38 | collectionView.reload(with: changes, updateDataSource: {
39 | dataSource.models = new
40 | ranBefore = true
41 | }) {
42 | ranCompletion = true
43 | }
44 |
45 | XCTAssertTrue(ranBefore)
46 | XCTAssertTrue(ranCompletion)
47 | }
48 |
49 | func testReloadWithMove() {
50 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
51 | let layout = NSCollectionViewFlowLayout()
52 | layout.itemSize = CGSize(width: 250, height: 250)
53 | let superview = NSView()
54 | let collectionView = NSCollectionView(frame: .init(origin: .zero, size: layout.itemSize))
55 | superview.addSubview(collectionView)
56 | collectionView.collectionViewLayout = layout
57 | collectionView.dataSource = dataSource
58 | collectionView.register(NSCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier.init("cell"))
59 |
60 | let old = dataSource.models
61 | let new = ["Baz", "Bar", "Foo"]
62 | let manager = DiffManager()
63 | let changes = manager.diff(old, new)
64 |
65 | var ranBefore: Bool = false
66 | var ranCompletion: Bool = false
67 |
68 | collectionView.reload(with: changes, updateDataSource: {
69 | dataSource.models = new
70 | ranBefore = true
71 | }) {
72 | ranCompletion = true
73 | }
74 |
75 | XCTAssertTrue(ranBefore)
76 | XCTAssertTrue(ranCompletion)
77 | }
78 |
79 | func testReloadWithDeletions() {
80 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
81 | let layout = NSCollectionViewFlowLayout()
82 | layout.itemSize = CGSize(width: 250, height: 250)
83 | let superview = NSView()
84 | let collectionView = NSCollectionView(frame: .init(origin: .zero, size: layout.itemSize))
85 | superview.addSubview(collectionView)
86 | collectionView.collectionViewLayout = layout
87 | collectionView.dataSource = dataSource
88 | collectionView.register(NSCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier.init("cell"))
89 |
90 | let old = dataSource.models
91 | let new = [String]()
92 | let manager = DiffManager()
93 | let changes = manager.diff(old, new)
94 |
95 | var ranBefore: Bool = false
96 | var ranCompletion: Bool = false
97 |
98 | collectionView.reload(with: changes, updateDataSource: {
99 | dataSource.models = new
100 | ranBefore = true
101 | }) {
102 | ranCompletion = true
103 | }
104 |
105 | XCTAssertTrue(ranBefore)
106 | XCTAssertTrue(ranCompletion)
107 | }
108 |
109 | func testReloadWithEmptyChanges() {
110 | let dataSource = DataSourceMock(models: ["Foo", "Bar", "Baz"])
111 | let layout = NSCollectionViewFlowLayout()
112 | layout.itemSize = CGSize(width: 250, height: 250)
113 | let collectionView = NSCollectionView(frame: .init(origin: .zero, size: layout.itemSize))
114 | collectionView.collectionViewLayout = layout
115 | collectionView.dataSource = dataSource
116 | collectionView.register(NSCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier.init("cell"))
117 |
118 | let old = dataSource.models
119 | let new = ["Foo", "Bar", "Baz"]
120 | let manager = DiffManager()
121 | let changes = manager.diff(old, new)
122 |
123 | var ranBefore: Bool = false
124 | var ranCompletion: Bool = false
125 |
126 | collectionView.reload(with: changes, updateDataSource: {
127 | dataSource.models = new
128 | ranBefore = true
129 | }) {
130 | ranCompletion = true
131 | }
132 |
133 | XCTAssertFalse(ranBefore)
134 | XCTAssertTrue(ranCompletion)
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/Source/Shared/Algorithm.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | class Algorithm {
4 | public static func diff(old: [T], new: [T], compare: (T,T) -> Bool) -> [Change] {
5 | if new.isEmpty {
6 | var changes = [Change]()
7 | changes.reserveCapacity(old.count)
8 | for (offset, element) in old.enumerated() {
9 | changes.append(Change(.delete,
10 | item: element,
11 | index: offset))
12 | }
13 | return changes
14 | } else if old.isEmpty {
15 | var changes = [Change]()
16 | changes.reserveCapacity(new.count)
17 | for (offset, element) in new.enumerated() {
18 | changes.append(Change(.insert,
19 | item: element,
20 | index: offset))
21 | }
22 | return changes
23 | }
24 |
25 | var table = [Int: TableEntry]()
26 | var (oldArray, newArray) = ([ArrayEntry](), [ArrayEntry]())
27 | var deleteOffsets = Array(repeating: 0, count: old.count)
28 | var changes = [Change]()
29 | var (runningOffset, offset) = (0, 0)
30 |
31 | table.reserveCapacity(new.count > old.count ? new.count : old.count)
32 | changes.reserveCapacity(newArray.count + oldArray.count)
33 | newArray.reserveCapacity(new.count)
34 | oldArray.reserveCapacity(old.count)
35 |
36 | // 1 Pass
37 | for element in new[0...].lazy {
38 | let diffValue = (element as? Diffable)?.diffValue ?? element.hashValue
39 | let entry: TableEntry
40 | if let tableEntry = table[diffValue] {
41 | entry = tableEntry
42 | } else {
43 | entry = TableEntry()
44 | }
45 |
46 | table[diffValue] = entry
47 | entry.newCounter += 1
48 | newArray.append(ArrayEntry(tableEntry: entry))
49 | }
50 |
51 | // 2 Pass
52 | for element in old[0...].lazy {
53 | let diffValue = (element as? Diffable)?.diffValue ?? element.hashValue
54 | let entry: TableEntry
55 | if let tableEntry = table[diffValue] {
56 | entry = tableEntry
57 | } else {
58 | entry = TableEntry()
59 | }
60 |
61 | table[diffValue] = entry
62 | entry.oldCounter += 1
63 | entry.indexesInOld.append(offset)
64 | oldArray.append(ArrayEntry(tableEntry: entry))
65 | offset += 1
66 | }
67 |
68 | // 3rd Pass
69 | offset = 0
70 |
71 | for arrayEntry in newArray[0...].lazy {
72 | let entry = arrayEntry.tableEntry
73 | if entry.appearsInBoth && !entry.indexesInOld.isEmpty {
74 | let oldIndex = entry.indexesInOld.removeFirst()
75 | newArray[offset].indexInOther = oldIndex
76 | oldArray[oldIndex].indexInOther = offset
77 | }
78 | offset += 1
79 | }
80 |
81 | // 4th Pass
82 | offset = 1
83 |
84 | if offset < newArray.count - 1 {
85 | repeat {
86 | let tableEntry = newArray[offset]
87 | let otherIndex = tableEntry.indexInOther
88 |
89 | if otherIndex + 1 < oldArray.count {
90 | let newEntry = newArray[offset + 1]
91 | let oldEntry = oldArray[otherIndex + 1]
92 |
93 | if newEntry.tableEntry === oldEntry.tableEntry {
94 | newArray[offset + 1].indexInOther = otherIndex + 1
95 | oldArray[otherIndex + 1].indexInOther = offset + 1
96 | }
97 | }
98 | offset += 1
99 | } while offset < newArray.count - 1
100 | }
101 |
102 | // 5th Pass
103 | offset = newArray.count - 1
104 |
105 | if offset > newArray.count {
106 | let otherIndex = newArray[offset].indexInOther
107 | repeat {
108 | if otherIndex - 1 >= 0 &&
109 | newArray[offset - 1].indexInOther == -1,
110 | oldArray[otherIndex - 1].indexInOther == -1 {
111 | newArray[offset - 1].indexInOther = otherIndex - 1
112 | oldArray[otherIndex - 1].indexInOther = offset - 1
113 | }
114 | offset -= 1
115 | } while offset > 0
116 | }
117 |
118 | // Handle deleted objects
119 | offset = 0
120 | for element in oldArray[0...].lazy {
121 | deleteOffsets[offset] = runningOffset
122 |
123 | if element.indexInOther == -1 {
124 | changes.append(Change(.delete, item: old[offset], index: offset))
125 | runningOffset += 1
126 | }
127 | offset += 1
128 | }
129 |
130 | // Handle insert, updates and move.
131 | offset = 0
132 | for element in newArray[0...].lazy {
133 | if element.indexInOther < 0 {
134 | changes.append(Change(.insert,
135 | item: new[offset],
136 | index: offset))
137 | runningOffset += 1
138 | } else {
139 | let oldIndex = element.indexInOther
140 | if !compare(old[oldIndex], new[offset]) {
141 | changes.append(Change(.update,
142 | item: old[oldIndex],
143 | index: oldIndex,
144 | newIndex: offset,
145 | newItem: new[offset]))
146 | } else {
147 | let deleteOffset = deleteOffsets[oldIndex]
148 | if (oldIndex - deleteOffset + runningOffset) != offset,
149 | oldIndex != offset {
150 | changes.append(Change(.move,
151 | item: new[offset],
152 | index: oldIndex,
153 | newIndex: offset))
154 | }
155 | }
156 |
157 | }
158 | offset += 1
159 | }
160 |
161 | return changes
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/Tests/Shared/DiffManagerTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | import Differific
3 |
4 | class DiffManagerTests: XCTestCase {
5 | struct MockDiffable: Hashable, Diffable {
6 | let id: Int
7 | var diffValue: Int {
8 | return id
9 | }
10 | }
11 |
12 | struct MockObject: Hashable {
13 | let id: Int
14 | let name: String
15 | func hash(into hasher: inout Hasher) {
16 | hasher.combine(id.hashValue)
17 | }
18 | }
19 |
20 | let manager = DiffManager()
21 |
22 | func testEmptyDiff() {
23 | let old = [String]()
24 | let new = [String]()
25 | let result = manager.diff(old, new)
26 |
27 | XCTAssertTrue(result.isEmpty)
28 | }
29 |
30 | func testInsert() {
31 | let old = [String]()
32 | let new = ["Foo", "Bar", "Baz"]
33 | let result = manager.diff(old, new)
34 |
35 | XCTAssertEqual(result.count, 3)
36 |
37 | XCTAssertEqual(result[0].kind, .insert)
38 | XCTAssertEqual(result[0].item, "Foo")
39 | XCTAssertEqual(result[0].index, 0)
40 |
41 | XCTAssertEqual(result[1].kind, .insert)
42 | XCTAssertEqual(result[1].item, "Bar")
43 | XCTAssertEqual(result[1].index, 1)
44 |
45 | XCTAssertEqual(result[2].kind, .insert)
46 | XCTAssertEqual(result[2].item, "Baz")
47 | XCTAssertEqual(result[2].index, 2)
48 | }
49 |
50 | func testDelete() {
51 | let old = ["Foo", "Bar", "Baz"]
52 | let new = [String]()
53 | let result = manager.diff(old, new)
54 |
55 | XCTAssertEqual(result.count, 3)
56 |
57 | XCTAssertEqual(result[0].kind, .delete)
58 | XCTAssertEqual(result[0].item, "Foo")
59 | XCTAssertEqual(result[0].index, 0)
60 |
61 | XCTAssertEqual(result[1].kind, .delete)
62 | XCTAssertEqual(result[1].item, "Bar")
63 | XCTAssertEqual(result[1].index, 1)
64 |
65 | XCTAssertEqual(result[2].kind, .delete)
66 | XCTAssertEqual(result[2].item, "Baz")
67 | XCTAssertEqual(result[2].index, 2)
68 | }
69 |
70 | func testMove() {
71 | let old = ["Foo", "Bar", "Baz"]
72 | let new = Array(old.reversed())
73 | let result = manager.diff(old, new)
74 |
75 | XCTAssertEqual(result.count, 2)
76 |
77 | XCTAssertEqual(result[0].kind, .move)
78 | XCTAssertEqual(result[0].item, "Baz")
79 | XCTAssertEqual(result[0].index, 2)
80 | XCTAssertEqual(result[0].newIndex, 0)
81 |
82 | XCTAssertEqual(result[1].kind, .move)
83 | XCTAssertEqual(result[1].item, "Foo")
84 | XCTAssertEqual(result[1].index, 0)
85 | XCTAssertEqual(result[1].newIndex, 2)
86 | }
87 |
88 | func testNoChange() {
89 | let old = ["Foo", "Bar", "Baz"]
90 | let new = ["Foo", "Bar", "Baz"]
91 | let result = manager.diff(old, new)
92 |
93 | XCTAssertTrue(result.isEmpty)
94 | }
95 |
96 | func testReplacing() {
97 | let old = [
98 | MockObject(id: 0, name: "Foo"),
99 | MockObject(id: 1, name: "Bar"),
100 | MockObject(id: 2, name: "Baz")
101 | ]
102 | let new = [
103 | MockObject(id: 0, name: "Foo0"),
104 | MockObject(id: 1, name: "Bar1"),
105 | MockObject(id: 2, name: "Baz2")
106 | ]
107 | let result = manager.diff(old, new)
108 |
109 | XCTAssertEqual(result.count, 3)
110 |
111 | XCTAssertEqual(result[0].kind, .update)
112 | XCTAssertEqual(result[0].item, MockObject(id: 0, name: "Foo"))
113 | XCTAssertEqual(result[0].newItem, MockObject(id: 0, name: "Foo0"))
114 | XCTAssertEqual(result[0].index, 0)
115 |
116 | XCTAssertEqual(result[1].kind, .update)
117 | XCTAssertEqual(result[1].item, MockObject(id: 1, name: "Bar"))
118 | XCTAssertEqual(result[1].newItem, MockObject(id: 1, name: "Bar1"))
119 | XCTAssertEqual(result[1].index, 1)
120 |
121 | XCTAssertEqual(result[2].kind, .update)
122 | XCTAssertEqual(result[2].item, MockObject(id: 2, name: "Baz"))
123 | XCTAssertEqual(result[2].newItem, MockObject(id: 2, name: "Baz2"))
124 | XCTAssertEqual(result[2].index, 2)
125 |
126 | }
127 |
128 | func testDiffing() {
129 | let old = [
130 | MockObject(id: 0, name: "Eirik"),
131 | MockObject(id: 1, name: "Markus"),
132 | MockObject(id: 2, name: "Andreas")
133 | ]
134 | let new = [
135 | MockObject(id: 3, name: "Eirik P"),
136 | MockObject(id: 0, name: "Eirik N"),
137 | MockObject(id: 1, name: "Markus"),
138 | MockObject(id: 4, name: "Chris")
139 | ]
140 | let result = manager.diff(old, new)
141 |
142 | XCTAssertEqual(result[0].kind, .delete)
143 | XCTAssertEqual(result[0].item, MockObject(id: 2, name: "Andreas"))
144 |
145 | XCTAssertEqual(result[1].kind, .insert)
146 | XCTAssertEqual(result[1].item, MockObject(id: 3, name: "Eirik P"))
147 |
148 | XCTAssertEqual(result[2].kind, .update)
149 | XCTAssertEqual(result[2].item, MockObject(id: 0, name: "Eirik"))
150 |
151 | XCTAssertEqual(result[3].kind, .move)
152 | XCTAssertEqual(result[3].item, MockObject(id: 1, name: "Markus"))
153 |
154 | XCTAssertEqual(result[4].kind, .insert)
155 | XCTAssertEqual(result[4].item, MockObject(id: 4, name: "Chris"))
156 |
157 | XCTAssertEqual(result.count, 5)
158 | }
159 |
160 | func testComparator() {
161 | let old = [
162 | MockObject(id: 0, name: "Foo"),
163 | MockObject(id: 1, name: "Bar"),
164 | MockObject(id: 2, name: "Baz")
165 | ]
166 | let new = [
167 | MockObject(id: 1, name: "Foo0"),
168 | MockObject(id: 0, name: "Bar1"),
169 | MockObject(id: 3, name: "Baz2")
170 | ]
171 |
172 | let diffManager = DiffManager()
173 | let changes = diffManager.diff(old, new, compare: { $0.id == $1.id })
174 |
175 | XCTAssertEqual(changes[0].kind, .delete)
176 | XCTAssertEqual(changes[1].kind, .move)
177 | XCTAssertEqual(changes[2].kind, .insert)
178 | }
179 |
180 | func testDiffable() {
181 | let old = [
182 | MockDiffable(id: 0),
183 | MockDiffable(id: 1),
184 | MockDiffable(id: 2)
185 | ]
186 |
187 | let new = [
188 | MockDiffable(id: 1),
189 | MockDiffable(id: 0),
190 | MockDiffable(id: 3)
191 | ]
192 |
193 | let diffManager = DiffManager()
194 | let changes = diffManager.diff(old, new)
195 |
196 | XCTAssertEqual(changes[0].kind, .delete)
197 | XCTAssertEqual(changes[1].kind, .move)
198 | XCTAssertEqual(changes[2].kind, .insert)
199 | }
200 |
201 | func testPerformance() {
202 | let diffManager = DiffManager()
203 | var old = [Int]()
204 | var new = [Int]()
205 | let amount = 1_000_000
206 |
207 | new.reserveCapacity(amount)
208 | old.reserveCapacity(amount)
209 |
210 | for x in 0.. /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
196 | showEnvVarsInLog = 0;
197 | };
198 | /* End PBXShellScriptBuildPhase section */
199 |
200 | /* Begin PBXSourcesBuildPhase section */
201 | D5C7F73C1C3BC9CE008CDDBA /* Sources */ = {
202 | isa = PBXSourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | D5C7F75D1C3BCA1E008CDDBA /* ViewController.swift in Sources */,
206 | D5C7F75C1C3BCA1E008CDDBA /* AppDelegate.swift in Sources */,
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | };
210 | /* End PBXSourcesBuildPhase section */
211 |
212 | /* Begin PBXVariantGroup section */
213 | D5C7F74C1C3BC9CE008CDDBA /* LaunchScreen.storyboard */ = {
214 | isa = PBXVariantGroup;
215 | children = (
216 | D5C7F74D1C3BC9CE008CDDBA /* Base */,
217 | );
218 | name = LaunchScreen.storyboard;
219 | sourceTree = "";
220 | };
221 | /* End PBXVariantGroup section */
222 |
223 | /* Begin XCBuildConfiguration section */
224 | D5C7F7501C3BC9CE008CDDBA /* Debug */ = {
225 | isa = XCBuildConfiguration;
226 | buildSettings = {
227 | ALWAYS_SEARCH_USER_PATHS = NO;
228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
229 | CLANG_CXX_LIBRARY = "libc++";
230 | CLANG_ENABLE_MODULES = YES;
231 | CLANG_ENABLE_OBJC_ARC = YES;
232 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
233 | CLANG_WARN_BOOL_CONVERSION = YES;
234 | CLANG_WARN_COMMA = YES;
235 | CLANG_WARN_CONSTANT_CONVERSION = YES;
236 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
237 | CLANG_WARN_EMPTY_BODY = YES;
238 | CLANG_WARN_ENUM_CONVERSION = YES;
239 | CLANG_WARN_INFINITE_RECURSION = YES;
240 | CLANG_WARN_INT_CONVERSION = YES;
241 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
242 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
243 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
244 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
245 | CLANG_WARN_STRICT_PROTOTYPES = YES;
246 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
247 | CLANG_WARN_UNREACHABLE_CODE = YES;
248 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
249 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
250 | COPY_PHASE_STRIP = NO;
251 | DEBUG_INFORMATION_FORMAT = dwarf;
252 | ENABLE_STRICT_OBJC_MSGSEND = YES;
253 | ENABLE_TESTABILITY = YES;
254 | GCC_C_LANGUAGE_STANDARD = gnu99;
255 | GCC_DYNAMIC_NO_PIC = NO;
256 | GCC_NO_COMMON_BLOCKS = YES;
257 | GCC_OPTIMIZATION_LEVEL = 0;
258 | GCC_PREPROCESSOR_DEFINITIONS = (
259 | "DEBUG=1",
260 | "$(inherited)",
261 | );
262 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
263 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
264 | GCC_WARN_UNDECLARED_SELECTOR = YES;
265 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
266 | GCC_WARN_UNUSED_FUNCTION = YES;
267 | GCC_WARN_UNUSED_VARIABLE = YES;
268 | IPHONEOS_DEPLOYMENT_TARGET = 9.2;
269 | MTL_ENABLE_DEBUG_INFO = YES;
270 | ONLY_ACTIVE_ARCH = YES;
271 | SDKROOT = iphoneos;
272 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
273 | SWIFT_VERSION = 4.0;
274 | };
275 | name = Debug;
276 | };
277 | D5C7F7511C3BC9CE008CDDBA /* Release */ = {
278 | isa = XCBuildConfiguration;
279 | buildSettings = {
280 | ALWAYS_SEARCH_USER_PATHS = NO;
281 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
282 | CLANG_CXX_LIBRARY = "libc++";
283 | CLANG_ENABLE_MODULES = YES;
284 | CLANG_ENABLE_OBJC_ARC = YES;
285 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
286 | CLANG_WARN_BOOL_CONVERSION = YES;
287 | CLANG_WARN_COMMA = YES;
288 | CLANG_WARN_CONSTANT_CONVERSION = YES;
289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
290 | CLANG_WARN_EMPTY_BODY = YES;
291 | CLANG_WARN_ENUM_CONVERSION = YES;
292 | CLANG_WARN_INFINITE_RECURSION = YES;
293 | CLANG_WARN_INT_CONVERSION = YES;
294 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
295 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
296 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
297 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
298 | CLANG_WARN_STRICT_PROTOTYPES = YES;
299 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
300 | CLANG_WARN_UNREACHABLE_CODE = YES;
301 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
302 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
303 | COPY_PHASE_STRIP = NO;
304 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
305 | ENABLE_NS_ASSERTIONS = NO;
306 | ENABLE_STRICT_OBJC_MSGSEND = YES;
307 | GCC_C_LANGUAGE_STANDARD = gnu99;
308 | GCC_NO_COMMON_BLOCKS = YES;
309 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
310 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
311 | GCC_WARN_UNDECLARED_SELECTOR = YES;
312 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
313 | GCC_WARN_UNUSED_FUNCTION = YES;
314 | GCC_WARN_UNUSED_VARIABLE = YES;
315 | IPHONEOS_DEPLOYMENT_TARGET = 9.2;
316 | MTL_ENABLE_DEBUG_INFO = NO;
317 | SDKROOT = iphoneos;
318 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
319 | SWIFT_VERSION = 4.0;
320 | VALIDATE_PRODUCT = YES;
321 | };
322 | name = Release;
323 | };
324 | D5C7F7531C3BC9CE008CDDBA /* Debug */ = {
325 | isa = XCBuildConfiguration;
326 | baseConfigurationReference = B763EF95B0B941F40D3AC8B2 /* Pods-DifferificDemo.debug.xcconfig */;
327 | buildSettings = {
328 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
329 | INFOPLIST_FILE = DifferificDemo/Info.plist;
330 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
331 | PRODUCT_BUNDLE_IDENTIFIER = com.zenangst.DifferificDemo;
332 | PRODUCT_NAME = "$(TARGET_NAME)";
333 | };
334 | name = Debug;
335 | };
336 | D5C7F7541C3BC9CE008CDDBA /* Release */ = {
337 | isa = XCBuildConfiguration;
338 | baseConfigurationReference = C196AB212A5242CACF6780D7 /* Pods-DifferificDemo.release.xcconfig */;
339 | buildSettings = {
340 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
341 | INFOPLIST_FILE = DifferificDemo/Info.plist;
342 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
343 | PRODUCT_BUNDLE_IDENTIFIER = com.zenangst.DifferificDemo;
344 | PRODUCT_NAME = "$(TARGET_NAME)";
345 | };
346 | name = Release;
347 | };
348 | /* End XCBuildConfiguration section */
349 |
350 | /* Begin XCConfigurationList section */
351 | D5C7F73B1C3BC9CE008CDDBA /* Build configuration list for PBXProject "DifferificDemo" */ = {
352 | isa = XCConfigurationList;
353 | buildConfigurations = (
354 | D5C7F7501C3BC9CE008CDDBA /* Debug */,
355 | D5C7F7511C3BC9CE008CDDBA /* Release */,
356 | );
357 | defaultConfigurationIsVisible = 0;
358 | defaultConfigurationName = Release;
359 | };
360 | D5C7F7521C3BC9CE008CDDBA /* Build configuration list for PBXNativeTarget "DifferificDemo" */ = {
361 | isa = XCConfigurationList;
362 | buildConfigurations = (
363 | D5C7F7531C3BC9CE008CDDBA /* Debug */,
364 | D5C7F7541C3BC9CE008CDDBA /* Release */,
365 | );
366 | defaultConfigurationIsVisible = 0;
367 | defaultConfigurationName = Release;
368 | };
369 | /* End XCConfigurationList section */
370 | };
371 | rootObject = D5C7F7381C3BC9CE008CDDBA /* Project object */;
372 | }
373 |
--------------------------------------------------------------------------------
/Differific.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | BD690D4820DC13F700E56E30 /* Counter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4720DC13F700E56E30 /* Counter.swift */; };
11 | BD690D4920DC13F700E56E30 /* Counter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4720DC13F700E56E30 /* Counter.swift */; };
12 | BD690D4A20DC13F700E56E30 /* Counter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4720DC13F700E56E30 /* Counter.swift */; };
13 | BD690D4C20DC141200E56E30 /* TableEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4B20DC141200E56E30 /* TableEntry.swift */; };
14 | BD690D4D20DC141200E56E30 /* TableEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4B20DC141200E56E30 /* TableEntry.swift */; };
15 | BD690D4E20DC141200E56E30 /* TableEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4B20DC141200E56E30 /* TableEntry.swift */; };
16 | BD690D5020DC143100E56E30 /* ArrayEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4F20DC143100E56E30 /* ArrayEntry.swift */; };
17 | BD690D5120DC143100E56E30 /* ArrayEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4F20DC143100E56E30 /* ArrayEntry.swift */; };
18 | BD690D5220DC143100E56E30 /* ArrayEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD690D4F20DC143100E56E30 /* ArrayEntry.swift */; };
19 | BDBF80B920923FB90002CE93 /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80B720923FB90002CE93 /* UITableView+Extensions.swift */; };
20 | BDBF80BA20923FB90002CE93 /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80B720923FB90002CE93 /* UITableView+Extensions.swift */; };
21 | BDBF80BB20923FB90002CE93 /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80B820923FB90002CE93 /* UICollectionView+Extensions.swift */; };
22 | BDBF80BC20923FB90002CE93 /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80B820923FB90002CE93 /* UICollectionView+Extensions.swift */; };
23 | BDBF80C720923FD00002CE93 /* DiffManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C320923FD00002CE93 /* DiffManager.swift */; };
24 | BDBF80C820923FD00002CE93 /* DiffManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C320923FD00002CE93 /* DiffManager.swift */; };
25 | BDBF80C920923FD00002CE93 /* DiffManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C320923FD00002CE93 /* DiffManager.swift */; };
26 | BDBF80CA20923FD00002CE93 /* Change.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C420923FD00002CE93 /* Change.swift */; };
27 | BDBF80CB20923FD00002CE93 /* Change.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C420923FD00002CE93 /* Change.swift */; };
28 | BDBF80CC20923FD00002CE93 /* Change.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C420923FD00002CE93 /* Change.swift */; };
29 | BDBF80CD20923FD00002CE93 /* IndexPathManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C520923FD00002CE93 /* IndexPathManager.swift */; };
30 | BDBF80CE20923FD00002CE93 /* IndexPathManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C520923FD00002CE93 /* IndexPathManager.swift */; };
31 | BDBF80CF20923FD00002CE93 /* IndexPathManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C520923FD00002CE93 /* IndexPathManager.swift */; };
32 | BDBF80D020923FD00002CE93 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C620923FD00002CE93 /* Algorithm.swift */; };
33 | BDBF80D120923FD00002CE93 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C620923FD00002CE93 /* Algorithm.swift */; };
34 | BDBF80D220923FD00002CE93 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80C620923FD00002CE93 /* Algorithm.swift */; };
35 | BDBF80D720923FFA0002CE93 /* NSCollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80BD20923FC10002CE93 /* NSCollectionView+Extensions.swift */; };
36 | BDBF80D820923FFA0002CE93 /* NSTableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80BE20923FC10002CE93 /* NSTableView+Extensions.swift */; };
37 | BDBF80DA209240110002CE93 /* DiffManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80D9209240110002CE93 /* DiffManagerTests.swift */; };
38 | BDBF80DB209240110002CE93 /* DiffManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80D9209240110002CE93 /* DiffManagerTests.swift */; };
39 | BDBF80DC209240110002CE93 /* DiffManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80D9209240110002CE93 /* DiffManagerTests.swift */; };
40 | BDBF80DE20924D880002CE93 /* IndexPathManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80DD20924D880002CE93 /* IndexPathManagerTests.swift */; };
41 | BDBF80DF20924D880002CE93 /* IndexPathManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80DD20924D880002CE93 /* IndexPathManagerTests.swift */; };
42 | BDBF80E020924D880002CE93 /* IndexPathManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80DD20924D880002CE93 /* IndexPathManagerTests.swift */; };
43 | BDBF80E2209250140002CE93 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80E1209250140002CE93 /* UITableViewExtensionsTests.swift */; };
44 | BDBF80E4209250140002CE93 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80E1209250140002CE93 /* UITableViewExtensionsTests.swift */; };
45 | BDBF80E6209252440002CE93 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80E5209252440002CE93 /* UICollectionViewExtensionsTests.swift */; };
46 | BDBF80E8209252440002CE93 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80E5209252440002CE93 /* UICollectionViewExtensionsTests.swift */; };
47 | BDBF80EA20927B080002CE93 /* NSCollectionViewExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80E920927B080002CE93 /* NSCollectionViewExtensionTests.swift */; };
48 | BDBF80EC20927B360002CE93 /* NSTableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBF80EB20927B360002CE93 /* NSTableViewExtensionsTests.swift */; };
49 | BDED0DC8222C57A800D7B46E /* Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDED0DC7222C57A800D7B46E /* Diffable.swift */; };
50 | BDED0DC9222C57A800D7B46E /* Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDED0DC7222C57A800D7B46E /* Diffable.swift */; };
51 | BDED0DCA222C57A800D7B46E /* Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDED0DC7222C57A800D7B46E /* Diffable.swift */; };
52 | D284B1051F79038B00D94AF3 /* Differific.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D284B0FC1F79038B00D94AF3 /* Differific.framework */; };
53 | D284B1381F7906DB00D94AF3 /* Info-iOS-Tests.plist in Resources */ = {isa = PBXBuildFile; fileRef = D284B12F1F7906DA00D94AF3 /* Info-iOS-Tests.plist */; };
54 | D284B1391F7906DB00D94AF3 /* Info-tvOS-Tests.plist in Resources */ = {isa = PBXBuildFile; fileRef = D284B1301F7906DA00D94AF3 /* Info-tvOS-Tests.plist */; };
55 | D284B13B1F7906DB00D94AF3 /* Info-macOS-Tests.plist in Resources */ = {isa = PBXBuildFile; fileRef = D284B1331F7906DA00D94AF3 /* Info-macOS-Tests.plist */; };
56 | D5B2E8AA1C3A780C00C0327D /* Differific.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5B2E89F1C3A780C00C0327D /* Differific.framework */; };
57 | D5C6294A1C3A7FAA007F7B7C /* Differific.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5C629401C3A7FAA007F7B7C /* Differific.framework */; };
58 | /* End PBXBuildFile section */
59 |
60 | /* Begin PBXContainerItemProxy section */
61 | D284B1061F79038B00D94AF3 /* PBXContainerItemProxy */ = {
62 | isa = PBXContainerItemProxy;
63 | containerPortal = D5B2E8961C3A780C00C0327D /* Project object */;
64 | proxyType = 1;
65 | remoteGlobalIDString = D284B0FB1F79038B00D94AF3;
66 | remoteInfo = "Differific-tvOS";
67 | };
68 | D5B2E8AB1C3A780C00C0327D /* PBXContainerItemProxy */ = {
69 | isa = PBXContainerItemProxy;
70 | containerPortal = D5B2E8961C3A780C00C0327D /* Project object */;
71 | proxyType = 1;
72 | remoteGlobalIDString = D5B2E89E1C3A780C00C0327D;
73 | remoteInfo = Differific;
74 | };
75 | D5C6294B1C3A7FAA007F7B7C /* PBXContainerItemProxy */ = {
76 | isa = PBXContainerItemProxy;
77 | containerPortal = D5B2E8961C3A780C00C0327D /* Project object */;
78 | proxyType = 1;
79 | remoteGlobalIDString = D5C6293F1C3A7FAA007F7B7C;
80 | remoteInfo = "Differific-Mac";
81 | };
82 | /* End PBXContainerItemProxy section */
83 |
84 | /* Begin PBXFileReference section */
85 | BD2875752092EA56002AB5C3 /* Differific.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = Differific.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
86 | BD690D4720DC13F700E56E30 /* Counter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Counter.swift; sourceTree = ""; };
87 | BD690D4B20DC141200E56E30 /* TableEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableEntry.swift; sourceTree = ""; };
88 | BD690D4F20DC143100E56E30 /* ArrayEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayEntry.swift; sourceTree = ""; };
89 | BD7221D42094863A00D28B9C /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; };
90 | BD7221D52094885300D28B9C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
91 | BDBF80B720923FB90002CE93 /* UITableView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Extensions.swift"; sourceTree = ""; };
92 | BDBF80B820923FB90002CE93 /* UICollectionView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Extensions.swift"; sourceTree = ""; };
93 | BDBF80BD20923FC10002CE93 /* NSCollectionView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSCollectionView+Extensions.swift"; sourceTree = ""; };
94 | BDBF80BE20923FC10002CE93 /* NSTableView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTableView+Extensions.swift"; sourceTree = ""; };
95 | BDBF80C320923FD00002CE93 /* DiffManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiffManager.swift; sourceTree = ""; };
96 | BDBF80C420923FD00002CE93 /* Change.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Change.swift; sourceTree = ""; };
97 | BDBF80C520923FD00002CE93 /* IndexPathManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndexPathManager.swift; sourceTree = ""; };
98 | BDBF80C620923FD00002CE93 /* Algorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = ""; };
99 | BDBF80D9209240110002CE93 /* DiffManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiffManagerTests.swift; sourceTree = ""; };
100 | BDBF80DD20924D880002CE93 /* IndexPathManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndexPathManagerTests.swift; sourceTree = ""; };
101 | BDBF80E1209250140002CE93 /* UITableViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewExtensionsTests.swift; sourceTree = ""; };
102 | BDBF80E5209252440002CE93 /* UICollectionViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensionsTests.swift; sourceTree = ""; };
103 | BDBF80E920927B080002CE93 /* NSCollectionViewExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSCollectionViewExtensionTests.swift; sourceTree = ""; };
104 | BDBF80EB20927B360002CE93 /* NSTableViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSTableViewExtensionsTests.swift; sourceTree = ""; };
105 | BDED0DC7222C57A800D7B46E /* Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Diffable.swift; sourceTree = ""; };
106 | BDED0DCB222C5FC000D7B46E /* codecov.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = codecov.yml; sourceTree = ""; };
107 | D284B0FC1F79038B00D94AF3 /* Differific.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Differific.framework; sourceTree = BUILT_PRODUCTS_DIR; };
108 | D284B1041F79038B00D94AF3 /* Differific-tvOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Differific-tvOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
109 | D284B1181F79039F00D94AF3 /* Differific.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Differific.framework; sourceTree = BUILT_PRODUCTS_DIR; };
110 | D284B12F1F7906DA00D94AF3 /* Info-iOS-Tests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS-Tests.plist"; sourceTree = ""; };
111 | D284B1301F7906DA00D94AF3 /* Info-tvOS-Tests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS-Tests.plist"; sourceTree = ""; };
112 | D284B1331F7906DA00D94AF3 /* Info-macOS-Tests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-macOS-Tests.plist"; sourceTree = ""; };
113 | D284B1401F79081F00D94AF3 /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; };
114 | D284B1411F79081F00D94AF3 /* Info-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = ""; };
115 | D284B1421F79081F00D94AF3 /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; };
116 | D284B1431F79081F00D94AF3 /* Info-watchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; };
117 | D500FD111C3AABED00782D78 /* Playground-iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = "Playground-iOS.playground"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
118 | D500FD121C3AAC8E00782D78 /* Playground-macOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = "Playground-macOS.playground"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
119 | D5B2E89F1C3A780C00C0327D /* Differific.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Differific.framework; sourceTree = BUILT_PRODUCTS_DIR; };
120 | D5B2E8A91C3A780C00C0327D /* Differific-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Differific-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
121 | D5C629401C3A7FAA007F7B7C /* Differific.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Differific.framework; sourceTree = BUILT_PRODUCTS_DIR; };
122 | D5C629491C3A7FAA007F7B7C /* Differific-macOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Differific-macOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
123 | /* End PBXFileReference section */
124 |
125 | /* Begin PBXFrameworksBuildPhase section */
126 | D284B0F81F79038B00D94AF3 /* Frameworks */ = {
127 | isa = PBXFrameworksBuildPhase;
128 | buildActionMask = 2147483647;
129 | files = (
130 | );
131 | runOnlyForDeploymentPostprocessing = 0;
132 | };
133 | D284B1011F79038B00D94AF3 /* Frameworks */ = {
134 | isa = PBXFrameworksBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | D284B1051F79038B00D94AF3 /* Differific.framework in Frameworks */,
138 | );
139 | runOnlyForDeploymentPostprocessing = 0;
140 | };
141 | D284B1141F79039F00D94AF3 /* Frameworks */ = {
142 | isa = PBXFrameworksBuildPhase;
143 | buildActionMask = 2147483647;
144 | files = (
145 | );
146 | runOnlyForDeploymentPostprocessing = 0;
147 | };
148 | D5B2E89B1C3A780C00C0327D /* Frameworks */ = {
149 | isa = PBXFrameworksBuildPhase;
150 | buildActionMask = 2147483647;
151 | files = (
152 | );
153 | runOnlyForDeploymentPostprocessing = 0;
154 | };
155 | D5B2E8A61C3A780C00C0327D /* Frameworks */ = {
156 | isa = PBXFrameworksBuildPhase;
157 | buildActionMask = 2147483647;
158 | files = (
159 | D5B2E8AA1C3A780C00C0327D /* Differific.framework in Frameworks */,
160 | );
161 | runOnlyForDeploymentPostprocessing = 0;
162 | };
163 | D5C6293C1C3A7FAA007F7B7C /* Frameworks */ = {
164 | isa = PBXFrameworksBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | );
168 | runOnlyForDeploymentPostprocessing = 0;
169 | };
170 | D5C629461C3A7FAA007F7B7C /* Frameworks */ = {
171 | isa = PBXFrameworksBuildPhase;
172 | buildActionMask = 2147483647;
173 | files = (
174 | D5C6294A1C3A7FAA007F7B7C /* Differific.framework in Frameworks */,
175 | );
176 | runOnlyForDeploymentPostprocessing = 0;
177 | };
178 | /* End PBXFrameworksBuildPhase section */
179 |
180 | /* Begin PBXGroup section */
181 | D284B0F41F79024300D94AF3 /* macOS */ = {
182 | isa = PBXGroup;
183 | children = (
184 | BDBF80BD20923FC10002CE93 /* NSCollectionView+Extensions.swift */,
185 | BDBF80BE20923FC10002CE93 /* NSTableView+Extensions.swift */,
186 | );
187 | path = macOS;
188 | sourceTree = "";
189 | };
190 | D284B1211F79041300D94AF3 /* watchOS */ = {
191 | isa = PBXGroup;
192 | children = (
193 | );
194 | path = watchOS;
195 | sourceTree = "";
196 | };
197 | D284B12D1F7906DA00D94AF3 /* macOS */ = {
198 | isa = PBXGroup;
199 | children = (
200 | BDBF80E920927B080002CE93 /* NSCollectionViewExtensionTests.swift */,
201 | BDBF80EB20927B360002CE93 /* NSTableViewExtensionsTests.swift */,
202 | );
203 | path = macOS;
204 | sourceTree = "";
205 | };
206 | D284B1311F7906DA00D94AF3 /* Shared */ = {
207 | isa = PBXGroup;
208 | children = (
209 | BDBF80D9209240110002CE93 /* DiffManagerTests.swift */,
210 | BDBF80DD20924D880002CE93 /* IndexPathManagerTests.swift */,
211 | );
212 | path = Shared;
213 | sourceTree = "";
214 | };
215 | D284B1351F7906DA00D94AF3 /* iOS+tvOS */ = {
216 | isa = PBXGroup;
217 | children = (
218 | BDBF80E1209250140002CE93 /* UITableViewExtensionsTests.swift */,
219 | BDBF80E5209252440002CE93 /* UICollectionViewExtensionsTests.swift */,
220 | );
221 | path = "iOS+tvOS";
222 | sourceTree = "";
223 | };
224 | D284B13F1F79081F00D94AF3 /* Info */ = {
225 | isa = PBXGroup;
226 | children = (
227 | D284B1401F79081F00D94AF3 /* Info-iOS.plist */,
228 | D284B1411F79081F00D94AF3 /* Info-macOS.plist */,
229 | D284B1421F79081F00D94AF3 /* Info-tvOS.plist */,
230 | D284B1431F79081F00D94AF3 /* Info-watchOS.plist */,
231 | );
232 | path = Info;
233 | sourceTree = "";
234 | };
235 | D5B2E8951C3A780C00C0327D = {
236 | isa = PBXGroup;
237 | children = (
238 | BD7221D42094863A00D28B9C /* .travis.yml */,
239 | BDED0DCB222C5FC000D7B46E /* codecov.yml */,
240 | BD2875752092EA56002AB5C3 /* Differific.podspec */,
241 | D284B13F1F79081F00D94AF3 /* Info */,
242 | D500FD111C3AABED00782D78 /* Playground-iOS.playground */,
243 | D500FD121C3AAC8E00782D78 /* Playground-macOS.playground */,
244 | D5B2E8A01C3A780C00C0327D /* Products */,
245 | BD7221D52094885300D28B9C /* README.md */,
246 | D5C629691C3A809D007F7B7C /* Source */,
247 | D5C6298F1C3A8BDA007F7B7C /* Tests */,
248 | );
249 | sourceTree = "";
250 | };
251 | D5B2E8A01C3A780C00C0327D /* Products */ = {
252 | isa = PBXGroup;
253 | children = (
254 | D5B2E89F1C3A780C00C0327D /* Differific.framework */,
255 | D5B2E8A91C3A780C00C0327D /* Differific-iOS-Tests.xctest */,
256 | D5C629401C3A7FAA007F7B7C /* Differific.framework */,
257 | D5C629491C3A7FAA007F7B7C /* Differific-macOS-Tests.xctest */,
258 | D284B0FC1F79038B00D94AF3 /* Differific.framework */,
259 | D284B1041F79038B00D94AF3 /* Differific-tvOS-Tests.xctest */,
260 | D284B1181F79039F00D94AF3 /* Differific.framework */,
261 | );
262 | name = Products;
263 | sourceTree = "";
264 | };
265 | D5C629691C3A809D007F7B7C /* Source */ = {
266 | isa = PBXGroup;
267 | children = (
268 | D5C6296A1C3A809D007F7B7C /* iOS+tvOS */,
269 | D284B0F41F79024300D94AF3 /* macOS */,
270 | D5C6296E1C3A809D007F7B7C /* Shared */,
271 | D284B1211F79041300D94AF3 /* watchOS */,
272 | );
273 | path = Source;
274 | sourceTree = "";
275 | };
276 | D5C6296A1C3A809D007F7B7C /* iOS+tvOS */ = {
277 | isa = PBXGroup;
278 | children = (
279 | BDBF80B820923FB90002CE93 /* UICollectionView+Extensions.swift */,
280 | BDBF80B720923FB90002CE93 /* UITableView+Extensions.swift */,
281 | );
282 | path = "iOS+tvOS";
283 | sourceTree = "";
284 | };
285 | D5C6296E1C3A809D007F7B7C /* Shared */ = {
286 | isa = PBXGroup;
287 | children = (
288 | BDBF80C620923FD00002CE93 /* Algorithm.swift */,
289 | BD690D4F20DC143100E56E30 /* ArrayEntry.swift */,
290 | BDBF80C420923FD00002CE93 /* Change.swift */,
291 | BD690D4720DC13F700E56E30 /* Counter.swift */,
292 | BDED0DC7222C57A800D7B46E /* Diffable.swift */,
293 | BDBF80C320923FD00002CE93 /* DiffManager.swift */,
294 | BDBF80C520923FD00002CE93 /* IndexPathManager.swift */,
295 | BD690D4B20DC141200E56E30 /* TableEntry.swift */,
296 | );
297 | path = Shared;
298 | sourceTree = "";
299 | };
300 | D5C6298F1C3A8BDA007F7B7C /* Tests */ = {
301 | isa = PBXGroup;
302 | children = (
303 | D284B12F1F7906DA00D94AF3 /* Info-iOS-Tests.plist */,
304 | D284B1331F7906DA00D94AF3 /* Info-macOS-Tests.plist */,
305 | D284B1301F7906DA00D94AF3 /* Info-tvOS-Tests.plist */,
306 | D284B1351F7906DA00D94AF3 /* iOS+tvOS */,
307 | D284B12D1F7906DA00D94AF3 /* macOS */,
308 | D284B1311F7906DA00D94AF3 /* Shared */,
309 | );
310 | path = Tests;
311 | sourceTree = "";
312 | };
313 | /* End PBXGroup section */
314 |
315 | /* Begin PBXHeadersBuildPhase section */
316 | D284B0F91F79038B00D94AF3 /* Headers */ = {
317 | isa = PBXHeadersBuildPhase;
318 | buildActionMask = 2147483647;
319 | files = (
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | D284B1151F79039F00D94AF3 /* Headers */ = {
324 | isa = PBXHeadersBuildPhase;
325 | buildActionMask = 2147483647;
326 | files = (
327 | );
328 | runOnlyForDeploymentPostprocessing = 0;
329 | };
330 | D5B2E89C1C3A780C00C0327D /* Headers */ = {
331 | isa = PBXHeadersBuildPhase;
332 | buildActionMask = 2147483647;
333 | files = (
334 | );
335 | runOnlyForDeploymentPostprocessing = 0;
336 | };
337 | D5C6293D1C3A7FAA007F7B7C /* Headers */ = {
338 | isa = PBXHeadersBuildPhase;
339 | buildActionMask = 2147483647;
340 | files = (
341 | );
342 | runOnlyForDeploymentPostprocessing = 0;
343 | };
344 | /* End PBXHeadersBuildPhase section */
345 |
346 | /* Begin PBXNativeTarget section */
347 | D284B0FB1F79038B00D94AF3 /* Differific-tvOS */ = {
348 | isa = PBXNativeTarget;
349 | buildConfigurationList = D284B10D1F79038B00D94AF3 /* Build configuration list for PBXNativeTarget "Differific-tvOS" */;
350 | buildPhases = (
351 | D284B0F71F79038B00D94AF3 /* Sources */,
352 | D284B0F81F79038B00D94AF3 /* Frameworks */,
353 | D284B0F91F79038B00D94AF3 /* Headers */,
354 | D284B0FA1F79038B00D94AF3 /* Resources */,
355 | );
356 | buildRules = (
357 | );
358 | dependencies = (
359 | );
360 | name = "Differific-tvOS";
361 | productName = "Differific-tvOS";
362 | productReference = D284B0FC1F79038B00D94AF3 /* Differific.framework */;
363 | productType = "com.apple.product-type.framework";
364 | };
365 | D284B1031F79038B00D94AF3 /* Differific-tvOS-Tests */ = {
366 | isa = PBXNativeTarget;
367 | buildConfigurationList = D284B1101F79038B00D94AF3 /* Build configuration list for PBXNativeTarget "Differific-tvOS-Tests" */;
368 | buildPhases = (
369 | D284B1001F79038B00D94AF3 /* Sources */,
370 | D284B1011F79038B00D94AF3 /* Frameworks */,
371 | D284B1021F79038B00D94AF3 /* Resources */,
372 | );
373 | buildRules = (
374 | );
375 | dependencies = (
376 | D284B1071F79038B00D94AF3 /* PBXTargetDependency */,
377 | );
378 | name = "Differific-tvOS-Tests";
379 | productName = "Differific-tvOSTests";
380 | productReference = D284B1041F79038B00D94AF3 /* Differific-tvOS-Tests.xctest */;
381 | productType = "com.apple.product-type.bundle.unit-test";
382 | };
383 | D284B1171F79039F00D94AF3 /* Differific-watchOS */ = {
384 | isa = PBXNativeTarget;
385 | buildConfigurationList = D284B11D1F79039F00D94AF3 /* Build configuration list for PBXNativeTarget "Differific-watchOS" */;
386 | buildPhases = (
387 | D284B1131F79039F00D94AF3 /* Sources */,
388 | D284B1141F79039F00D94AF3 /* Frameworks */,
389 | D284B1151F79039F00D94AF3 /* Headers */,
390 | D284B1161F79039F00D94AF3 /* Resources */,
391 | );
392 | buildRules = (
393 | );
394 | dependencies = (
395 | );
396 | name = "Differific-watchOS";
397 | productName = "Differific-watchOS";
398 | productReference = D284B1181F79039F00D94AF3 /* Differific.framework */;
399 | productType = "com.apple.product-type.framework";
400 | };
401 | D5B2E89E1C3A780C00C0327D /* Differific-iOS */ = {
402 | isa = PBXNativeTarget;
403 | buildConfigurationList = D5B2E8B31C3A780C00C0327D /* Build configuration list for PBXNativeTarget "Differific-iOS" */;
404 | buildPhases = (
405 | D5B2E89A1C3A780C00C0327D /* Sources */,
406 | D5B2E89B1C3A780C00C0327D /* Frameworks */,
407 | D5B2E89C1C3A780C00C0327D /* Headers */,
408 | D5B2E89D1C3A780C00C0327D /* Resources */,
409 | );
410 | buildRules = (
411 | );
412 | dependencies = (
413 | );
414 | name = "Differific-iOS";
415 | productName = Differific;
416 | productReference = D5B2E89F1C3A780C00C0327D /* Differific.framework */;
417 | productType = "com.apple.product-type.framework";
418 | };
419 | D5B2E8A81C3A780C00C0327D /* Differific-iOS-Tests */ = {
420 | isa = PBXNativeTarget;
421 | buildConfigurationList = D5B2E8B61C3A780C00C0327D /* Build configuration list for PBXNativeTarget "Differific-iOS-Tests" */;
422 | buildPhases = (
423 | D5B2E8A51C3A780C00C0327D /* Sources */,
424 | D5B2E8A61C3A780C00C0327D /* Frameworks */,
425 | D5B2E8A71C3A780C00C0327D /* Resources */,
426 | );
427 | buildRules = (
428 | );
429 | dependencies = (
430 | D5B2E8AC1C3A780C00C0327D /* PBXTargetDependency */,
431 | );
432 | name = "Differific-iOS-Tests";
433 | productName = DifferificTests;
434 | productReference = D5B2E8A91C3A780C00C0327D /* Differific-iOS-Tests.xctest */;
435 | productType = "com.apple.product-type.bundle.unit-test";
436 | };
437 | D5C6293F1C3A7FAA007F7B7C /* Differific-macOS */ = {
438 | isa = PBXNativeTarget;
439 | buildConfigurationList = D5C629511C3A7FAA007F7B7C /* Build configuration list for PBXNativeTarget "Differific-macOS" */;
440 | buildPhases = (
441 | D5C6293B1C3A7FAA007F7B7C /* Sources */,
442 | D5C6293C1C3A7FAA007F7B7C /* Frameworks */,
443 | D5C6293D1C3A7FAA007F7B7C /* Headers */,
444 | D5C6293E1C3A7FAA007F7B7C /* Resources */,
445 | );
446 | buildRules = (
447 | );
448 | dependencies = (
449 | );
450 | name = "Differific-macOS";
451 | productName = "Differific-Mac";
452 | productReference = D5C629401C3A7FAA007F7B7C /* Differific.framework */;
453 | productType = "com.apple.product-type.framework";
454 | };
455 | D5C629481C3A7FAA007F7B7C /* Differific-macOS-Tests */ = {
456 | isa = PBXNativeTarget;
457 | buildConfigurationList = D5C629541C3A7FAA007F7B7C /* Build configuration list for PBXNativeTarget "Differific-macOS-Tests" */;
458 | buildPhases = (
459 | D5C629451C3A7FAA007F7B7C /* Sources */,
460 | D5C629461C3A7FAA007F7B7C /* Frameworks */,
461 | D5C629471C3A7FAA007F7B7C /* Resources */,
462 | );
463 | buildRules = (
464 | );
465 | dependencies = (
466 | D5C6294C1C3A7FAA007F7B7C /* PBXTargetDependency */,
467 | );
468 | name = "Differific-macOS-Tests";
469 | productName = "Differific-MacTests";
470 | productReference = D5C629491C3A7FAA007F7B7C /* Differific-macOS-Tests.xctest */;
471 | productType = "com.apple.product-type.bundle.unit-test";
472 | };
473 | /* End PBXNativeTarget section */
474 |
475 | /* Begin PBXProject section */
476 | D5B2E8961C3A780C00C0327D /* Project object */ = {
477 | isa = PBXProject;
478 | attributes = {
479 | LastSwiftUpdateCheck = 0900;
480 | LastUpgradeCheck = 0930;
481 | ORGANIZATIONNAME = "Christoffer Winterkvist";
482 | TargetAttributes = {
483 | D284B0FB1F79038B00D94AF3 = {
484 | CreatedOnToolsVersion = 9.0;
485 | LastSwiftMigration = 0900;
486 | ProvisioningStyle = Automatic;
487 | };
488 | D284B1031F79038B00D94AF3 = {
489 | CreatedOnToolsVersion = 9.0;
490 | LastSwiftMigration = 0900;
491 | ProvisioningStyle = Automatic;
492 | };
493 | D284B1171F79039F00D94AF3 = {
494 | CreatedOnToolsVersion = 9.0;
495 | LastSwiftMigration = 0900;
496 | ProvisioningStyle = Automatic;
497 | };
498 | D5B2E89E1C3A780C00C0327D = {
499 | CreatedOnToolsVersion = 7.2;
500 | LastSwiftMigration = 1020;
501 | };
502 | D5B2E8A81C3A780C00C0327D = {
503 | CreatedOnToolsVersion = 7.2;
504 | LastSwiftMigration = 1020;
505 | };
506 | D5C6293F1C3A7FAA007F7B7C = {
507 | CreatedOnToolsVersion = 7.2;
508 | LastSwiftMigration = 1020;
509 | };
510 | D5C629481C3A7FAA007F7B7C = {
511 | CreatedOnToolsVersion = 7.2;
512 | LastSwiftMigration = 1020;
513 | };
514 | };
515 | };
516 | buildConfigurationList = D5B2E8991C3A780C00C0327D /* Build configuration list for PBXProject "Differific" */;
517 | compatibilityVersion = "Xcode 3.2";
518 | developmentRegion = en;
519 | hasScannedForEncodings = 0;
520 | knownRegions = (
521 | en,
522 | Base,
523 | );
524 | mainGroup = D5B2E8951C3A780C00C0327D;
525 | productRefGroup = D5B2E8A01C3A780C00C0327D /* Products */;
526 | projectDirPath = "";
527 | projectRoot = "";
528 | targets = (
529 | D5B2E89E1C3A780C00C0327D /* Differific-iOS */,
530 | D5B2E8A81C3A780C00C0327D /* Differific-iOS-Tests */,
531 | D5C6293F1C3A7FAA007F7B7C /* Differific-macOS */,
532 | D5C629481C3A7FAA007F7B7C /* Differific-macOS-Tests */,
533 | D284B0FB1F79038B00D94AF3 /* Differific-tvOS */,
534 | D284B1031F79038B00D94AF3 /* Differific-tvOS-Tests */,
535 | D284B1171F79039F00D94AF3 /* Differific-watchOS */,
536 | );
537 | };
538 | /* End PBXProject section */
539 |
540 | /* Begin PBXResourcesBuildPhase section */
541 | D284B0FA1F79038B00D94AF3 /* Resources */ = {
542 | isa = PBXResourcesBuildPhase;
543 | buildActionMask = 2147483647;
544 | files = (
545 | );
546 | runOnlyForDeploymentPostprocessing = 0;
547 | };
548 | D284B1021F79038B00D94AF3 /* Resources */ = {
549 | isa = PBXResourcesBuildPhase;
550 | buildActionMask = 2147483647;
551 | files = (
552 | );
553 | runOnlyForDeploymentPostprocessing = 0;
554 | };
555 | D284B1161F79039F00D94AF3 /* Resources */ = {
556 | isa = PBXResourcesBuildPhase;
557 | buildActionMask = 2147483647;
558 | files = (
559 | D284B1391F7906DB00D94AF3 /* Info-tvOS-Tests.plist in Resources */,
560 | D284B1381F7906DB00D94AF3 /* Info-iOS-Tests.plist in Resources */,
561 | D284B13B1F7906DB00D94AF3 /* Info-macOS-Tests.plist in Resources */,
562 | );
563 | runOnlyForDeploymentPostprocessing = 0;
564 | };
565 | D5B2E89D1C3A780C00C0327D /* Resources */ = {
566 | isa = PBXResourcesBuildPhase;
567 | buildActionMask = 2147483647;
568 | files = (
569 | );
570 | runOnlyForDeploymentPostprocessing = 0;
571 | };
572 | D5B2E8A71C3A780C00C0327D /* Resources */ = {
573 | isa = PBXResourcesBuildPhase;
574 | buildActionMask = 2147483647;
575 | files = (
576 | );
577 | runOnlyForDeploymentPostprocessing = 0;
578 | };
579 | D5C6293E1C3A7FAA007F7B7C /* Resources */ = {
580 | isa = PBXResourcesBuildPhase;
581 | buildActionMask = 2147483647;
582 | files = (
583 | );
584 | runOnlyForDeploymentPostprocessing = 0;
585 | };
586 | D5C629471C3A7FAA007F7B7C /* Resources */ = {
587 | isa = PBXResourcesBuildPhase;
588 | buildActionMask = 2147483647;
589 | files = (
590 | );
591 | runOnlyForDeploymentPostprocessing = 0;
592 | };
593 | /* End PBXResourcesBuildPhase section */
594 |
595 | /* Begin PBXSourcesBuildPhase section */
596 | D284B0F71F79038B00D94AF3 /* Sources */ = {
597 | isa = PBXSourcesBuildPhase;
598 | buildActionMask = 2147483647;
599 | files = (
600 | BDED0DCA222C57A800D7B46E /* Diffable.swift in Sources */,
601 | BDBF80CF20923FD00002CE93 /* IndexPathManager.swift in Sources */,
602 | BDBF80D220923FD00002CE93 /* Algorithm.swift in Sources */,
603 | BDBF80BC20923FB90002CE93 /* UICollectionView+Extensions.swift in Sources */,
604 | BDBF80C920923FD00002CE93 /* DiffManager.swift in Sources */,
605 | BDBF80BA20923FB90002CE93 /* UITableView+Extensions.swift in Sources */,
606 | BD690D4E20DC141200E56E30 /* TableEntry.swift in Sources */,
607 | BDBF80CC20923FD00002CE93 /* Change.swift in Sources */,
608 | BD690D5220DC143100E56E30 /* ArrayEntry.swift in Sources */,
609 | BD690D4A20DC13F700E56E30 /* Counter.swift in Sources */,
610 | );
611 | runOnlyForDeploymentPostprocessing = 0;
612 | };
613 | D284B1001F79038B00D94AF3 /* Sources */ = {
614 | isa = PBXSourcesBuildPhase;
615 | buildActionMask = 2147483647;
616 | files = (
617 | BDBF80E8209252440002CE93 /* UICollectionViewExtensionsTests.swift in Sources */,
618 | BDBF80DC209240110002CE93 /* DiffManagerTests.swift in Sources */,
619 | BDBF80E020924D880002CE93 /* IndexPathManagerTests.swift in Sources */,
620 | BDBF80E4209250140002CE93 /* UITableViewExtensionsTests.swift in Sources */,
621 | );
622 | runOnlyForDeploymentPostprocessing = 0;
623 | };
624 | D284B1131F79039F00D94AF3 /* Sources */ = {
625 | isa = PBXSourcesBuildPhase;
626 | buildActionMask = 2147483647;
627 | files = (
628 | );
629 | runOnlyForDeploymentPostprocessing = 0;
630 | };
631 | D5B2E89A1C3A780C00C0327D /* Sources */ = {
632 | isa = PBXSourcesBuildPhase;
633 | buildActionMask = 2147483647;
634 | files = (
635 | BDED0DC8222C57A800D7B46E /* Diffable.swift in Sources */,
636 | BDBF80CD20923FD00002CE93 /* IndexPathManager.swift in Sources */,
637 | BDBF80D020923FD00002CE93 /* Algorithm.swift in Sources */,
638 | BDBF80BB20923FB90002CE93 /* UICollectionView+Extensions.swift in Sources */,
639 | BDBF80C720923FD00002CE93 /* DiffManager.swift in Sources */,
640 | BDBF80B920923FB90002CE93 /* UITableView+Extensions.swift in Sources */,
641 | BD690D4C20DC141200E56E30 /* TableEntry.swift in Sources */,
642 | BDBF80CA20923FD00002CE93 /* Change.swift in Sources */,
643 | BD690D5020DC143100E56E30 /* ArrayEntry.swift in Sources */,
644 | BD690D4820DC13F700E56E30 /* Counter.swift in Sources */,
645 | );
646 | runOnlyForDeploymentPostprocessing = 0;
647 | };
648 | D5B2E8A51C3A780C00C0327D /* Sources */ = {
649 | isa = PBXSourcesBuildPhase;
650 | buildActionMask = 2147483647;
651 | files = (
652 | BDBF80E6209252440002CE93 /* UICollectionViewExtensionsTests.swift in Sources */,
653 | BDBF80DA209240110002CE93 /* DiffManagerTests.swift in Sources */,
654 | BDBF80DE20924D880002CE93 /* IndexPathManagerTests.swift in Sources */,
655 | BDBF80E2209250140002CE93 /* UITableViewExtensionsTests.swift in Sources */,
656 | );
657 | runOnlyForDeploymentPostprocessing = 0;
658 | };
659 | D5C6293B1C3A7FAA007F7B7C /* Sources */ = {
660 | isa = PBXSourcesBuildPhase;
661 | buildActionMask = 2147483647;
662 | files = (
663 | BDED0DC9222C57A800D7B46E /* Diffable.swift in Sources */,
664 | BDBF80CE20923FD00002CE93 /* IndexPathManager.swift in Sources */,
665 | BDBF80D120923FD00002CE93 /* Algorithm.swift in Sources */,
666 | BDBF80D820923FFA0002CE93 /* NSTableView+Extensions.swift in Sources */,
667 | BDBF80C820923FD00002CE93 /* DiffManager.swift in Sources */,
668 | BDBF80CB20923FD00002CE93 /* Change.swift in Sources */,
669 | BD690D4D20DC141200E56E30 /* TableEntry.swift in Sources */,
670 | BDBF80D720923FFA0002CE93 /* NSCollectionView+Extensions.swift in Sources */,
671 | BD690D5120DC143100E56E30 /* ArrayEntry.swift in Sources */,
672 | BD690D4920DC13F700E56E30 /* Counter.swift in Sources */,
673 | );
674 | runOnlyForDeploymentPostprocessing = 0;
675 | };
676 | D5C629451C3A7FAA007F7B7C /* Sources */ = {
677 | isa = PBXSourcesBuildPhase;
678 | buildActionMask = 2147483647;
679 | files = (
680 | BDBF80EC20927B360002CE93 /* NSTableViewExtensionsTests.swift in Sources */,
681 | BDBF80DB209240110002CE93 /* DiffManagerTests.swift in Sources */,
682 | BDBF80EA20927B080002CE93 /* NSCollectionViewExtensionTests.swift in Sources */,
683 | BDBF80DF20924D880002CE93 /* IndexPathManagerTests.swift in Sources */,
684 | );
685 | runOnlyForDeploymentPostprocessing = 0;
686 | };
687 | /* End PBXSourcesBuildPhase section */
688 |
689 | /* Begin PBXTargetDependency section */
690 | D284B1071F79038B00D94AF3 /* PBXTargetDependency */ = {
691 | isa = PBXTargetDependency;
692 | target = D284B0FB1F79038B00D94AF3 /* Differific-tvOS */;
693 | targetProxy = D284B1061F79038B00D94AF3 /* PBXContainerItemProxy */;
694 | };
695 | D5B2E8AC1C3A780C00C0327D /* PBXTargetDependency */ = {
696 | isa = PBXTargetDependency;
697 | target = D5B2E89E1C3A780C00C0327D /* Differific-iOS */;
698 | targetProxy = D5B2E8AB1C3A780C00C0327D /* PBXContainerItemProxy */;
699 | };
700 | D5C6294C1C3A7FAA007F7B7C /* PBXTargetDependency */ = {
701 | isa = PBXTargetDependency;
702 | target = D5C6293F1C3A7FAA007F7B7C /* Differific-macOS */;
703 | targetProxy = D5C6294B1C3A7FAA007F7B7C /* PBXContainerItemProxy */;
704 | };
705 | /* End PBXTargetDependency section */
706 |
707 | /* Begin XCBuildConfiguration section */
708 | D284B10E1F79038B00D94AF3 /* Debug */ = {
709 | isa = XCBuildConfiguration;
710 | buildSettings = {
711 | CLANG_ANALYZER_NONNULL = YES;
712 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
713 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
714 | CLANG_ENABLE_MODULES = YES;
715 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
716 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
717 | CODE_SIGN_IDENTITY = "";
718 | CODE_SIGN_STYLE = Automatic;
719 | DEFINES_MODULE = YES;
720 | DYLIB_COMPATIBILITY_VERSION = 1;
721 | DYLIB_CURRENT_VERSION = 1;
722 | DYLIB_INSTALL_NAME_BASE = "@rpath";
723 | GCC_C_LANGUAGE_STANDARD = gnu11;
724 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-tvOS.plist";
725 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
726 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
727 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-tvOS";
728 | PRODUCT_NAME = Differific;
729 | SDKROOT = appletvos;
730 | SKIP_INSTALL = YES;
731 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
732 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
733 | SWIFT_VERSION = 4.2;
734 | TARGETED_DEVICE_FAMILY = 3;
735 | TVOS_DEPLOYMENT_TARGET = 11.0;
736 | };
737 | name = Debug;
738 | };
739 | D284B10F1F79038B00D94AF3 /* Release */ = {
740 | isa = XCBuildConfiguration;
741 | buildSettings = {
742 | CLANG_ANALYZER_NONNULL = YES;
743 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
744 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
745 | CLANG_ENABLE_MODULES = YES;
746 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
747 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
748 | CODE_SIGN_IDENTITY = "";
749 | CODE_SIGN_STYLE = Automatic;
750 | DEFINES_MODULE = YES;
751 | DYLIB_COMPATIBILITY_VERSION = 1;
752 | DYLIB_CURRENT_VERSION = 1;
753 | DYLIB_INSTALL_NAME_BASE = "@rpath";
754 | GCC_C_LANGUAGE_STANDARD = gnu11;
755 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-tvOS.plist";
756 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
757 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
758 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-tvOS";
759 | PRODUCT_NAME = Differific;
760 | SDKROOT = appletvos;
761 | SKIP_INSTALL = YES;
762 | SWIFT_VERSION = 4.2;
763 | TARGETED_DEVICE_FAMILY = 3;
764 | TVOS_DEPLOYMENT_TARGET = 11.0;
765 | };
766 | name = Release;
767 | };
768 | D284B1111F79038B00D94AF3 /* Debug */ = {
769 | isa = XCBuildConfiguration;
770 | buildSettings = {
771 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
772 | CLANG_ANALYZER_NONNULL = YES;
773 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
774 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
775 | CLANG_ENABLE_MODULES = YES;
776 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
777 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
778 | CODE_SIGN_STYLE = Automatic;
779 | GCC_C_LANGUAGE_STANDARD = gnu11;
780 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Info-tvOS-Tests.plist";
781 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
782 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-tvOSTests";
783 | PRODUCT_NAME = "$(TARGET_NAME)";
784 | SDKROOT = appletvos;
785 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
786 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
787 | SWIFT_VERSION = 4.2;
788 | TARGETED_DEVICE_FAMILY = 3;
789 | TVOS_DEPLOYMENT_TARGET = 11.0;
790 | };
791 | name = Debug;
792 | };
793 | D284B1121F79038B00D94AF3 /* Release */ = {
794 | isa = XCBuildConfiguration;
795 | buildSettings = {
796 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
797 | CLANG_ANALYZER_NONNULL = YES;
798 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
799 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
800 | CLANG_ENABLE_MODULES = YES;
801 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
802 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
803 | CODE_SIGN_STYLE = Automatic;
804 | GCC_C_LANGUAGE_STANDARD = gnu11;
805 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Info-tvOS-Tests.plist";
806 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
807 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-tvOSTests";
808 | PRODUCT_NAME = "$(TARGET_NAME)";
809 | SDKROOT = appletvos;
810 | SWIFT_VERSION = 4.2;
811 | TARGETED_DEVICE_FAMILY = 3;
812 | TVOS_DEPLOYMENT_TARGET = 11.0;
813 | };
814 | name = Release;
815 | };
816 | D284B11E1F79039F00D94AF3 /* Debug */ = {
817 | isa = XCBuildConfiguration;
818 | buildSettings = {
819 | APPLICATION_EXTENSION_API_ONLY = YES;
820 | CLANG_ANALYZER_NONNULL = YES;
821 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
822 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
823 | CLANG_ENABLE_MODULES = YES;
824 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
825 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
826 | CODE_SIGN_IDENTITY = "";
827 | CODE_SIGN_STYLE = Automatic;
828 | DEFINES_MODULE = YES;
829 | DYLIB_COMPATIBILITY_VERSION = 1;
830 | DYLIB_CURRENT_VERSION = 1;
831 | DYLIB_INSTALL_NAME_BASE = "@rpath";
832 | GCC_C_LANGUAGE_STANDARD = gnu11;
833 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-watchOS.plist";
834 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
835 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
836 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-watchOS";
837 | PRODUCT_NAME = Differific;
838 | SDKROOT = watchos;
839 | SKIP_INSTALL = YES;
840 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
841 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
842 | SWIFT_VERSION = 4.2;
843 | TARGETED_DEVICE_FAMILY = 4;
844 | WATCHOS_DEPLOYMENT_TARGET = 3.0;
845 | };
846 | name = Debug;
847 | };
848 | D284B11F1F79039F00D94AF3 /* Release */ = {
849 | isa = XCBuildConfiguration;
850 | buildSettings = {
851 | APPLICATION_EXTENSION_API_ONLY = YES;
852 | CLANG_ANALYZER_NONNULL = YES;
853 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
854 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
855 | CLANG_ENABLE_MODULES = YES;
856 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
857 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
858 | CODE_SIGN_IDENTITY = "";
859 | CODE_SIGN_STYLE = Automatic;
860 | DEFINES_MODULE = YES;
861 | DYLIB_COMPATIBILITY_VERSION = 1;
862 | DYLIB_CURRENT_VERSION = 1;
863 | DYLIB_INSTALL_NAME_BASE = "@rpath";
864 | GCC_C_LANGUAGE_STANDARD = gnu11;
865 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-watchOS.plist";
866 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
867 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
868 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-watchOS";
869 | PRODUCT_NAME = Differific;
870 | SDKROOT = watchos;
871 | SKIP_INSTALL = YES;
872 | SWIFT_VERSION = 4.2;
873 | TARGETED_DEVICE_FAMILY = 4;
874 | WATCHOS_DEPLOYMENT_TARGET = 3.0;
875 | };
876 | name = Release;
877 | };
878 | D5B2E8B11C3A780C00C0327D /* Debug */ = {
879 | isa = XCBuildConfiguration;
880 | buildSettings = {
881 | ALWAYS_SEARCH_USER_PATHS = NO;
882 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
883 | CLANG_CXX_LIBRARY = "libc++";
884 | CLANG_ENABLE_MODULES = YES;
885 | CLANG_ENABLE_OBJC_ARC = YES;
886 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
887 | CLANG_WARN_BOOL_CONVERSION = YES;
888 | CLANG_WARN_COMMA = YES;
889 | CLANG_WARN_CONSTANT_CONVERSION = YES;
890 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
891 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
892 | CLANG_WARN_EMPTY_BODY = YES;
893 | CLANG_WARN_ENUM_CONVERSION = YES;
894 | CLANG_WARN_INFINITE_RECURSION = YES;
895 | CLANG_WARN_INT_CONVERSION = YES;
896 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
897 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
898 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
899 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
900 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
901 | CLANG_WARN_STRICT_PROTOTYPES = YES;
902 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
903 | CLANG_WARN_UNREACHABLE_CODE = YES;
904 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
905 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
906 | COPY_PHASE_STRIP = NO;
907 | CURRENT_PROJECT_VERSION = 1;
908 | DEBUG_INFORMATION_FORMAT = dwarf;
909 | ENABLE_STRICT_OBJC_MSGSEND = YES;
910 | ENABLE_TESTABILITY = YES;
911 | GCC_C_LANGUAGE_STANDARD = gnu99;
912 | GCC_DYNAMIC_NO_PIC = NO;
913 | GCC_NO_COMMON_BLOCKS = YES;
914 | GCC_OPTIMIZATION_LEVEL = 0;
915 | GCC_PREPROCESSOR_DEFINITIONS = (
916 | "DEBUG=1",
917 | "$(inherited)",
918 | );
919 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
920 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
921 | GCC_WARN_UNDECLARED_SELECTOR = YES;
922 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
923 | GCC_WARN_UNUSED_FUNCTION = YES;
924 | GCC_WARN_UNUSED_VARIABLE = YES;
925 | IPHONEOS_DEPLOYMENT_TARGET = 9.2;
926 | MTL_ENABLE_DEBUG_INFO = YES;
927 | ONLY_ACTIVE_ARCH = YES;
928 | SDKROOT = iphoneos;
929 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
930 | SWIFT_VERSION = 4.2;
931 | TARGETED_DEVICE_FAMILY = "1,2";
932 | VERSIONING_SYSTEM = "apple-generic";
933 | VERSION_INFO_PREFIX = "";
934 | };
935 | name = Debug;
936 | };
937 | D5B2E8B21C3A780C00C0327D /* Release */ = {
938 | isa = XCBuildConfiguration;
939 | buildSettings = {
940 | ALWAYS_SEARCH_USER_PATHS = NO;
941 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
942 | CLANG_CXX_LIBRARY = "libc++";
943 | CLANG_ENABLE_MODULES = YES;
944 | CLANG_ENABLE_OBJC_ARC = YES;
945 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
946 | CLANG_WARN_BOOL_CONVERSION = YES;
947 | CLANG_WARN_COMMA = YES;
948 | CLANG_WARN_CONSTANT_CONVERSION = YES;
949 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
950 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
951 | CLANG_WARN_EMPTY_BODY = YES;
952 | CLANG_WARN_ENUM_CONVERSION = YES;
953 | CLANG_WARN_INFINITE_RECURSION = YES;
954 | CLANG_WARN_INT_CONVERSION = YES;
955 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
956 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
957 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
958 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
959 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
960 | CLANG_WARN_STRICT_PROTOTYPES = YES;
961 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
962 | CLANG_WARN_UNREACHABLE_CODE = YES;
963 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
964 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
965 | COPY_PHASE_STRIP = NO;
966 | CURRENT_PROJECT_VERSION = 1;
967 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
968 | ENABLE_NS_ASSERTIONS = NO;
969 | ENABLE_STRICT_OBJC_MSGSEND = YES;
970 | GCC_C_LANGUAGE_STANDARD = gnu99;
971 | GCC_NO_COMMON_BLOCKS = YES;
972 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
973 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
974 | GCC_WARN_UNDECLARED_SELECTOR = YES;
975 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
976 | GCC_WARN_UNUSED_FUNCTION = YES;
977 | GCC_WARN_UNUSED_VARIABLE = YES;
978 | IPHONEOS_DEPLOYMENT_TARGET = 9.2;
979 | MTL_ENABLE_DEBUG_INFO = NO;
980 | SDKROOT = iphoneos;
981 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
982 | SWIFT_VERSION = 4.2;
983 | TARGETED_DEVICE_FAMILY = "1,2";
984 | VALIDATE_PRODUCT = YES;
985 | VERSIONING_SYSTEM = "apple-generic";
986 | VERSION_INFO_PREFIX = "";
987 | };
988 | name = Release;
989 | };
990 | D5B2E8B41C3A780C00C0327D /* Debug */ = {
991 | isa = XCBuildConfiguration;
992 | buildSettings = {
993 | CLANG_ENABLE_MODULES = YES;
994 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
995 | DEFINES_MODULE = YES;
996 | DYLIB_COMPATIBILITY_VERSION = 1;
997 | DYLIB_CURRENT_VERSION = 1;
998 | DYLIB_INSTALL_NAME_BASE = "@rpath";
999 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-iOS.plist";
1000 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
1001 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1002 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1003 | PRODUCT_BUNDLE_IDENTIFIER = "com.zenangst.Differific-iOS";
1004 | PRODUCT_NAME = Differific;
1005 | SKIP_INSTALL = YES;
1006 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
1007 | SWIFT_VERSION = 5.0;
1008 | };
1009 | name = Debug;
1010 | };
1011 | D5B2E8B51C3A780C00C0327D /* Release */ = {
1012 | isa = XCBuildConfiguration;
1013 | buildSettings = {
1014 | CLANG_ENABLE_MODULES = YES;
1015 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
1016 | DEFINES_MODULE = YES;
1017 | DYLIB_COMPATIBILITY_VERSION = 1;
1018 | DYLIB_CURRENT_VERSION = 1;
1019 | DYLIB_INSTALL_NAME_BASE = "@rpath";
1020 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-iOS.plist";
1021 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
1022 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1023 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1024 | PRODUCT_BUNDLE_IDENTIFIER = "com.zenangst.Differific-iOS";
1025 | PRODUCT_NAME = Differific;
1026 | SKIP_INSTALL = YES;
1027 | SWIFT_VERSION = 5.0;
1028 | };
1029 | name = Release;
1030 | };
1031 | D5B2E8B71C3A780C00C0327D /* Debug */ = {
1032 | isa = XCBuildConfiguration;
1033 | buildSettings = {
1034 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
1035 | CLANG_ENABLE_MODULES = YES;
1036 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
1037 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Info-iOS-Tests.plist";
1038 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
1039 | PRODUCT_BUNDLE_IDENTIFIER = no.hyper.DifferificTests;
1040 | PRODUCT_NAME = "$(TARGET_NAME)";
1041 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
1042 | SWIFT_VERSION = 5.0;
1043 | };
1044 | name = Debug;
1045 | };
1046 | D5B2E8B81C3A780C00C0327D /* Release */ = {
1047 | isa = XCBuildConfiguration;
1048 | buildSettings = {
1049 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
1050 | CLANG_ENABLE_MODULES = YES;
1051 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
1052 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Info-iOS-Tests.plist";
1053 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
1054 | PRODUCT_BUNDLE_IDENTIFIER = no.hyper.DifferificTests;
1055 | PRODUCT_NAME = "$(TARGET_NAME)";
1056 | SWIFT_VERSION = 5.0;
1057 | };
1058 | name = Release;
1059 | };
1060 | D5C629521C3A7FAA007F7B7C /* Debug */ = {
1061 | isa = XCBuildConfiguration;
1062 | buildSettings = {
1063 | CLANG_ENABLE_MODULES = YES;
1064 | CODE_SIGN_IDENTITY = "-";
1065 | COMBINE_HIDPI_IMAGES = YES;
1066 | DEFINES_MODULE = YES;
1067 | DYLIB_COMPATIBILITY_VERSION = 1;
1068 | DYLIB_CURRENT_VERSION = 1;
1069 | DYLIB_INSTALL_NAME_BASE = "@rpath";
1070 | FRAMEWORK_VERSION = A;
1071 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-macOS.plist";
1072 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
1073 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
1074 | MACOSX_DEPLOYMENT_TARGET = 10.11;
1075 | PRODUCT_BUNDLE_IDENTIFIER = "com.zenangst.Differific-macOS";
1076 | PRODUCT_NAME = Differific;
1077 | SDKROOT = macosx;
1078 | SKIP_INSTALL = YES;
1079 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
1080 | SWIFT_VERSION = 5.0;
1081 | };
1082 | name = Debug;
1083 | };
1084 | D5C629531C3A7FAA007F7B7C /* Release */ = {
1085 | isa = XCBuildConfiguration;
1086 | buildSettings = {
1087 | CLANG_ENABLE_MODULES = YES;
1088 | CODE_SIGN_IDENTITY = "-";
1089 | COMBINE_HIDPI_IMAGES = YES;
1090 | DEFINES_MODULE = YES;
1091 | DYLIB_COMPATIBILITY_VERSION = 1;
1092 | DYLIB_CURRENT_VERSION = 1;
1093 | DYLIB_INSTALL_NAME_BASE = "@rpath";
1094 | FRAMEWORK_VERSION = A;
1095 | INFOPLIST_FILE = "$(SRCROOT)/Info/Info-macOS.plist";
1096 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
1097 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
1098 | MACOSX_DEPLOYMENT_TARGET = 10.11;
1099 | PRODUCT_BUNDLE_IDENTIFIER = "com.zenangst.Differific-macOS";
1100 | PRODUCT_NAME = Differific;
1101 | SDKROOT = macosx;
1102 | SKIP_INSTALL = YES;
1103 | SWIFT_VERSION = 5.0;
1104 | };
1105 | name = Release;
1106 | };
1107 | D5C629551C3A7FAA007F7B7C /* Debug */ = {
1108 | isa = XCBuildConfiguration;
1109 | buildSettings = {
1110 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
1111 | CODE_SIGN_IDENTITY = "-";
1112 | COMBINE_HIDPI_IMAGES = YES;
1113 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
1114 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Info-macOS-Tests.plist";
1115 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks $(FRAMEWORK_SEARCH_PATHS)";
1116 | MACOSX_DEPLOYMENT_TARGET = 10.11;
1117 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-MacTests";
1118 | PRODUCT_NAME = "$(TARGET_NAME)";
1119 | SDKROOT = macosx;
1120 | SWIFT_VERSION = 5.0;
1121 | };
1122 | name = Debug;
1123 | };
1124 | D5C629561C3A7FAA007F7B7C /* Release */ = {
1125 | isa = XCBuildConfiguration;
1126 | buildSettings = {
1127 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
1128 | CODE_SIGN_IDENTITY = "-";
1129 | COMBINE_HIDPI_IMAGES = YES;
1130 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
1131 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Info-macOS-Tests.plist";
1132 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks $(FRAMEWORK_SEARCH_PATHS)";
1133 | MACOSX_DEPLOYMENT_TARGET = 10.11;
1134 | PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Differific-MacTests";
1135 | PRODUCT_NAME = "$(TARGET_NAME)";
1136 | SDKROOT = macosx;
1137 | SWIFT_VERSION = 5.0;
1138 | };
1139 | name = Release;
1140 | };
1141 | /* End XCBuildConfiguration section */
1142 |
1143 | /* Begin XCConfigurationList section */
1144 | D284B10D1F79038B00D94AF3 /* Build configuration list for PBXNativeTarget "Differific-tvOS" */ = {
1145 | isa = XCConfigurationList;
1146 | buildConfigurations = (
1147 | D284B10E1F79038B00D94AF3 /* Debug */,
1148 | D284B10F1F79038B00D94AF3 /* Release */,
1149 | );
1150 | defaultConfigurationIsVisible = 0;
1151 | defaultConfigurationName = Release;
1152 | };
1153 | D284B1101F79038B00D94AF3 /* Build configuration list for PBXNativeTarget "Differific-tvOS-Tests" */ = {
1154 | isa = XCConfigurationList;
1155 | buildConfigurations = (
1156 | D284B1111F79038B00D94AF3 /* Debug */,
1157 | D284B1121F79038B00D94AF3 /* Release */,
1158 | );
1159 | defaultConfigurationIsVisible = 0;
1160 | defaultConfigurationName = Release;
1161 | };
1162 | D284B11D1F79039F00D94AF3 /* Build configuration list for PBXNativeTarget "Differific-watchOS" */ = {
1163 | isa = XCConfigurationList;
1164 | buildConfigurations = (
1165 | D284B11E1F79039F00D94AF3 /* Debug */,
1166 | D284B11F1F79039F00D94AF3 /* Release */,
1167 | );
1168 | defaultConfigurationIsVisible = 0;
1169 | defaultConfigurationName = Release;
1170 | };
1171 | D5B2E8991C3A780C00C0327D /* Build configuration list for PBXProject "Differific" */ = {
1172 | isa = XCConfigurationList;
1173 | buildConfigurations = (
1174 | D5B2E8B11C3A780C00C0327D /* Debug */,
1175 | D5B2E8B21C3A780C00C0327D /* Release */,
1176 | );
1177 | defaultConfigurationIsVisible = 0;
1178 | defaultConfigurationName = Release;
1179 | };
1180 | D5B2E8B31C3A780C00C0327D /* Build configuration list for PBXNativeTarget "Differific-iOS" */ = {
1181 | isa = XCConfigurationList;
1182 | buildConfigurations = (
1183 | D5B2E8B41C3A780C00C0327D /* Debug */,
1184 | D5B2E8B51C3A780C00C0327D /* Release */,
1185 | );
1186 | defaultConfigurationIsVisible = 0;
1187 | defaultConfigurationName = Release;
1188 | };
1189 | D5B2E8B61C3A780C00C0327D /* Build configuration list for PBXNativeTarget "Differific-iOS-Tests" */ = {
1190 | isa = XCConfigurationList;
1191 | buildConfigurations = (
1192 | D5B2E8B71C3A780C00C0327D /* Debug */,
1193 | D5B2E8B81C3A780C00C0327D /* Release */,
1194 | );
1195 | defaultConfigurationIsVisible = 0;
1196 | defaultConfigurationName = Release;
1197 | };
1198 | D5C629511C3A7FAA007F7B7C /* Build configuration list for PBXNativeTarget "Differific-macOS" */ = {
1199 | isa = XCConfigurationList;
1200 | buildConfigurations = (
1201 | D5C629521C3A7FAA007F7B7C /* Debug */,
1202 | D5C629531C3A7FAA007F7B7C /* Release */,
1203 | );
1204 | defaultConfigurationIsVisible = 0;
1205 | defaultConfigurationName = Release;
1206 | };
1207 | D5C629541C3A7FAA007F7B7C /* Build configuration list for PBXNativeTarget "Differific-macOS-Tests" */ = {
1208 | isa = XCConfigurationList;
1209 | buildConfigurations = (
1210 | D5C629551C3A7FAA007F7B7C /* Debug */,
1211 | D5C629561C3A7FAA007F7B7C /* Release */,
1212 | );
1213 | defaultConfigurationIsVisible = 0;
1214 | defaultConfigurationName = Release;
1215 | };
1216 | /* End XCConfigurationList section */
1217 | };
1218 | rootObject = D5B2E8961C3A780C00C0327D /* Project object */;
1219 | }
1220 |
--------------------------------------------------------------------------------