Adds SyncStatusViewController to view basic sync status of games

This commit is contained in:
Riley Testut 2018-11-20 13:04:55 -06:00
parent c1fc0d1ce3
commit 5354d779c1
8 changed files with 303 additions and 10 deletions

View File

@ -98,6 +98,7 @@
BF7AE8081C2E858400B1B5BC /* GridMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8041C2E858400B1B5BC /* GridMenuViewController.swift */; };
BF7AE80A1C2E8C7600B1B5BC /* UIColor+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */; };
BF80E1D21F13117000847008 /* ControllerInputsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF616A121F08184A0077F8B2 /* ControllerInputsViewController.swift */; };
BF8A333421A484A000A42FD4 /* BadgedTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8A333321A484A000A42FD4 /* BadgedTableViewCell.swift */; };
BF8CA9361F5F651900499FDD /* PopoverMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CA9351F5F651900499FDD /* PopoverMenuController.swift */; };
BF8DDD241F4F6C880088A21B /* InputCalloutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8DDD231F4F6C880088A21B /* InputCalloutView.swift */; };
BF95E2771E4977BF0030E7AD /* GameMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF95E2761E4977BF0030E7AD /* GameMetadata.swift */; };
@ -116,6 +117,7 @@
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; };
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; };
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
BFDB3418219E4B1700595A62 /* SyncStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */; };
BFDD04F11D5E2C27002D450E /* GameCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */; };
BFE022A01F5B57FF0052D888 /* PopoverMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE0229F1F5B577D0052D888 /* PopoverMenuButton.swift */; };
BFE4269E1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */; };
@ -244,6 +246,7 @@
BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+FontSize.swift"; sourceTree = "<group>"; };
BF7AE8041C2E858400B1B5BC /* GridMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GridMenuViewController.swift; sourceTree = "<group>"; };
BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Delta.swift"; sourceTree = "<group>"; };
BF8A333321A484A000A42FD4 /* BadgedTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgedTableViewCell.swift; sourceTree = "<group>"; };
BF8CA9351F5F651900499FDD /* PopoverMenuController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverMenuController.swift; sourceTree = "<group>"; };
BF8DDD231F4F6C880088A21B /* InputCalloutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputCalloutView.swift; sourceTree = "<group>"; };
BF95E2761E4977BF0030E7AD /* GameMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameMetadata.swift; sourceTree = "<group>"; };
@ -258,6 +261,7 @@
BFC6F7B71F435BC500221B96 /* Input+Display.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Input+Display.swift"; sourceTree = "<group>"; };
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheatsViewController.swift; sourceTree = "<group>"; };
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = "<group>"; };
BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncStatusViewController.swift; sourceTree = "<group>"; };
BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollectionViewController.swift; sourceTree = "<group>"; };
BFE0229F1F5B577D0052D888 /* PopoverMenuButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverMenuButton.swift; sourceTree = "<group>"; };
BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SaveStatesStoryboardSegue.swift; sourceTree = "<group>"; };
@ -370,6 +374,7 @@
isa = PBXGroup;
children = (
BF48F74D219A16DA00BC2FC1 /* SyncingServicesViewController.swift */,
BFDB3417219E4B1700595A62 /* SyncStatusViewController.swift */,
);
path = Syncing;
sourceTree = "<group>";
@ -520,6 +525,7 @@
children = (
BFFA4C081E8A24D600D87934 /* GameTableViewCell.swift */,
BF71CF891FE904B1001F1613 /* GameTableViewCell.xib */,
BF8A333321A484A000A42FD4 /* BadgedTableViewCell.swift */,
);
path = "Table View";
sourceTree = "<group>";
@ -941,6 +947,7 @@
BF4828841F9027B600028B97 /* Delta.xcdatamodeld in Sources */,
BF5942951E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift in Sources */,
BF353FF91C5D870B00C1184C /* MenuItem.swift in Sources */,
BFDB3418219E4B1700595A62 /* SyncStatusViewController.swift in Sources */,
BF18B61F1E2985F900F70067 /* UIAlertController+Importing.swift in Sources */,
BFDD04F11D5E2C27002D450E /* GameCollectionViewController.swift in Sources */,
BFE4269E1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift in Sources */,
@ -977,6 +984,7 @@
BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */,
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */,
BF6EE5EB1F7C5F8F0051AD6C /* GameControllerInputMapping.swift in Sources */,
BF8A333421A484A000A42FD4 /* BadgedTableViewCell.swift in Sources */,
BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */,
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
BF59426F1E09BC5D0051894B /* DatabaseManager.swift in Sources */,

