Skip to content

Commit

Permalink
Add playback time tracker (local)
Browse files Browse the repository at this point in the history
  • Loading branch information
GianniCarlo committed Apr 6, 2019
1 parent f848897 commit 7ba5ef9
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 3 deletions.
8 changes: 8 additions & 0 deletions BookPlayer.xcodeproj/project.pbxproj
Expand Up @@ -14,6 +14,8 @@
4112AFD6223AD27D00BFEA55 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4112AFD5223AD27D00BFEA55 /* Sentry.framework */; }; 4112AFD6223AD27D00BFEA55 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4112AFD5223AD27D00BFEA55 /* Sentry.framework */; };
412451841D489204008AC0E5 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 412451821D489204008AC0E5 /* Crashlytics.framework */; }; 412451841D489204008AC0E5 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 412451821D489204008AC0E5 /* Crashlytics.framework */; };
413616401D2E21F000E48944 /* LibraryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4136163F1D2E21F000E48944 /* LibraryViewController.swift */; }; 413616401D2E21F000E48944 /* LibraryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4136163F1D2E21F000E48944 /* LibraryViewController.swift */; };
413C7D9022580A0F009F3658 /* PlaybackRecord+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 413C7D8E22580A0F009F3658 /* PlaybackRecord+CoreDataClass.swift */; };
413C7D9122580A0F009F3658 /* PlaybackRecord+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 413C7D8F22580A0F009F3658 /* PlaybackRecord+CoreDataProperties.swift */; };
4142964421F21D95004356DA /* BulkControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4142964321F21D95004356DA /* BulkControlsView.swift */; }; 4142964421F21D95004356DA /* BulkControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4142964321F21D95004356DA /* BulkControlsView.swift */; };
4142964621F21DAE004356DA /* BulkControlsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4142964521F21DAE004356DA /* BulkControlsView.xib */; }; 4142964621F21DAE004356DA /* BulkControlsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4142964521F21DAE004356DA /* BulkControlsView.xib */; };
4142964921F2E2BA004356DA /* ThemeCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4142964721F2E2BA004356DA /* ThemeCellView.swift */; }; 4142964921F2E2BA004356DA /* ThemeCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4142964721F2E2BA004356DA /* ThemeCellView.swift */; };
Expand Down Expand Up @@ -185,6 +187,8 @@
4112AFD5223AD27D00BFEA55 /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = Carthage/Build/iOS/Sentry.framework; sourceTree = "<group>"; }; 4112AFD5223AD27D00BFEA55 /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = Carthage/Build/iOS/Sentry.framework; sourceTree = "<group>"; };
412451821D489204008AC0E5 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; }; 412451821D489204008AC0E5 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
4136163F1D2E21F000E48944 /* LibraryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryViewController.swift; sourceTree = "<group>"; }; 4136163F1D2E21F000E48944 /* LibraryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibraryViewController.swift; sourceTree = "<group>"; };
413C7D8E22580A0F009F3658 /* PlaybackRecord+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PlaybackRecord+CoreDataClass.swift"; sourceTree = "<group>"; };
413C7D8F22580A0F009F3658 /* PlaybackRecord+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PlaybackRecord+CoreDataProperties.swift"; sourceTree = "<group>"; };
4142964321F21D95004356DA /* BulkControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BulkControlsView.swift; sourceTree = "<group>"; }; 4142964321F21D95004356DA /* BulkControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BulkControlsView.swift; sourceTree = "<group>"; };
4142964521F21DAE004356DA /* BulkControlsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BulkControlsView.xib; sourceTree = "<group>"; }; 4142964521F21DAE004356DA /* BulkControlsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BulkControlsView.xib; sourceTree = "<group>"; };
4142964721F2E2BA004356DA /* ThemeCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeCellView.swift; sourceTree = "<group>"; }; 4142964721F2E2BA004356DA /* ThemeCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeCellView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -644,6 +648,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4165EDF920A743D500616EDF /* BookPlayer.xcdatamodeld */, 4165EDF920A743D500616EDF /* BookPlayer.xcdatamodeld */,
413C7D8E22580A0F009F3658 /* PlaybackRecord+CoreDataClass.swift */,
413C7D8F22580A0F009F3658 /* PlaybackRecord+CoreDataProperties.swift */,
41839AB120AA8B960047E55D /* Theme+CoreDataClass.swift */, 41839AB120AA8B960047E55D /* Theme+CoreDataClass.swift */,
41839AB220AA8B960047E55D /* Theme+CoreDataProperties.swift */, 41839AB220AA8B960047E55D /* Theme+CoreDataProperties.swift */,
41839AB520AA8C970047E55D /* Book+CoreDataClass.swift */, 41839AB520AA8C970047E55D /* Book+CoreDataClass.swift */,
Expand Down Expand Up @@ -1057,7 +1063,9 @@
410D0FED1EDCF4B000A52EB9 /* SettingsViewController.swift in Sources */, 410D0FED1EDCF4B000A52EB9 /* SettingsViewController.swift in Sources */,
41B2A5DE21CAF20E00917584 /* ThemesViewController.swift in Sources */, 41B2A5DE21CAF20E00917584 /* ThemesViewController.swift in Sources */,
C398559C20C492FF00BE9EC0 /* AddButton.swift in Sources */, C398559C20C492FF00BE9EC0 /* AddButton.swift in Sources */,
413C7D9022580A0F009F3658 /* PlaybackRecord+CoreDataClass.swift in Sources */,
4175E1242206CF9600FB7B71 /* DataManager+CoreData.swift in Sources */, 4175E1242206CF9600FB7B71 /* DataManager+CoreData.swift in Sources */,
413C7D9122580A0F009F3658 /* PlaybackRecord+CoreDataProperties.swift in Sources */,
C3EC372E206EE0650094B4E8 /* SleepTimer.swift in Sources */, C3EC372E206EE0650094B4E8 /* SleepTimer.swift in Sources */,
4165EE1220A7D1E100616EDF /* RootViewController.swift in Sources */, 4165EE1220A7D1E100616EDF /* RootViewController.swift in Sources */,
4165EE0820A743D500616EDF /* Playlist+CoreDataProperties.swift in Sources */, 4165EE0820A743D500616EDF /* Playlist+CoreDataProperties.swift in Sources */,
Expand Down
28 changes: 28 additions & 0 deletions BookPlayer/Library/DataManagement/DataManager+CoreData.swift
Expand Up @@ -262,4 +262,32 @@ extension DataManager {
item.markAsFinished(asFinished) item.markAsFinished(asFinished)
self.saveContext() self.saveContext()
} }

