Replace RxDataSources with custom datasource based on DifferenceKit
This commit is contained in:
parent
f6bc41fcc6
commit
24a28d5b24
@ -9,8 +9,6 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A000AA124C2EEDE001F5B00 /* Location.swift */; };
|
7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A000AA124C2EEDE001F5B00 /* Location.swift */; };
|
||||||
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */ = {isa = PBXBuildFile; productRef = 7A051610241412CA00FC55AC /* SwiftDate */; };
|
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */ = {isa = PBXBuildFile; productRef = 7A051610241412CA00FC55AC /* SwiftDate */; };
|
||||||
7A0516162414EC1200FC55AC /* Differentiator in Frameworks */ = {isa = PBXBuildFile; productRef = 7A0516152414EC1200FC55AC /* Differentiator */; };
|
|
||||||
7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */ = {isa = PBXBuildFile; productRef = 7A0516172414EC1200FC55AC /* RxDataSources */; };
|
|
||||||
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0516192414FF0900FC55AC /* DateSection.swift */; };
|
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0516192414FF0900FC55AC /* DateSection.swift */; };
|
||||||
7A1090E824A394F100B4F0B2 /* AudioRecordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1090E724A394F100B4F0B2 /* AudioRecordCell.swift */; };
|
7A1090E824A394F100B4F0B2 /* AudioRecordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1090E724A394F100B4F0B2 /* AudioRecordCell.swift */; };
|
||||||
7A1090EA24A3A26300B4F0B2 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1090E924A3A26300B4F0B2 /* AudioPlayer.swift */; };
|
7A1090EA24A3A26300B4F0B2 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1090E924A3A26300B4F0B2 /* AudioPlayer.swift */; };
|
||||||
@ -80,6 +78,8 @@
|
|||||||
7A96AE33246C095700297C33 /* Base64FS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE32246C095700297C33 /* Base64FS.swift */; };
|
7A96AE33246C095700297C33 /* Base64FS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE32246C095700297C33 /* Base64FS.swift */; };
|
||||||
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; };
|
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; };
|
||||||
7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE1C2532F3EB0041AFC6 /* PKHUD */; };
|
7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE1C2532F3EB0041AFC6 /* PKHUD */; };
|
||||||
|
7AABDE23253327F10041AFC6 /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE22253327F10041AFC6 /* DifferenceKit */; };
|
||||||
|
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AABDE25253350C30041AFC6 /* RxSectionedDataSource.swift */; };
|
||||||
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAE6AD224CDDF950023860B /* VehicleEvent.swift */; };
|
7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAE6AD224CDDF950023860B /* VehicleEvent.swift */; };
|
||||||
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB562B9249C9E9B00473D53 /* Region.swift */; };
|
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB562B9249C9E9B00473D53 /* Region.swift */; };
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
||||||
@ -168,6 +168,7 @@
|
|||||||
7A96AE30246B2FE400297C33 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
7A96AE30246B2FE400297C33 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||||
7A96AE32246C095700297C33 /* Base64FS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64FS.swift; sourceTree = "<group>"; };
|
7A96AE32246C095700297C33 /* Base64FS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64FS.swift; sourceTree = "<group>"; };
|
||||||
7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxRealmDataSource.swift; sourceTree = "<group>"; };
|
7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxRealmDataSource.swift; sourceTree = "<group>"; };
|
||||||
|
7AABDE25253350C30041AFC6 /* RxSectionedDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxSectionedDataSource.swift; sourceTree = "<group>"; };
|
||||||
7AAE6AD224CDDF950023860B /* VehicleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleEvent.swift; sourceTree = "<group>"; };
|
7AAE6AD224CDDF950023860B /* VehicleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleEvent.swift; sourceTree = "<group>"; };
|
||||||
7AB562B9249C9E9B00473D53 /* Region.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Region.swift; sourceTree = "<group>"; };
|
7AB562B9249C9E9B00473D53 /* Region.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Region.swift; sourceTree = "<group>"; };
|
||||||
7AB67E8B2435C38700258F61 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = "<group>"; };
|
7AB67E8B2435C38700258F61 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = "<group>"; };
|
||||||
@ -195,16 +196,15 @@
|
|||||||
files = (
|
files = (
|
||||||
7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */,
|
7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */,
|
||||||
7AF58D342402A91C00CE01A0 /* Kingfisher in Frameworks */,
|
7AF58D342402A91C00CE01A0 /* Kingfisher in Frameworks */,
|
||||||
7A0516162414EC1200FC55AC /* Differentiator in Frameworks */,
|
|
||||||
7A813DC12508C4D900CC93B9 /* ExceptionCatcher in Frameworks */,
|
7A813DC12508C4D900CC93B9 /* ExceptionCatcher in Frameworks */,
|
||||||
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */,
|
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */,
|
||||||
7A11472823FEA1F400B424AF /* RealmSwift in Frameworks */,
|
7A11472823FEA1F400B424AF /* RealmSwift in Frameworks */,
|
||||||
7A11472123FEA18700B424AF /* RxCocoa in Frameworks */,
|
7A11472123FEA18700B424AF /* RxCocoa in Frameworks */,
|
||||||
7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */,
|
|
||||||
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */,
|
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */,
|
||||||
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
|
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
|
||||||
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
|
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
|
||||||
7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */,
|
7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */,
|
||||||
|
7AABDE23253327F10041AFC6 /* DifferenceKit in Frameworks */,
|
||||||
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */,
|
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */,
|
||||||
7A11471F23FEA18700B424AF /* RxRelay in Frameworks */,
|
7A11471F23FEA18700B424AF /* RxRelay in Frameworks */,
|
||||||
7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */,
|
7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */,
|
||||||
@ -296,6 +296,7 @@
|
|||||||
7A1090E924A3A26300B4F0B2 /* AudioPlayer.swift */,
|
7A1090E924A3A26300B4F0B2 /* AudioPlayer.swift */,
|
||||||
7A000AA124C2EEDE001F5B00 /* Location.swift */,
|
7A000AA124C2EEDE001F5B00 /* Location.swift */,
|
||||||
7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */,
|
7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */,
|
||||||
|
7AABDE25253350C30041AFC6 /* RxSectionedDataSource.swift */,
|
||||||
);
|
);
|
||||||
path = Utils;
|
path = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -436,11 +437,10 @@
|
|||||||
7AF58D2E24029C5200CE01A0 /* MagazineLayout */,
|
7AF58D2E24029C5200CE01A0 /* MagazineLayout */,
|
||||||
7AF58D332402A91C00CE01A0 /* Kingfisher */,
|
7AF58D332402A91C00CE01A0 /* Kingfisher */,
|
||||||
7A051610241412CA00FC55AC /* SwiftDate */,
|
7A051610241412CA00FC55AC /* SwiftDate */,
|
||||||
7A0516152414EC1200FC55AC /* Differentiator */,
|
|
||||||
7A0516172414EC1200FC55AC /* RxDataSources */,
|
|
||||||
7A96AE29246AFD6200297C33 /* Eureka */,
|
7A96AE29246AFD6200297C33 /* Eureka */,
|
||||||
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */,
|
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */,
|
||||||
7AABDE1C2532F3EB0041AFC6 /* PKHUD */,
|
7AABDE1C2532F3EB0041AFC6 /* PKHUD */,
|
||||||
|
7AABDE22253327F10041AFC6 /* DifferenceKit */,
|
||||||
);
|
);
|
||||||
productName = AutoCat;
|
productName = AutoCat;
|
||||||
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
||||||
@ -477,10 +477,10 @@
|
|||||||
7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */,
|
7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */,
|
||||||
7AF58D322402A91C00CE01A0 /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
7AF58D322402A91C00CE01A0 /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||||
7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */,
|
7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */,
|
||||||
7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */,
|
|
||||||
7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */,
|
7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */,
|
||||||
7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */,
|
7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */,
|
||||||
7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */,
|
7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */,
|
||||||
|
7AABDE21253327F10041AFC6 /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -523,6 +523,7 @@
|
|||||||
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
||||||
7A813DC32508EE4F00CC93B9 /* EventCell.swift in Sources */,
|
7A813DC32508EE4F00CC93B9 /* EventCell.swift in Sources */,
|
||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
||||||
|
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */,
|
||||||
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */,
|
7AB562BA249C9E9B00473D53 /* Region.swift in Sources */,
|
||||||
7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */,
|
7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */,
|
||||||
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
||||||
@ -727,7 +728,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 43;
|
CURRENT_PROJECT_VERSION = 44;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
@ -749,7 +750,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 43;
|
CURRENT_PROJECT_VERSION = 44;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
@ -797,14 +798,6 @@
|
|||||||
minimumVersion = 6.1.0;
|
minimumVersion = 6.1.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */ = {
|
|
||||||
isa = XCRemoteSwiftPackageReference;
|
|
||||||
repositoryURL = "https://github.com/RxSwiftCommunity/RxDataSources";
|
|
||||||
requirement = {
|
|
||||||
kind = upToNextMajorVersion;
|
|
||||||
minimumVersion = 4.0.1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
7A11471B23FEA18700B424AF /* XCRemoteSwiftPackageReference "RxSwift" */ = {
|
7A11471B23FEA18700B424AF /* XCRemoteSwiftPackageReference "RxSwift" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/ReactiveX/RxSwift.git";
|
repositoryURL = "https://github.com/ReactiveX/RxSwift.git";
|
||||||
@ -853,6 +846,14 @@
|
|||||||
minimumVersion = 5.4.0;
|
minimumVersion = 5.4.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
7AABDE21253327F10041AFC6 /* XCRemoteSwiftPackageReference "DifferenceKit" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/ra1028/DifferenceKit.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 1.1.5;
|
||||||
|
};
|
||||||
|
};
|
||||||
7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */ = {
|
7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/airbnb/MagazineLayout";
|
repositoryURL = "https://github.com/airbnb/MagazineLayout";
|
||||||
@ -877,16 +878,6 @@
|
|||||||
package = 7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */;
|
package = 7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */;
|
||||||
productName = SwiftDate;
|
productName = SwiftDate;
|
||||||
};
|
};
|
||||||
7A0516152414EC1200FC55AC /* Differentiator */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
package = 7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */;
|
|
||||||
productName = Differentiator;
|
|
||||||
};
|
|
||||||
7A0516172414EC1200FC55AC /* RxDataSources */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
package = 7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */;
|
|
||||||
productName = RxDataSources;
|
|
||||||
};
|
|
||||||
7A11471C23FEA18700B424AF /* RxSwift */ = {
|
7A11471C23FEA18700B424AF /* RxSwift */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 7A11471B23FEA18700B424AF /* XCRemoteSwiftPackageReference "RxSwift" */;
|
package = 7A11471B23FEA18700B424AF /* XCRemoteSwiftPackageReference "RxSwift" */;
|
||||||
@ -937,6 +928,11 @@
|
|||||||
package = 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */;
|
package = 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */;
|
||||||
productName = PKHUD;
|
productName = PKHUD;
|
||||||
};
|
};
|
||||||
|
7AABDE22253327F10041AFC6 /* DifferenceKit */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 7AABDE21253327F10041AFC6 /* XCRemoteSwiftPackageReference "DifferenceKit" */;
|
||||||
|
productName = DifferenceKit;
|
||||||
|
};
|
||||||
7AF58D2E24029C5200CE01A0 /* MagazineLayout */ = {
|
7AF58D2E24029C5200CE01A0 /* MagazineLayout */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */;
|
package = 7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */;
|
||||||
|
|||||||
@ -1,6 +1,15 @@
|
|||||||
{
|
{
|
||||||
"object": {
|
"object": {
|
||||||
"pins": [
|
"pins": [
|
||||||
|
{
|
||||||
|
"package": "DifferenceKit",
|
||||||
|
"repositoryURL": "https://github.com/ra1028/DifferenceKit.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "14c66681e12a38b81045f44c6c29724a0d4b0e72",
|
||||||
|
"version": "1.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "Eureka",
|
"package": "Eureka",
|
||||||
"repositoryURL": "https://github.com/xmartlabs/Eureka",
|
"repositoryURL": "https://github.com/xmartlabs/Eureka",
|
||||||
@ -64,15 +73,6 @@
|
|||||||
"version": "6.1.3"
|
"version": "6.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"package": "RxDataSources",
|
|
||||||
"repositoryURL": "https://github.com/RxSwiftCommunity/RxDataSources",
|
|
||||||
"state": {
|
|
||||||
"branch": null,
|
|
||||||
"revision": "a18cee01c9ee55f04d0c7eb15c77a96c3648c88e",
|
|
||||||
"version": "4.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"package": "RxRealm",
|
"package": "RxRealm",
|
||||||
"repositoryURL": "https://github.com/RxSwiftCommunity/RxRealm",
|
"repositoryURL": "https://github.com/RxSwiftCommunity/RxRealm",
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.SwiftErrorBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.SwiftErrorBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "C14D0996-5708-44D2-A6BA-4A4B50B522EE"
|
uuid = "C14D0996-5708-44D2-A6BA-4A4B50B522EE"
|
||||||
shouldBeEnabled = "No"
|
shouldBeEnabled = "Yes"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No">
|
continueAfterRunningActions = "No">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "CF01B44D-372B-4C78-A197-7FDEC607CE0E"
|
uuid = "CF01B44D-372B-4C78-A197-7FDEC607CE0E"
|
||||||
shouldBeEnabled = "No"
|
shouldBeEnabled = "Yes"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
scope = "1"
|
scope = "1"
|
||||||
|
|||||||
@ -9,6 +9,27 @@
|
|||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>DifferenceKit (Playground) 1.xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>isShown</key>
|
||||||
|
<false/>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>14</integer>
|
||||||
|
</dict>
|
||||||
|
<key>DifferenceKit (Playground) 2.xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>isShown</key>
|
||||||
|
<false/>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>15</integer>
|
||||||
|
</dict>
|
||||||
|
<key>DifferenceKit (Playground).xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>isShown</key>
|
||||||
|
<false/>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>11</integer>
|
||||||
|
</dict>
|
||||||
<key>Eureka (Playground) 1.xcscheme</key>
|
<key>Eureka (Playground) 1.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
@ -35,14 +56,14 @@
|
|||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>11</integer>
|
<integer>12</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>GettingStarted (Playground) 2.xcscheme</key>
|
<key>GettingStarted (Playground) 2.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>12</integer>
|
<integer>13</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>GettingStarted (Playground) 3.xcscheme</key>
|
<key>GettingStarted (Playground) 3.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import RxDataSources
|
|
||||||
import RxSwift
|
import RxSwift
|
||||||
import RxCocoa
|
import RxCocoa
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
@ -13,7 +12,7 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
let bag = DisposeBag()
|
let bag = DisposeBag()
|
||||||
let searchController = UISearchController(searchResultsController: nil)
|
let searchController = UISearchController(searchResultsController: nil)
|
||||||
var refreshControl = UIRefreshControl()
|
var refreshControl = UIRefreshControl()
|
||||||
var datasource: RxTableViewSectionedAnimatedDataSource<DateSection<Vehicle>>!
|
var datasource: RxSectionedDataSource<Vehicle,VehicleCell>!
|
||||||
|
|
||||||
var filterRelay = BehaviorRelay<Filter>(value: Filter())
|
var filterRelay = BehaviorRelay<Filter>(value: Filter())
|
||||||
var filter = Filter()
|
var filter = Filter()
|
||||||
@ -33,23 +32,8 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
self.refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
|
self.refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
|
||||||
self.tableView.addSubview(self.refreshControl)
|
self.tableView.addSubview(self.refreshControl)
|
||||||
|
|
||||||
self.datasource = RxTableViewSectionedAnimatedDataSource<DateSection<Vehicle>>(configureCell: { dataSource, tableView, indexPath, item in
|
self.datasource = RxSectionedDataSource(table: self.tableView)
|
||||||
if let cell = tableView.dequeueReusableCell(withIdentifier: "VehicleCell", for: indexPath) as? VehicleCell {
|
self.tableView.delegate = self
|
||||||
cell.configure(with: item)
|
|
||||||
return cell
|
|
||||||
} else {
|
|
||||||
return UITableViewCell()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
self.datasource.canEditRowAtIndexPath = { _, _ in true }
|
|
||||||
|
|
||||||
self.datasource.titleForHeaderInSection = { dataSourse, index in
|
|
||||||
return dataSourse.sectionModels[index].header
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tableView.rx.modelSelected(Vehicle.self)
|
|
||||||
.subscribe(onNext: self.updateDetailController(with:))
|
|
||||||
.disposed(by: self.bag)
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.filterRelay
|
self.filterRelay
|
||||||
@ -62,12 +46,9 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
self.showMapButton.isEnabled = $0.count > 0
|
self.showMapButton.isEnabled = $0.count > 0
|
||||||
self.refreshControl.endRefreshing()
|
self.refreshControl.endRefreshing()
|
||||||
})
|
})
|
||||||
.map { $0.groupedByDate() }
|
.bind(to: self.datasource.data)
|
||||||
.bind(to: self.tableView.rx.items(dataSource: self.datasource))
|
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tableView.rx.setDelegate(self).disposed(by: self.bag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Code duplication
|
// FIXME: Code duplication
|
||||||
@ -135,7 +116,7 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
// MARK: - UITableViewDelegate
|
// MARK: - UITableViewDelegate
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
||||||
let vehicle = self.datasource[indexPath]
|
let vehicle = self.datasource.item(at: indexPath)
|
||||||
let updateAction = UIContextualAction(style: .normal, title: "Update") { action, view, completion in
|
let updateAction = UIContextualAction(style: .normal, title: "Update") { action, view, completion in
|
||||||
self.update(vehicle: vehicle, at: indexPath)
|
self.update(vehicle: vehicle, at: indexPath)
|
||||||
completion(true)
|
completion(true)
|
||||||
@ -149,7 +130,7 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
|
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
|
||||||
let vehicle = self.datasource[indexPath]
|
let vehicle = self.datasource.item(at: indexPath)
|
||||||
|
|
||||||
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
|
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
|
||||||
let update = UIAction(title: "Update", image: UIImage(systemName: "arrow.2.circlepath")) { action in
|
let update = UIAction(title: "Update", image: UIImage(systemName: "arrow.2.circlepath")) { action in
|
||||||
@ -171,10 +152,15 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.datasource[indexPath] = newVehicle
|
self.datasource.set(item: newVehicle, at: indexPath)
|
||||||
self.updateDetailController(with: newVehicle)
|
self.updateDetailController(with: newVehicle)
|
||||||
} onError: { err in
|
} onError: { err in
|
||||||
HUD.show(error: err)
|
HUD.show(error: err)
|
||||||
}.disposed(by: self.bag)
|
}.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
let vehicle = self.datasource.item(at: indexPath)
|
||||||
|
self.updateDetailController(with: vehicle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxDataSources
|
|
||||||
import SwiftDate
|
import SwiftDate
|
||||||
|
import DifferenceKit
|
||||||
|
|
||||||
protocol Dated {
|
protocol Dated {
|
||||||
var date: Date { get }
|
var date: Date { get }
|
||||||
@ -18,7 +18,7 @@ extension AudioRecord: Dated {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RandomAccessCollection where Element: Dated & IdentifiableType & Equatable {
|
extension RandomAccessCollection where Element: Dated & Equatable & Differentiable {
|
||||||
func groupedByDate() -> [DateSection<Element>] {
|
func groupedByDate() -> [DateSection<Element>] {
|
||||||
let now = Date()
|
let now = Date()
|
||||||
let monthStart = now.dateAtStartOf(.month)
|
let monthStart = now.dateAtStartOf(.month)
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
import RxDataSources
|
import DifferenceKit
|
||||||
|
|
||||||
class AudioRecord: Object, IdentifiableType {
|
class AudioRecord: Object, Identifiable, Differentiable {
|
||||||
|
|
||||||
@objc dynamic var path: String = ""
|
@objc dynamic var path: String = ""
|
||||||
@objc dynamic var number: String?
|
@objc dynamic var number: String?
|
||||||
@ -12,13 +12,19 @@ class AudioRecord: Object, IdentifiableType {
|
|||||||
@objc dynamic var event: VehicleEvent?
|
@objc dynamic var event: VehicleEvent?
|
||||||
|
|
||||||
var identifier: TimeInterval = 0
|
var identifier: TimeInterval = 0
|
||||||
var identity: TimeInterval {
|
var id: TimeInterval {
|
||||||
if self.identifier == 0 {
|
if self.identifier == 0 {
|
||||||
self.identifier = self.addedDate
|
self.identifier = self.addedDate
|
||||||
}
|
}
|
||||||
return self.identifier
|
return self.identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var differenceIdentifier: TimeInterval { id }
|
||||||
|
|
||||||
|
func isContentEqual(to source: AudioRecord) -> Bool {
|
||||||
|
return self == source
|
||||||
|
}
|
||||||
|
|
||||||
init(path: String, number: String?, raw: String, duration: TimeInterval, event: VehicleEvent?) {
|
init(path: String, number: String?, raw: String, duration: TimeInterval, event: VehicleEvent?) {
|
||||||
self.path = path
|
self.path = path
|
||||||
self.number = number
|
self.number = number
|
||||||
@ -36,7 +42,7 @@ class AudioRecord: Object, IdentifiableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override class func ignoredProperties() -> [String] {
|
override class func ignoredProperties() -> [String] {
|
||||||
return ["identity", "identifier"]
|
return ["id", "identifier", "differenceIdentifier"]
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAddedDate() -> TimeInterval {
|
func getAddedDate() -> TimeInterval {
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxDataSources
|
|
||||||
import SwiftDate
|
import SwiftDate
|
||||||
|
import DifferenceKit
|
||||||
|
|
||||||
struct DateSection<T>: AnimatableSectionModelType, Equatable where T: IdentifiableType, T: Equatable {
|
struct DateSection<T>: Differentiable, DifferentiableSection where T: Differentiable {
|
||||||
|
|
||||||
var timestamp: Double = 0
|
var timestamp: Double = 0
|
||||||
var header: String
|
var header: String
|
||||||
var items: [T]
|
var elements: [T]
|
||||||
|
|
||||||
var identity: String {
|
init<C>(source: DateSection<T>, elements: C) where C : Swift.Collection, C.Element == Self.Collection.Element {
|
||||||
return header
|
self.timestamp = source.timestamp
|
||||||
|
self.header = source.header
|
||||||
|
self.elements = Array(elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(original: DateSection, items: [T]) {
|
init(original: DateSection, items: [T]) {
|
||||||
self = original
|
self = original
|
||||||
self.items = items
|
self.elements = items
|
||||||
}
|
}
|
||||||
|
|
||||||
init(timestamp: Double, items: [T]) {
|
init(timestamp: Double, items: [T]) {
|
||||||
@ -45,6 +47,16 @@ struct DateSection<T>: AnimatableSectionModelType, Equatable where T: Identifiab
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.timestamp = timestamp
|
self.timestamp = timestamp
|
||||||
self.items = items
|
self.elements = items
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Differentiable
|
||||||
|
|
||||||
|
var differenceIdentifier: String {
|
||||||
|
return header
|
||||||
|
}
|
||||||
|
|
||||||
|
func isContentEqual(to source: DateSection<T>) -> Bool {
|
||||||
|
return self.differenceIdentifier == source.differenceIdentifier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
import RxDataSources
|
import DifferenceKit
|
||||||
|
|
||||||
class VehicleName: Object, Decodable {
|
class VehicleName: Object, Decodable {
|
||||||
@objc dynamic var original: String?
|
@objc dynamic var original: String?
|
||||||
@ -66,7 +66,7 @@ class VehicleOwnershipPeriod: Object, Decodable {
|
|||||||
@objc dynamic var to: Int64
|
@objc dynamic var to: Int64
|
||||||
}
|
}
|
||||||
|
|
||||||
class Vehicle: Object, Decodable, IdentifiableType {
|
class Vehicle: Object, Decodable, Identifiable, Differentiable {
|
||||||
@objc dynamic var brand: VehicleBrand?
|
@objc dynamic var brand: VehicleBrand?
|
||||||
@objc dynamic var model: VehicleModel?
|
@objc dynamic var model: VehicleModel?
|
||||||
@objc dynamic var color: String?
|
@objc dynamic var color: String?
|
||||||
@ -89,13 +89,19 @@ class Vehicle: Object, Decodable, IdentifiableType {
|
|||||||
let events = List<VehicleEvent>()
|
let events = List<VehicleEvent>()
|
||||||
|
|
||||||
var identifier: String = ""
|
var identifier: String = ""
|
||||||
var identity: String {
|
var id: String {
|
||||||
if self.identifier.isEmpty {
|
if self.identifier.isEmpty {
|
||||||
self.identifier = self.number
|
self.identifier = self.number
|
||||||
}
|
}
|
||||||
return self.identifier
|
return self.identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var differenceIdentifier: String { id }
|
||||||
|
|
||||||
|
func isContentEqual(to source: Vehicle) -> Bool {
|
||||||
|
return self == source
|
||||||
|
}
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case brand
|
case brand
|
||||||
case model
|
case model
|
||||||
@ -183,7 +189,7 @@ class Vehicle: Object, Decodable, IdentifiableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override class func ignoredProperties() -> [String] {
|
override class func ignoredProperties() -> [String] {
|
||||||
return ["identity", "identifier"]
|
return ["id", "identifier", "differenceIdentifier"]
|
||||||
}
|
}
|
||||||
|
|
||||||
var unrecognized: Bool {
|
var unrecognized: Bool {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
import RxDataSources
|
import DifferenceKit
|
||||||
|
|
||||||
class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where Item: Object & IdentifiableType & Dated, Cell: UITableViewCell & ConfigurableCell, Cell.Item == Item {
|
class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where Item: Object & Identifiable & Dated & Differentiable, Cell: UITableViewCell & ConfigurableCell, Cell.Item == Item {
|
||||||
|
|
||||||
private var tv: UITableView
|
private var tv: UITableView
|
||||||
private var data: Results<Item>
|
private var data: Results<Item>
|
||||||
@ -24,28 +24,20 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where
|
|||||||
self.tv.reloadData()
|
self.tv.reloadData()
|
||||||
case .update(_, let deletions, let insertions, let modifications):
|
case .update(_, let deletions, let insertions, let modifications):
|
||||||
print("====== Deletes: \(deletions.count), Inserts: \(insertions.count), Mods: \(modifications.count)")
|
print("====== Deletes: \(deletions.count), Inserts: \(insertions.count), Mods: \(modifications.count)")
|
||||||
let oldSectionsCount = self.sections.count
|
|
||||||
|
let newSections = self.data.groupedByDate()
|
||||||
|
let changeset = StagedChangeset(source: self.sections, target: newSections, section: 0)
|
||||||
|
|
||||||
self.tv.beginUpdates()
|
self.tv.beginUpdates()
|
||||||
let delPaths = deletions.map(self.indexPath)
|
|
||||||
self.tv.deleteRows(at: deletions.map(self.indexPath), with: .automatic)
|
self.tv.deleteRows(at: deletions.map(self.indexPath), with: .automatic)
|
||||||
if let delPath = delPaths.first, self.sections[delPath.section].items.count == 1 {
|
|
||||||
self.tv.deleteSections(IndexSet(integer: delPath.section), with: .automatic)
|
|
||||||
}
|
|
||||||
self.sections = self.data.groupedByDate()
|
self.sections = self.data.groupedByDate()
|
||||||
let insPaths = insertions.map(self.indexPath)
|
self.tv.insertRows(at: insertions.map(self.indexPath), with: .automatic)
|
||||||
if let insPath = insPaths.first, self.sections[insPath.section].items.count == 1 {
|
self.tv.reloadRows(at: modifications.map(self.indexPath), with: .automatic)
|
||||||
self.tv.insertSections(IndexSet(integer: insPath.section), with: .automatic)
|
|
||||||
|
if let firstChangeset = changeset.first {
|
||||||
|
self.tv.deleteSections(IndexSet(firstChangeset.elementDeleted.map { $0.element }), with: .automatic)
|
||||||
|
self.tv.insertSections(IndexSet(firstChangeset.elementInserted.map { $0.element }), with: .automatic)
|
||||||
}
|
}
|
||||||
self.tv.insertRows(at: insPaths, with: .automatic)
|
|
||||||
let modPaths = modifications.map(self.indexPath)
|
|
||||||
if let modPath = modPaths.first {
|
|
||||||
if oldSectionsCount > self.sections.count {
|
|
||||||
self.tv.deleteSections(IndexSet(integer: modPath.section), with: .automatic)
|
|
||||||
} else if oldSectionsCount < self.sections.count {
|
|
||||||
self.tv.insertSections(IndexSet(integer: modPath.section), with: .automatic)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.tv.reloadRows(at: modPaths, with: .automatic)
|
|
||||||
self.tv.endUpdates()
|
self.tv.endUpdates()
|
||||||
case .error(let err):
|
case .error(let err):
|
||||||
print("Realm observer error: \(err)")
|
print("Realm observer error: \(err)")
|
||||||
@ -58,12 +50,12 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where
|
|||||||
func indexPath(by index: Int) -> IndexPath {
|
func indexPath(by index: Int) -> IndexPath {
|
||||||
var sectionStartIndex = 0
|
var sectionStartIndex = 0
|
||||||
for (i, section) in self.sections.enumerated() {
|
for (i, section) in self.sections.enumerated() {
|
||||||
if index < sectionStartIndex + section.items.count {
|
if index < sectionStartIndex + section.elements.count {
|
||||||
print("Index \(index) -> (\(i), \(index - sectionStartIndex))")
|
print("Index \(index) -> (\(i), \(index - sectionStartIndex))")
|
||||||
return IndexPath(row: index - sectionStartIndex, section: i)
|
return IndexPath(row: index - sectionStartIndex, section: i)
|
||||||
}
|
}
|
||||||
|
|
||||||
sectionStartIndex += section.items.count
|
sectionStartIndex += section.elements.count
|
||||||
}
|
}
|
||||||
|
|
||||||
return IndexPath(row: 0, section: 0)
|
return IndexPath(row: 0, section: 0)
|
||||||
@ -76,7 +68,7 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
return self.sections[section].items.count
|
return self.sections[section].elements.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
@ -84,7 +76,7 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where
|
|||||||
return UITableViewCell()
|
return UITableViewCell()
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = self.sections[indexPath.section].items[indexPath.row]
|
let item = self.sections[indexPath.section].elements[indexPath.row]
|
||||||
cell.configure(with: item)
|
cell.configure(with: item)
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
@ -96,6 +88,6 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func item(at indexPath: IndexPath) -> Item {
|
func item(at indexPath: IndexPath) -> Item {
|
||||||
return self.sections[indexPath.section].items[indexPath.row]
|
return self.sections[indexPath.section].elements[indexPath.row]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
61
AutoCat/Utils/RxSectionedDataSource.swift
Normal file
61
AutoCat/Utils/RxSectionedDataSource.swift
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import UIKit
|
||||||
|
import DifferenceKit
|
||||||
|
import RxSwift
|
||||||
|
import RxCocoa
|
||||||
|
|
||||||
|
class RxSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where Item: Dated & Equatable & Differentiable, Cell: UITableViewCell & ConfigurableCell, Cell.Item == Item {
|
||||||
|
private var tv: UITableView
|
||||||
|
private var cellIdentifier: String
|
||||||
|
private var sections: [DateSection<Item>] = []
|
||||||
|
|
||||||
|
init(table: UITableView, cellIdentifier: String = String(describing: Cell.self)) {
|
||||||
|
self.tv = table
|
||||||
|
self.cellIdentifier = cellIdentifier
|
||||||
|
super.init()
|
||||||
|
self.tv.dataSource = self
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UITableViewDataSource
|
||||||
|
|
||||||
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
return self.sections.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return self.sections[section].elements.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: indexPath) as? Cell else {
|
||||||
|
return UITableViewCell()
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = self.sections[indexPath.section].elements[indexPath.row]
|
||||||
|
cell.configure(with: item)
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||||
|
return self.sections[section].header
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
func item(at indexPath: IndexPath) -> Item {
|
||||||
|
return self.sections[indexPath.section].elements[indexPath.row]
|
||||||
|
}
|
||||||
|
|
||||||
|
func set(item: Item, at indexPath: IndexPath) {
|
||||||
|
self.sections[indexPath.section].elements[indexPath.row] = item
|
||||||
|
}
|
||||||
|
|
||||||
|
var data: Binder<[Item]> {
|
||||||
|
return Binder(self) { datasource, data in
|
||||||
|
let newSections = data.groupedByDate()
|
||||||
|
let changeset = StagedChangeset(source: self.sections, target: newSections)
|
||||||
|
self.tv.reload(using: changeset, with: .automatic) { newSects in
|
||||||
|
self.sections = newSects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user