View File

@ -4,7 +4,6 @@
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -18,7 +17,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<label key="tableFooterView" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delta 0.6.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Str-BY-agW">
<rect key="frame" x="0.0" y="773" width="375" height="44"/>
<rect key="frame" x="0.0" y="817" width="375" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
@ -227,11 +226,11 @@
<rect key="frame" x="0.0" y="611" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="bwW-PG-BcV" id="RNA-99-evH">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Service" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="4U1-fe-PIb">
<rect key="frame" x="16" y="12" width="54" height="19.5"/>
<rect key="frame" x="15" y="12" width="54" height="19.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -250,19 +249,46 @@
<segue destination="R9m-rV-VgV" kind="show" id="MAM-GM-FlH"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DetailCell" textLabel="1u0-gh-zP7" detailTextLabel="ncZ-5K-Hrk" style="IBUITableViewCellStyleValue1" id="JPg-6O-DRe">
<rect key="frame" x="0.0" y="655" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JPg-6O-DRe" id="zcZ-QR-Nno">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Status" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1u0-gh-zP7">
<rect key="frame" x="15" y="12" width="46.5" height="19.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ncZ-5K-Hrk">
<rect key="frame" x="298.5" y="12" width="41.5" height="19.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
<connections>
<segue destination="vVg-ci-JRa" kind="show" id="Hfy-lJ-4tW"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="3D Touch" id="fdp-8c-oOc">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="c5i-qG-ir9" style="IBUITableViewCellStyleDefault" id="SSL-t4-QZj">
<rect key="frame" x="0.0" y="711" width="375" height="44"/>
<rect key="frame" x="0.0" y="755" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SSL-t4-QZj" id="hQB-Iy-bzy">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="App Icon Shortcuts" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="c5i-qG-ir9">
<rect key="frame" x="16" y="0.0" width="324" height="43.5"/>
<rect key="frame" x="15" y="0.0" width="325" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -777,5 +803,42 @@
</objects>
<point key="canvasLocation" x="2513" y="1872"/>
</scene>
<!--Sync Status-->
<scene sceneID="IYe-DI-U7i">
<objects>
<tableViewController title="Sync Status" id="vVg-ci-JRa" customClass="SyncStatusViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Nza-ON-XbS">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="AWh-ik-Gvu" style="IBUITableViewCellStyleDefault" id="wpv-cf-duw" customClass="BadgedTableViewCell" customModule="Delta" customModuleProvider="target">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="wpv-cf-duw" id="ehC-Qx-Zx4">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="AWh-ik-Gvu">
<rect key="frame" x="16" y="0.0" width="324" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="vVg-ci-JRa" id="Ch3-KN-Vuq"/>
<outlet property="delegate" destination="vVg-ci-JRa" id="WMN-hE-f2P"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="kT7-Ig-nyf" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3351" y="1872"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,73 @@
//
// BadgedTableViewCell.swift
// Delta
//
// Created by Riley Testut on 11/20/18.
// Copyright © 2018 Riley Testut. All rights reserved.
//
import UIKit
class BadgedTableViewCell: UITableViewCell
{
let badgeLabel = UILabel()
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
self.initialize()
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
{
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.initialize()
}
private func initialize()
{
self.badgeLabel.clipsToBounds = true
self.badgeLabel.textAlignment = .center
self.badgeLabel.backgroundColor = .red
self.badgeLabel.font = UIFont.boldSystemFont(ofSize: 14)
self.badgeLabel.textColor = .white
self.contentView.addSubview(self.badgeLabel)
}
override func layoutSubviews()
{
super.layoutSubviews()
guard let textLabel = self.textLabel else { return }
let spacing = 8 as CGFloat
var contentSize = self.badgeLabel.intrinsicContentSize
contentSize.width += 10
contentSize.height += 10
contentSize.width = max(contentSize.width, contentSize.height)
var frame = CGRect(x: self.contentView.bounds.maxX - contentSize.width,
y: self.contentView.bounds.midY - contentSize.height / 2,
width: contentSize.width,
height: contentSize.height)
if self.accessoryType == .none
{
frame.origin.x -= spacing
}
self.badgeLabel.frame = frame
self.badgeLabel.layer.cornerRadius = frame.height / 2
self.badgeLabel.backgroundColor = .red
let overlap = textLabel.frame.maxX - (frame.minX - spacing)
if overlap > 0 && !self.badgeLabel.isHidden
{
textLabel.frame.size.width -= overlap
}
}
}