// MARK: - TimeRecord

class func getPlaybackRecord() -> PlaybackRecord {
let calendar = Calendar.current

let today = Date()
let dateFrom = calendar.startOfDay(for: today)
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)!

// Set predicate as date being today's date
let fromPredicate = NSPredicate(format: "%@ >= %@", today as NSDate, dateFrom as NSDate)
let toPredicate = NSPredicate(format: "%@ < %@", today as NSDate, dateTo as NSDate)
let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])

let context = self.persistentContainer.viewContext
let fetch: NSFetchRequest<PlaybackRecord> = PlaybackRecord.fetchRequest()
fetch.predicate = datePredicate

let record = try? context.fetch(fetch).first

return record ?? PlaybackRecord.create(in: context)
}

class func recordTime(_ playbackRecord: PlaybackRecord) {
playbackRecord.time += 1
self.saveContext()
}
} }
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="18D109" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14490.98" systemVersion="18D109" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Book" representedClassName=".Book" parentEntity="LibraryItem" syncable="YES"> <entity name="Book" representedClassName=".Book" parentEntity="LibraryItem" syncable="YES">
<attribute name="author" attributeType="String" syncable="YES"/> <attribute name="author" attributeType="String" syncable="YES"/>
<attribute name="ext" attributeType="String" syncable="YES"/> <attribute name="ext" attributeType="String" syncable="YES"/>
Expand Down Expand Up @@ -32,6 +32,10 @@
<attribute name="title" attributeType="String" syncable="YES"/> <attribute name="title" attributeType="String" syncable="YES"/>
<relationship name="library" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Library" inverseName="items" inverseEntity="Library" syncable="YES"/> <relationship name="library" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Library" inverseName="items" inverseEntity="Library" syncable="YES"/>
</entity> </entity>
<entity name="PlaybackRecord" representedClassName=".PlaybackRecord" syncable="YES">
<attribute name="date" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
<attribute name="time" attributeType="Double" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
</entity>
<entity name="Playlist" representedClassName=".Playlist" parentEntity="LibraryItem" syncable="YES"> <entity name="Playlist" representedClassName=".Playlist" parentEntity="LibraryItem" syncable="YES">
<attribute name="desc" attributeType="String" syncable="YES"/> <attribute name="desc" attributeType="String" syncable="YES"/>
<relationship name="books" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="Book" inverseName="playlist" inverseEntity="Book" syncable="YES"/> <relationship name="books" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="Book" inverseName="playlist" inverseEntity="Book" syncable="YES"/>
Expand All @@ -57,5 +61,6 @@
<element name="LibraryItem" positionX="-63" positionY="-18" width="128" height="193"/> <element name="LibraryItem" positionX="-63" positionY="-18" width="128" height="193"/>
<element name="Playlist" positionX="16" positionY="207" width="128" height="73"/> <element name="Playlist" positionX="16" positionY="207" width="128" height="73"/>
<element name="Theme" positionX="-261" positionY="330" width="128" height="225"/> <element name="Theme" positionX="-261" positionY="330" width="128" height="225"/>
<element name="PlaybackRecord" positionX="-54" positionY="135" width="128" height="75"/>
</elements> </elements>
</model> </model>
18 changes: 18 additions & 0 deletions BookPlayer/Models/PlaybackRecord+CoreDataClass.swift
@@ -0,0 +1,18 @@
//
// PlaybackRecord+CoreDataClass.swift
// BookPlayer
//
// Created by Gianni Carlo on 4/5/19.
// Copyright © 2019 Tortuga Power. All rights reserved.
//
//

