Replace repeating timer implementation

This commit is contained in:
Arkadiusz Fal 2022-06-30 00:43:41 +02:00
parent 283d89b5a9
commit dc346f6c25
4 changed files with 59 additions and 76 deletions

View File

@ -3,6 +3,7 @@ import CoreMedia
import Defaults import Defaults
import Foundation import Foundation
import Logging import Logging
import Repeat
import SwiftUI import SwiftUI
final class MPVBackend: PlayerBackend { final class MPVBackend: PlayerBackend {
@ -41,7 +42,7 @@ final class MPVBackend: PlayerBackend {
}} }}
var isPlaying = true { didSet { var isPlaying = true { didSet {
networkStateTimer.resume() networkStateTimer.start()
if isPlaying { if isPlaying {
startClientUpdates() startClientUpdates()
@ -73,8 +74,8 @@ final class MPVBackend: PlayerBackend {
#endif #endif
var client: MPVClient! { didSet { client.backend = self } } var client: MPVClient! { didSet { client.backend = self } }
private var clientTimer: RepeatingTimer! private var clientTimer: Repeater!
private var networkStateTimer: RepeatingTimer! private var networkStateTimer: Repeater!
private var handleEOF = false private var handleEOF = false
private var onFileLoaded: (() -> Void)? private var onFileLoaded: (() -> Void)?
@ -117,11 +118,13 @@ final class MPVBackend: PlayerBackend {
self.playerTime = playerTime self.playerTime = playerTime
self.networkState = networkState self.networkState = networkState
clientTimer = .init(timeInterval: Self.controlsUpdateInterval) clientTimer = .init(interval: .seconds(Self.controlsUpdateInterval), mode: .infinite) { [weak self] _ in
clientTimer.eventHandler = getClientUpdates self?.getClientUpdates()
}
networkStateTimer = .init(timeInterval: Self.networkStateUpdateInterval) networkStateTimer = .init(interval: .seconds(Self.networkStateUpdateInterval), mode: .infinite) { [weak self] _ in
networkStateTimer.eventHandler = updateNetworkState self?.updateNetworkState()
}
} }
typealias AreInIncreasingOrder = (Stream, Stream) -> Bool typealias AreInIncreasingOrder = (Stream, Stream) -> Bool
@ -339,7 +342,7 @@ final class MPVBackend: PlayerBackend {
} }
func startClientUpdates() { func startClientUpdates() {
clientTimer.resume() clientTimer.start()
} }
private var handleSegmentsThrottle = Throttle(interval: 1) private var handleSegmentsThrottle = Throttle(interval: 1)
@ -366,7 +369,7 @@ final class MPVBackend: PlayerBackend {
} }
private func stopClientUpdates() { private func stopClientUpdates() {
clientTimer.suspend() clientTimer.pause()
} }
private func updateControlsIsPlaying() { private func updateControlsIsPlaying() {
@ -404,13 +407,13 @@ final class MPVBackend: PlayerBackend {
case MPV_EVENT_PAUSE: case MPV_EVENT_PAUSE:
isPlaying = false isPlaying = false
networkStateTimer.resume() networkStateTimer.start()
case MPV_EVENT_UNPAUSE: case MPV_EVENT_UNPAUSE:
isPlaying = true isPlaying = true
isLoadingVideo = false isLoadingVideo = false
isSeeking = false isSeeking = false
networkStateTimer.resume() networkStateTimer.start()
case MPV_EVENT_SEEK: case MPV_EVENT_SEEK:
isSeeking = true isSeeking = true
@ -482,15 +485,15 @@ final class MPVBackend: PlayerBackend {
} }
if !networkState.needsUpdates { if !networkState.needsUpdates {
networkStateTimer.suspend() networkStateTimer.pause()
} }
} }
func setNeedsNetworkStateUpdates(_ needsUpdates: Bool) { func setNeedsNetworkStateUpdates(_ needsUpdates: Bool) {
if needsUpdates { if needsUpdates {
networkStateTimer.resume() networkStateTimer.start()
} else { } else {
networkStateTimer.suspend() networkStateTimer.pause()
} }
} }
} }

View File

@ -1,54 +0,0 @@
import Foundation
final class RepeatingTimer {
let timeInterval: TimeInterval
init(timeInterval: TimeInterval) {
self.timeInterval = timeInterval
}
private lazy var timer: DispatchSourceTimer = {
let t = DispatchSource.makeTimerSource()
t.schedule(deadline: .now() + self.timeInterval, repeating: self.timeInterval)
t.setEventHandler { [weak self] in
self?.eventHandler?()
}
return t
}()
var eventHandler: (() -> Void)?
private enum State {
case suspended
case resumed
}
private var state: State = .suspended
deinit {
timer.setEventHandler {}
timer.cancel()
/*
If the timer is suspended, calling cancel without resuming
triggers a crash. This is documented here https://forums.developer.apple.com/thread/15902
*/
resume()
eventHandler = nil
}
func resume() {
if state == .resumed {
return
}
state = .resumed
timer.resume()
}
func suspend() {
if state == .suspended {
return
}
state = .suspended
timer.suspend()
}
}

View File

@ -135,9 +135,6 @@
370F4FFF27CC1756001B35DC /* libxcb.1.1.0.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 370F4FB027CC16CA001B35DC /* libxcb.1.1.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 370F4FFF27CC1756001B35DC /* libxcb.1.1.0.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 370F4FB027CC16CA001B35DC /* libxcb.1.1.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
370F500027CC1756001B35DC /* libXdmcp.6.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 370F4FC727CC16CB001B35DC /* libXdmcp.6.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 370F500027CC1756001B35DC /* libXdmcp.6.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 370F4FC727CC16CB001B35DC /* libXdmcp.6.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
370F500C27CC1821001B35DC /* MPVViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C2211C27ADA33300305B41 /* MPVViewController.swift */; }; 370F500C27CC1821001B35DC /* MPVViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C2211C27ADA33300305B41 /* MPVViewController.swift */; };
371114EB27B94C8800C2EF7B /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371114EA27B94C8800C2EF7B /* RepeatingTimer.swift */; };
371114EC27B94C8800C2EF7B /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371114EA27B94C8800C2EF7B /* RepeatingTimer.swift */; };
371114ED27B94C8800C2EF7B /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371114EA27B94C8800C2EF7B /* RepeatingTimer.swift */; };
3711403F26B206A6005B3555 /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3711403E26B206A6005B3555 /* SearchModel.swift */; }; 3711403F26B206A6005B3555 /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3711403E26B206A6005B3555 /* SearchModel.swift */; };
3711404026B206A6005B3555 /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3711403E26B206A6005B3555 /* SearchModel.swift */; }; 3711404026B206A6005B3555 /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3711403E26B206A6005B3555 /* SearchModel.swift */; };
3711404126B206A6005B3555 /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3711403E26B206A6005B3555 /* SearchModel.swift */; }; 3711404126B206A6005B3555 /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3711403E26B206A6005B3555 /* SearchModel.swift */; };
@ -191,6 +188,9 @@
372915E62687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; }; 372915E62687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
372915E72687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; }; 372915E72687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
372915E82687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; }; 372915E82687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
372AA410286D067B0000B1DC /* Repeat in Frameworks */ = {isa = PBXBuildFile; productRef = 372AA40F286D067B0000B1DC /* Repeat */; };
372AA412286D06950000B1DC /* Repeat in Frameworks */ = {isa = PBXBuildFile; productRef = 372AA411286D06950000B1DC /* Repeat */; };
372AA414286D06A10000B1DC /* Repeat in Frameworks */ = {isa = PBXBuildFile; productRef = 372AA413286D06A10000B1DC /* Repeat */; };
372CFD15285F2E2A00B0B54B /* ControlsBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372CFD14285F2E2A00B0B54B /* ControlsBar.swift */; }; 372CFD15285F2E2A00B0B54B /* ControlsBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372CFD14285F2E2A00B0B54B /* ControlsBar.swift */; };
372CFD16285F2E2A00B0B54B /* ControlsBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372CFD14285F2E2A00B0B54B /* ControlsBar.swift */; }; 372CFD16285F2E2A00B0B54B /* ControlsBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372CFD14285F2E2A00B0B54B /* ControlsBar.swift */; };
372D85DE283841B800FF3C7D /* PiPDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373031F428383A89000CFD59 /* PiPDelegate.swift */; }; 372D85DE283841B800FF3C7D /* PiPDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373031F428383A89000CFD59 /* PiPDelegate.swift */; };
@ -881,7 +881,6 @@
370F4FC727CC16CB001B35DC /* libXdmcp.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libXdmcp.6.dylib; sourceTree = "<group>"; }; 370F4FC727CC16CB001B35DC /* libXdmcp.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libXdmcp.6.dylib; sourceTree = "<group>"; };
370F4FC827CC16CB001B35DC /* libbrotlicommon.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libbrotlicommon.1.dylib; sourceTree = "<group>"; }; 370F4FC827CC16CB001B35DC /* libbrotlicommon.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libbrotlicommon.1.dylib; sourceTree = "<group>"; };
370F500A27CC176F001B35DC /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; }; 370F500A27CC176F001B35DC /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; };
371114EA27B94C8800C2EF7B /* RepeatingTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatingTimer.swift; sourceTree = "<group>"; };
3711403E26B206A6005B3555 /* SearchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchModel.swift; sourceTree = "<group>"; }; 3711403E26B206A6005B3555 /* SearchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchModel.swift; sourceTree = "<group>"; };
3712643B2865FF4500D77974 /* Shared Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Shared Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 3712643B2865FF4500D77974 /* Shared Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Shared Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
37130A5A277657090033018A /* Yattee.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Yattee.xcdatamodel; sourceTree = "<group>"; }; 37130A5A277657090033018A /* Yattee.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Yattee.xcdatamodel; sourceTree = "<group>"; };
@ -1179,6 +1178,7 @@
3736A20A286BB72300C9E5EE /* libssl.xcframework in Frameworks */, 3736A20A286BB72300C9E5EE /* libssl.xcframework in Frameworks */,
37C2212727ADA41000305B41 /* CoreFoundation.framework in Frameworks */, 37C2212727ADA41000305B41 /* CoreFoundation.framework in Frameworks */,
37C2212527ADA40A00305B41 /* AudioToolbox.framework in Frameworks */, 37C2212527ADA40A00305B41 /* AudioToolbox.framework in Frameworks */,
372AA410286D067B0000B1DC /* Repeat in Frameworks */,
37C2212327ADA3F200305B41 /* libiconv.tbd in Frameworks */, 37C2212327ADA3F200305B41 /* libiconv.tbd in Frameworks */,
37C2212127ADA3A600305B41 /* libbz2.tbd in Frameworks */, 37C2212127ADA3A600305B41 /* libbz2.tbd in Frameworks */,
37C2211F27ADA3A200305B41 /* libz.tbd in Frameworks */, 37C2211F27ADA3A200305B41 /* libz.tbd in Frameworks */,
@ -1210,6 +1210,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
372AA414286D06A10000B1DC /* Repeat in Frameworks */,
370F4FD227CC16CB001B35DC /* libavformat.59.16.100.dylib in Frameworks */, 370F4FD227CC16CB001B35DC /* libavformat.59.16.100.dylib in Frameworks */,
370F4FD327CC16CB001B35DC /* libass.9.dylib in Frameworks */, 370F4FD327CC16CB001B35DC /* libass.9.dylib in Frameworks */,
370F4FDF27CC16CB001B35DC /* libxcb-shape.0.0.0.dylib in Frameworks */, 370F4FDF27CC16CB001B35DC /* libxcb-shape.0.0.0.dylib in Frameworks */,
@ -1289,6 +1290,7 @@
3736A203286BB72300C9E5EE /* libfribidi.xcframework in Frameworks */, 3736A203286BB72300C9E5EE /* libfribidi.xcframework in Frameworks */,
3736A207286BB72300C9E5EE /* libfreetype.xcframework in Frameworks */, 3736A207286BB72300C9E5EE /* libfreetype.xcframework in Frameworks */,
3772003D27E8EEDB00CB2475 /* libiconv.tbd in Frameworks */, 3772003D27E8EEDB00CB2475 /* libiconv.tbd in Frameworks */,
372AA412286D06950000B1DC /* Repeat in Frameworks */,
3772003827E8EEB100CB2475 /* AudioToolbox.framework in Frameworks */, 3772003827E8EEB100CB2475 /* AudioToolbox.framework in Frameworks */,
3736A209286BB72300C9E5EE /* libcrypto.xcframework in Frameworks */, 3736A209286BB72300C9E5EE /* libcrypto.xcframework in Frameworks */,
37FB28462722054C00A57617 /* SDWebImageSwiftUI in Frameworks */, 37FB28462722054C00A57617 /* SDWebImageSwiftUI in Frameworks */,
@ -1824,7 +1826,6 @@
3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */, 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */,
3729037D2739E47400EA99F6 /* MenuCommands.swift */, 3729037D2739E47400EA99F6 /* MenuCommands.swift */,
37B7958F2771DAE0001CF27B /* OpenURLHandler.swift */, 37B7958F2771DAE0001CF27B /* OpenURLHandler.swift */,
371114EA27B94C8800C2EF7B /* RepeatingTimer.swift */,
3700155E271B12DD0049C794 /* SiestaConfiguration.swift */, 3700155E271B12DD0049C794 /* SiestaConfiguration.swift */,
37FFC43F272734C3009FFD26 /* Throttle.swift */, 37FFC43F272734C3009FFD26 /* Throttle.swift */,
378FFBC328660172009E3FBE /* URLParser.swift */, 378FFBC328660172009E3FBE /* URLParser.swift */,
@ -2122,6 +2123,7 @@
3765917B27237D21009F956E /* PINCache */, 3765917B27237D21009F956E /* PINCache */,
37CF8B8328535E4F00B71E37 /* SDWebImage */, 37CF8B8328535E4F00B71E37 /* SDWebImage */,
37A5DBC3285DFF5400CA4DD1 /* SwiftUIPager */, 37A5DBC3285DFF5400CA4DD1 /* SwiftUIPager */,
372AA40F286D067B0000B1DC /* Repeat */,
); );
productName = "Yattee (iOS)"; productName = "Yattee (iOS)";
productReference = 37D4B0C92671614900C925CA /* Yattee.app */; productReference = 37D4B0C92671614900C925CA /* Yattee.app */;
@ -2155,6 +2157,7 @@
3703206927D2BB49007A0CB8 /* Alamofire */, 3703206927D2BB49007A0CB8 /* Alamofire */,
37CF8B8528535E5A00B71E37 /* SDWebImage */, 37CF8B8528535E5A00B71E37 /* SDWebImage */,
37A5DBC5285E06B100CA4DD1 /* SwiftUIPager */, 37A5DBC5285E06B100CA4DD1 /* SwiftUIPager */,
372AA413286D06A10000B1DC /* Repeat */,
); );
productName = "Yattee (macOS)"; productName = "Yattee (macOS)";
productReference = 37D4B0CF2671614900C925CA /* Yattee.app */; productReference = 37D4B0CF2671614900C925CA /* Yattee.app */;
@ -2229,6 +2232,7 @@
37FB285327220D8400A57617 /* SDWebImagePINPlugin */, 37FB285327220D8400A57617 /* SDWebImagePINPlugin */,
3765917D27237D2A009F956E /* PINCache */, 3765917D27237D2A009F956E /* PINCache */,
37CF8B8728535E6300B71E37 /* SDWebImage */, 37CF8B8728535E6300B71E37 /* SDWebImage */,
372AA411286D06950000B1DC /* Repeat */,
); );
productName = Yattee; productName = Yattee;
productReference = 37D4B158267164AE00C925CA /* Yattee.app */; productReference = 37D4B158267164AE00C925CA /* Yattee.app */;
@ -2325,6 +2329,7 @@
3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */, 3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */,
37CF8B8228535E4F00B71E37 /* XCRemoteSwiftPackageReference "SDWebImage" */, 37CF8B8228535E4F00B71E37 /* XCRemoteSwiftPackageReference "SDWebImage" */,
37A5DBC2285DFF5400CA4DD1 /* XCRemoteSwiftPackageReference "SwiftUIPager" */, 37A5DBC2285DFF5400CA4DD1 /* XCRemoteSwiftPackageReference "SwiftUIPager" */,
372AA40E286D067B0000B1DC /* XCRemoteSwiftPackageReference "Repeat" */,
); );
productRefGroup = 37D4B0CA2671614900C925CA /* Products */; productRefGroup = 37D4B0CA2671614900C925CA /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -2660,7 +2665,6 @@
37136CAC286273060095C0CF /* PersistentSystemOverlays+Backport.swift in Sources */, 37136CAC286273060095C0CF /* PersistentSystemOverlays+Backport.swift in Sources */,
374C053527242D9F009BDDBE /* SponsorBlockSettings.swift in Sources */, 374C053527242D9F009BDDBE /* SponsorBlockSettings.swift in Sources */,
37BF661C27308859008CCFB0 /* DropFavorite.swift in Sources */, 37BF661C27308859008CCFB0 /* DropFavorite.swift in Sources */,
371114EB27B94C8800C2EF7B /* RepeatingTimer.swift in Sources */,
376A33E42720CB35000C1D6B /* Account.swift in Sources */, 376A33E42720CB35000C1D6B /* Account.swift in Sources */,
3756C2A62861131100E4B059 /* NetworkState.swift in Sources */, 3756C2A62861131100E4B059 /* NetworkState.swift in Sources */,
37BA794326DBA973002A0235 /* PlaylistsModel.swift in Sources */, 37BA794326DBA973002A0235 /* PlaylistsModel.swift in Sources */,
@ -2845,7 +2849,6 @@
37E2EEAC270656EC00170416 /* BrowserPlayerControls.swift in Sources */, 37E2EEAC270656EC00170416 /* BrowserPlayerControls.swift in Sources */,
37BF662027308884008CCFB0 /* DropFavoriteOutside.swift in Sources */, 37BF662027308884008CCFB0 /* DropFavoriteOutside.swift in Sources */,
37E70924271CD43000D34DDE /* WelcomeScreen.swift in Sources */, 37E70924271CD43000D34DDE /* WelcomeScreen.swift in Sources */,
371114EC27B94C8800C2EF7B /* RepeatingTimer.swift in Sources */,
374C0543272496E4009BDDBE /* AppDelegate.swift in Sources */, 374C0543272496E4009BDDBE /* AppDelegate.swift in Sources */,
373CFACC26966264003CB2C6 /* SearchQuery.swift in Sources */, 373CFACC26966264003CB2C6 /* SearchQuery.swift in Sources */,
37AAF29126740715007FC770 /* Channel.swift in Sources */, 37AAF29126740715007FC770 /* Channel.swift in Sources */,
@ -3030,7 +3033,6 @@
376578872685429C00D4EA09 /* CaseIterable+Next.swift in Sources */, 376578872685429C00D4EA09 /* CaseIterable+Next.swift in Sources */,
37D4B1802671650A00C925CA /* YatteeApp.swift in Sources */, 37D4B1802671650A00C925CA /* YatteeApp.swift in Sources */,
3748187026A769D60084E870 /* DetailBadge.swift in Sources */, 3748187026A769D60084E870 /* DetailBadge.swift in Sources */,
371114ED27B94C8800C2EF7B /* RepeatingTimer.swift in Sources */,
3741A32C27E7EFFD00D266D1 /* PlayerControls.swift in Sources */, 3741A32C27E7EFFD00D266D1 /* PlayerControls.swift in Sources */,
371B7E632759706A00D21217 /* CommentsView.swift in Sources */, 371B7E632759706A00D21217 /* CommentsView.swift in Sources */,
37A9965C26D6F8CA006E3224 /* HorizontalCells.swift in Sources */, 37A9965C26D6F8CA006E3224 /* HorizontalCells.swift in Sources */,
@ -4080,6 +4082,14 @@
minimumVersion = 6.0.0; minimumVersion = 6.0.0;
}; };
}; };
372AA40E286D067B0000B1DC /* XCRemoteSwiftPackageReference "Repeat" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/malcommac/Repeat.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.6.0;
};
};
3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */ = { 3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/pinterest/PINCache"; repositoryURL = "https://github.com/pinterest/PINCache";
@ -4221,6 +4231,21 @@
package = 372915E22687E33E00F5A35B /* XCRemoteSwiftPackageReference "Defaults" */; package = 372915E22687E33E00F5A35B /* XCRemoteSwiftPackageReference "Defaults" */;
productName = Defaults; productName = Defaults;
}; };
372AA40F286D067B0000B1DC /* Repeat */ = {
isa = XCSwiftPackageProductDependency;
package = 372AA40E286D067B0000B1DC /* XCRemoteSwiftPackageReference "Repeat" */;
productName = Repeat;
};
372AA411286D06950000B1DC /* Repeat */ = {
isa = XCSwiftPackageProductDependency;
package = 372AA40E286D067B0000B1DC /* XCRemoteSwiftPackageReference "Repeat" */;
productName = Repeat;
};
372AA413286D06A10000B1DC /* Repeat */ = {
isa = XCSwiftPackageProductDependency;
package = 372AA40E286D067B0000B1DC /* XCRemoteSwiftPackageReference "Repeat" */;
productName = Repeat;
};
3765917B27237D21009F956E /* PINCache */ = { 3765917B27237D21009F956E /* PINCache */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = 3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */; package = 3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */;

View File

@ -45,6 +45,15 @@
"version" : "1.2.1" "version" : "1.2.1"
} }
}, },
{
"identity" : "repeat",
"kind" : "remoteSourceControl",
"location" : "https://github.com/malcommac/Repeat.git",
"state" : {
"revision" : "9df757d0936c15dfd9d01067766fab87e927f838",
"version" : "0.6.0"
}
},
{ {
"identity" : "sdwebimage", "identity" : "sdwebimage",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",