View File

@ -14,11 +14,11 @@ import Harmony
@objc(GameCollection)
public class GameCollection: _GameCollection
{
var name: String {
@objc var name: String {
return self.system?.localizedName ?? NSLocalizedString("Unknown", comment: "")
}
var shortName: String {
@objc var shortName: String {
return self.system?.localizedShortName ?? NSLocalizedString("Unknown", comment: "")
}

View File

@ -0,0 +1,142 @@
//
// SyncStatusViewController.swift
// Delta
//
// Created by Riley Testut on 11/15/18.
// Copyright © 2018 Riley Testut. All rights reserved.
//
import UIKit
import Roxas
class SyncStatusViewController: UITableViewController
{
private lazy var dataSource = self.makeDataSource()
private var gameConflictsCount: [URL: Int]?
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.dataSource = self.dataSource
self.navigationItem.searchController = self.dataSource.searchController
}
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
self.fetchConflictedRecords()
}
}
private extension SyncStatusViewController
{
func makeDataSource() -> RSTFetchedResultsTableViewDataSource<Game>
{
let fetchRequest = Game.fetchRequest() as NSFetchRequest<Game>
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Game.gameCollection?.index, ascending: true), NSSortDescriptor(key: #keyPath(Game.name), ascending: true)]
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(Game.gameCollection.name), cacheName: nil)
let dataSource = RSTFetchedResultsTableViewDataSource(fetchedResultsController: fetchedResultsController)
dataSource.proxy = self
dataSource.searchController.searchableKeyPaths = [#keyPath(Game.name)]
dataSource.cellConfigurationHandler = { (cell, game, indexPath) in
let cell = cell as! BadgedTableViewCell
cell.textLabel?.text = game.name
cell.textLabel?.numberOfLines = 0
if let gameConflictsCount = self.gameConflictsCount
{
if let count = gameConflictsCount[game.objectID.uriRepresentation()], count > 0
{
cell.badgeLabel.text = String(describing: count)
cell.badgeLabel.isHidden = false
}
else
{
cell.badgeLabel.isHidden = true
}
cell.accessoryType = .disclosureIndicator
cell.accessoryView = nil
}
else
{
let activityIndicatorView = UIActivityIndicatorView(style: .gray)
activityIndicatorView.startAnimating()
cell.accessoryType = .none
cell.accessoryView = activityIndicatorView
cell.badgeLabel.isHidden = true
}
}
return dataSource
}
func fetchConflictedRecords()
{
DispatchQueue.global().async {
do
{
var gameConflictsCount = [URL: Int]()
let records = try SyncManager.shared.recordController.fetchConflictedRecords()
for record in records
{
guard let recordedObject = record.recordedObject else { continue }
let conflictedGame: Game?
switch recordedObject
{
case let game as Game: conflictedGame = game
case let saveState as SaveState: conflictedGame = saveState.game
case let cheat as Cheat: conflictedGame = cheat.game
default: conflictedGame = nil
}
guard let game = conflictedGame else { continue }
gameConflictsCount[game.objectID.uriRepresentation(), default: 0] += 1
}
self.gameConflictsCount = gameConflictsCount
}
catch
{
print(error)
self.gameConflictsCount = [:]
DispatchQueue.main.async {
let alertController = UIAlertController(title: NSLocalizedString("Failed to Get Sync Status", comment: ""),
message: error.localizedDescription,
preferredStyle: .alert)
alertController.addAction(.ok)
self.present(alertController, animated: true, completion: nil)
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
extension SyncStatusViewController
{
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
let section = self.dataSource.fetchedResultsController.sections?[section]
return section?.name
}
}

View File

@ -9,6 +9,9 @@
import UIKit
import Harmony
import Harmony_Drive
import Roxas
enum SyncingService: String, CaseIterable
{

View File

@ -17,6 +17,10 @@ final class SyncManager
return self.syncCoordinator.service
}
var recordController: RecordController {
return self.syncCoordinator.recordController
}
private(set) var isAuthenticated = false
private let syncCoordinator = SyncCoordinator(service: DriveService.shared, persistentContainer: DatabaseManager.shared)

2
External/Harmony vendored

@ -1 +1 @@
Subproject commit 09255222fd823bc9014a54e5625bdd286001f047
Subproject commit 6f5dc280077cee8382ccc6622ee8383aadb59d48