import CoreData
import Foundation

public class PlaybackRecord: NSManagedObject {
public override func awakeFromInsert() {
super.awakeFromInsert()
setPrimitiveValue(Date(), forKey: "date")
}
}
25 changes: 25 additions & 0 deletions BookPlayer/Models/PlaybackRecord+CoreDataProperties.swift
@@ -0,0 +1,25 @@
//
// PlaybackRecord+CoreDataProperties.swift
// BookPlayer
//
// Created by Gianni Carlo on 4/5/19.
// Copyright © 2019 Tortuga Power. All rights reserved.
//
//

import CoreData
import Foundation

extension PlaybackRecord {
@nonobjc public class func fetchRequest() -> NSFetchRequest<PlaybackRecord> {
return NSFetchRequest<PlaybackRecord>(entityName: "PlaybackRecord")
}

@nonobjc public class func create(in context: NSManagedObjectContext) -> PlaybackRecord {
// swiftlint:disable force_cast
return NSEntityDescription.insertNewObject(forEntityName: "PlaybackRecord", into: context) as! PlaybackRecord
}

@NSManaged public var date: Date
@NSManaged public var time: Double
}
3 changes: 1 addition & 2 deletions BookPlayer/Player/PlayerManager.swift
Expand Up @@ -81,8 +81,6 @@ class PlayerManager: NSObject {
// Set speed for player // Set speed for player
audioplayer.rate = self.speed audioplayer.rate = self.speed


UserActivityManager.shared.resumePlaybackActivity()

NotificationCenter.default.post(name: .bookReady, object: nil, userInfo: ["book": book]) NotificationCenter.default.post(name: .bookReady, object: nil, userInfo: ["book": book])


completion(true) completion(true)
Expand All @@ -105,6 +103,7 @@ class PlayerManager: NSObject {
book.percentCompleted = book.percentage book.percentCompleted = book.percentage


DataManager.saveContext() DataManager.saveContext()
UserActivityManager.shared.recordTime()


// Notify // Notify
if isPercentageDifferent { if isPercentageDifferent {
Expand Down
18 changes: 18 additions & 0 deletions BookPlayer/Services/UserActivityManager.swift
Expand Up @@ -13,6 +13,7 @@ class UserActivityManager {
static let shared = UserActivityManager() static let shared = UserActivityManager()


var currentActivity: NSUserActivity var currentActivity: NSUserActivity
var playbackRecord: PlaybackRecord?


private init() { private init() {
let activity = NSUserActivity(activityType: Constants.UserActivityPlayback) let activity = NSUserActivity(activityType: Constants.UserActivityPlayback)
Expand All @@ -29,9 +30,26 @@ class UserActivityManager {


func resumePlaybackActivity() { func resumePlaybackActivity() {
self.currentActivity.becomeCurrent() self.currentActivity.becomeCurrent()

if self.playbackRecord == nil {
self.playbackRecord = DataManager.getPlaybackRecord()
}

guard let record = self.playbackRecord else { return }

guard !Calendar.current.isDate(record.date, inSameDayAs: Date()) else { return }

self.playbackRecord = DataManager.getPlaybackRecord()
} }


func stopPlaybackActivity() { func stopPlaybackActivity() {
self.currentActivity.resignCurrent() self.currentActivity.resignCurrent()
self.playbackRecord = nil
}

func recordTime() {
guard let record = self.playbackRecord else { return }

DataManager.recordTime(record)
} }
} }

0 comments on commit 7ba5ef9

Please sign in to comment.