This repository has been archived on 2025-03-19. You can view files and clone it, but cannot push or open issues or pull requests.
Nook-Music/grandfatherrock/FirstViewController.swift
Micah Gomez 269815e253 !
2020-09-08 02:21:28 -06:00

879 lines
28 KiB
Swift

//
// FirstViewController.swift
// grandfatherrock
//
// Created by Micah Gomez on 4/15/20.
// Copyright © 2020 Micah Gomez. All rights reserved.
//
import UIKit
import AVFoundation
import MediaPlayer
import StoreKit
protocol ObjectSavable {
func setObject<Object>(_ object: Object, forKey: String) throws where Object: Encodable
func getObject<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable
}
enum ObjectSavableError: String, LocalizedError {
case unableToEncode = "Unable to encode object into data"
case noValue = "No data object found for the given key"
case unableToDecode = "Unable to decode object into given type"
var errorDescription: String? {
rawValue
}
}
extension UserDefaults: ObjectSavable {
func setObject<Object>(_ object: Object, forKey: String) throws where Object: Encodable {
let encoder = JSONEncoder()
do {
let data = try encoder.encode(object)
set(data, forKey: forKey)
} catch {
throw ObjectSavableError.unableToEncode
}
}
func getObject<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable {
guard let data = data(forKey: forKey) else { throw ObjectSavableError.noValue }
let decoder = JSONDecoder()
do {
let object = try decoder.decode(type, from: data)
return object
} catch {
throw ObjectSavableError.unableToDecode
}
}
}
public class musicHandler{
@objc class func updateMusic(){
timer.invalidate()
print("updating song")
GlobalVars.hour = Calendar.current.component(.hour, from: Date())
//song = GlobalVars.titleCode + hourPadding + String(GlobalVars.hour)
//print(song)
let musicPlayer = MPMusicPlayerController.applicationMusicPlayer
do{
var mediaPredicate = MPMediaPredicate()
switch GlobalVars.selectedMusicList {
case 0:
if(GlobalVars.musicSelectionID0[GlobalVars.hour] != 0){
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID0[GlobalVars.hour], forProperty: "persistentID")
} else {
var searchID:UInt64 = 0
var searchHour:Int = GlobalVars.hour
while (searchID == 0) {
if(searchHour > 0){
searchHour -= 1
} else {
searchHour = 23
}
if(searchHour == GlobalVars.hour){
print("no songs found!")
break
}
print("searching ", searchHour)
searchID = GlobalVars.musicSelectionID0[searchHour]
print(searchID)
}
print("Song Found!")
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID0[searchHour], forProperty: "persistentID")
}
case 1:
if(GlobalVars.musicSelectionID1[GlobalVars.hour] != 0){
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID1[GlobalVars.hour], forProperty: "persistentID")
} else {
var searchID:UInt64 = 0
var searchHour:Int = GlobalVars.hour
while (searchID == 0) {
if(searchHour > 0){
searchHour -= 1
} else {
searchHour = 23
}
if(searchHour == GlobalVars.hour){
print("no songs found!")
break
}
print("searching ", searchHour)
searchID = GlobalVars.musicSelectionID1[searchHour]
print(searchID)
}
print("Song Found!")
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID1[searchHour], forProperty: "persistentID")
}
case 2:
if(GlobalVars.musicSelectionID2[GlobalVars.hour] != 0){
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID2[GlobalVars.hour], forProperty: "persistentID")
} else {
var searchID:UInt64 = 0
var searchHour:Int = GlobalVars.hour
while (searchID == 0) {
if(searchHour > 0){
searchHour -= 1
} else {
searchHour = 23
}
if(searchHour == GlobalVars.hour){
print("no songs found!")
break
}
print("searching ", searchHour)
searchID = GlobalVars.musicSelectionID2[searchHour]
print(searchID)
}
print("Song Found!")
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID2[searchHour], forProperty: "persistentID")
}
case 3:
if(GlobalVars.musicSelectionID3[GlobalVars.hour] != 0){
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID3[GlobalVars.hour], forProperty: "persistentID")
} else {
var searchID:UInt64 = 0
var searchHour:Int = GlobalVars.hour
while (searchID == 0) {
if(searchHour > 0){
searchHour -= 1
} else {
searchHour = 23
}
if(searchHour == GlobalVars.hour){
print("no songs found!")
break
}
print("searching ", searchHour)
searchID = GlobalVars.musicSelectionID3[searchHour]
print(searchID)
}
print("Song Found!")
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID3[searchHour], forProperty: "persistentID")
}
case 4:
if(GlobalVars.musicSelectionID4[GlobalVars.hour] != 0){
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID4[GlobalVars.hour], forProperty: "persistentID")
} else {
var searchID:UInt64 = 0
var searchHour:Int = GlobalVars.hour
while (searchID == 0) {
if(searchHour > 0){
searchHour -= 1
} else {
searchHour = 23
}
if(searchHour == GlobalVars.hour){
print("no songs found!")
break
}
print("searching ", searchHour)
searchID = GlobalVars.musicSelectionID4[searchHour]
print(searchID)
}
print("Song Found!")
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID4[searchHour], forProperty: "persistentID")
}
default:
if(GlobalVars.musicSelectionID0[GlobalVars.hour] != 0){
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID0[GlobalVars.hour], forProperty: "persistentID")
} else {
var searchID:UInt64 = 0
var searchHour:Int = GlobalVars.hour
while (searchID == 0) {
if(searchHour > 0){
searchHour -= 1
} else {
searchHour = 23
}
if(searchHour == GlobalVars.hour){
print("no songs found!")
break
}
print("searching ", searchHour)
searchID = GlobalVars.musicSelectionID0[searchHour]
print(searchID)
}
print("Song Found!")
mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID0[searchHour], forProperty: "persistentID")
}
}
//let mediaPredicate = MPMediaPropertyPredicate(value: GlobalVars.musicSelectionID1[GlobalVars.hour], forProperty: "persistentID")
let mediaQuery = MPMediaQuery()
mediaQuery.addFilterPredicate(mediaPredicate)
//let mediaItemCollection: MPMediaItemCollection = MPMediaItemCollection()
musicPlayer.setQueue(with: mediaQuery)
print(mediaQuery)
//musicPlayer.play()
}
if(MPMusicPlayerController.applicationMusicPlayer.playbackState == MPMusicPlaybackState.playing){
musicPlayer.play()
}
if(Calendar.current.component(.minute, from: Date()) == 0){
date = Date().addingTimeInterval(3600)
} else{
let currentMinute = Calendar.current.component(.minute, from: Date())
let currentSeconds = Calendar.current.component(.second, from: Date())
let timeTillTopOfTheHour = 3600 - currentSeconds - (currentMinute * 60)
date = Date().addingTimeInterval(TimeInterval(timeTillTopOfTheHour))
}
print(date)
timer = Timer(fireAt: date, interval: 0, target: self, selector: #selector(updateMusic), userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
}
}
struct GlobalVars {
static var musicSelectionID0:[UInt64] = [UInt64]()
static var musicSelection0:[String] = [String]()
static var musicSelectionID1:[UInt64] = [UInt64]()
static var musicSelection1:[String] = [String]()
static var musicSelectionID2:[UInt64] = [UInt64]()
static var musicSelection2:[String] = [String]()
static var musicSelectionID3:[UInt64] = [UInt64]()
static var musicSelection3:[String] = [String]()
static var musicSelectionID4:[UInt64] = [UInt64]()
static var musicSelection4:[String] = [String]()
static var selectedMusicList:Int = 0
static var musicStarted = false
static var titleName = UserDefaults.standard.string(forKey: "selectedTitle")
static var hour = Calendar.current.component(.hour, from: Date())
}
var i = 0
var date = Date()
var timer = Timer()
let currentSeconds = Calendar.current.component(.second, from: Date())
let currentMinute = Calendar.current.component(.minute, from: Date())
let timeTillTopOfTheHour = 3600 - currentSeconds - (currentMinute * 60)
var hourPadding = ""
var prevVol = 0.0
class FirstViewController: UIViewController{
let defaults = UserDefaults.standard
let musicPlayer = MPMusicPlayerController.applicationMusicPlayer
//@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var timeLabel: UILabel!
var labelTimer = Timer()
@objc func tick() {
//dateLabel.text = DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .none)
timeLabel.text = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .short)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
musicPlayer.stop()
GlobalVars.musicStarted = false
IAPHandler.shared.fetchAvailableProducts()
IAPHandler.shared.purchaseStatusBlock = {[weak self] (type) in
guard let strongSelf = self else{ return }
if type == .purchased {
let alertView = UIAlertController(title: "", message: type.message(), preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: { (alert) in
})
alertView.addAction(action)
strongSelf.present(alertView, animated: true, completion: nil)
}
}
if(!defaults.bool(forKey: "didRun")){
defaults.set("New Horizons", forKey: "selectedTitle")
defaults.set(0, forKey: "titleNo")
//defaults.set(true, forKey: "didRun")
GlobalVars.musicSelectionID0 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
GlobalVars.musicSelection0 = ["","","","","","","","","","","","","","","","","","","","","","","",""]
GlobalVars.musicSelectionID1 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
GlobalVars.musicSelection1 = ["","","","","","","","","","","","","","","","","","","","","","","",""]
GlobalVars.musicSelectionID2 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
GlobalVars.musicSelection2 = ["","","","","","","","","","","","","","","","","","","","","","","",""]
GlobalVars.musicSelectionID3 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
GlobalVars.musicSelection3 = ["","","","","","","","","","","","","","","","","","","","","","","",""]
GlobalVars.musicSelectionID4 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
GlobalVars.musicSelection4 = ["","","","","","","","","","","","","","","","","","","","","","","",""]
do {
try defaults.setObject(GlobalVars.musicSelection0, forKey: "savedMusicSelection0")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID0, forKey: "savedMusicSelectionID0")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection1, forKey: "savedMusicSelection1")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID1, forKey: "savedMusicSelectionID1")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection2, forKey: "savedMusicSelection2")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID2, forKey: "savedMusicSelectionID2")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection3, forKey: "savedMusicSelection3")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID3, forKey: "savedMusicSelectionID3")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection4, forKey: "savedMusicSelection4")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID4, forKey: "savedMusicSelectionID4")
} catch {
print(error.localizedDescription)
}
print("First App run")
} else {
do {
GlobalVars.musicSelection0 = try defaults.getObject(forKey: "savedMusicSelection0", castTo: [String].self)
print(GlobalVars.musicSelection0)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelectionID0 = try defaults.getObject(forKey: "savedMusicSelectionID0", castTo: [UInt64].self)
print(GlobalVars.musicSelectionID0)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelection1 = try defaults.getObject(forKey: "savedMusicSelection1", castTo: [String].self)
print(GlobalVars.musicSelection1)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelectionID1 = try defaults.getObject(forKey: "savedMusicSelectionID1", castTo: [UInt64].self)
print(GlobalVars.musicSelectionID1)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelection2 = try defaults.getObject(forKey: "savedMusicSelection2", castTo: [String].self)
print(GlobalVars.musicSelection2)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelectionID2 = try defaults.getObject(forKey: "savedMusicSelectionID2", castTo: [UInt64].self)
print(GlobalVars.musicSelectionID2)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelection3 = try defaults.getObject(forKey: "savedMusicSelection3", castTo: [String].self)
print(GlobalVars.musicSelection3)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelectionID3 = try defaults.getObject(forKey: "savedMusicSelectionID3", castTo: [UInt64].self)
print(GlobalVars.musicSelectionID3)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelection4 = try defaults.getObject(forKey: "savedMusicSelection4", castTo: [String].self)
print(GlobalVars.musicSelection4)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.musicSelectionID4 = try defaults.getObject(forKey: "savedMusicSelectionID4", castTo: [UInt64].self)
print(GlobalVars.musicSelectionID4)
} catch {
print(error.localizedDescription)
}
do {
GlobalVars.selectedMusicList = try defaults.getObject(forKey: "savedSelectedMusicList", castTo: Int.self)
print(GlobalVars.selectedMusicList)
} catch {
print(error.localizedDescription)
}
print("App Ran Before")
}
print(currentSeconds)
print(currentMinute)
print(timeTillTopOfTheHour)
//print(GlobalVars.selectedSong)
GlobalVars.hour = Calendar.current.component(.hour, from: Date())
date = Date().addingTimeInterval(TimeInterval(timeTillTopOfTheHour))
print(date)
timer = Timer(fireAt: date, interval: 0, target: musicHandler.self, selector: #selector(musicHandler.updateMusic), userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: .common)
//dateLabel.text = DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .none)
timeLabel.text = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .short)
labelTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector:#selector(self.tick) , userInfo: nil, repeats: true)
/*do{
audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: song, ofType: "mp3")!))
audioPlayer.prepareToPlay()
audioPlayer.numberOfLoops = -1
let audioSession = AVAudioSession.sharedInstance()
do{
try audioSession.setCategory(.playback, mode: .default)
try audioSession.setActive(true)
}
}
catch{
print(error)
}*/
}
@IBOutlet var gradientView: UIView!
override func viewDidAppear(_ animated: Bool) {
print("fuck!")
if (!defaults.bool(forKey: "didRun")){
let fuckAlert = UIAlertController(title: "Welcome!", message: "Please visit the 'Select Music' tab to set your hourly playlist, and come back here and hit play once it's ready!", preferredStyle: .alert)
// Create OK button
let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
print("Ok button tapped");
}
fuckAlert.addAction(OKAction)
// Present Dialog message
self.present(fuckAlert, animated: true, completion:nil)
defaults.set(true, forKey: "didRun")
}
var foundSong = false
switch GlobalVars.selectedMusicList {
case 0:
for i in GlobalVars.musicSelectionID0 {
if (i != 0){
foundSong = true
}
}
case 1:
for i in GlobalVars.musicSelectionID1 {
if (i != 0){
foundSong = true
}
}
case 2:
for i in GlobalVars.musicSelectionID2 {
if (i != 0){
foundSong = true
}
}
case 3:
for i in GlobalVars.musicSelectionID3 {
if (i != 0){
foundSong = true
}
}
case 4:
for i in GlobalVars.musicSelectionID4 {
if (i != 0){
foundSong = true
}
}
default:
for i in GlobalVars.musicSelectionID0 {
if (i != 0){
foundSong = true
}
}
}
if !foundSong && defaults.bool(forKey: "didRun") {
let errorAlert = UIAlertController(title: "Song Error", message: "No songs found in this track. Please visit the 'Select Music' tab to set a song and get started!", preferredStyle: .alert)
// Create OK button
let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
print("Ok button tapped");
}
errorAlert.addAction(OKAction)
// Present Dialog message
self.present(errorAlert, animated: true, completion:nil)
print("Song is missing for at one hour")
controlButton.isEnabled = false
} else {
controlButton.isEnabled = true
}
self.view.layoutIfNeeded()
}
override func viewWillAppear(_ animated: Bool) {
// create the gradient layer
let gradient = CAGradientLayer()
gradient.frame = self.view.bounds
print("time: ", GlobalVars.hour)
if((GlobalVars.hour >= 8) && (GlobalVars.hour <= 19)){ //Daytime
print("day")
gradient.colors = [UIColor(red: 0.39, green: 0.69, blue: 1.00, alpha: 1).cgColor, UIColor(red: 0.07, green: 0.45, blue: 0.87, alpha: 1).cgColor]
} else if((GlobalVars.hour >= 20) && (GlobalVars.hour <= 21)){//Sunset
print("sunset")
gradient.colors = [UIColor(red: 0.00, green: 0.31, blue: 0.59, alpha: 1).cgColor, UIColor(red: 1.00, green: 0.78, blue: 0.88, alpha: 1).cgColor]
} else if((GlobalVars.hour >= 22) || (GlobalVars.hour <= 5)){//Night
print("night")
gradient.colors = [UIColor(red: 0.08, green: 0.27, blue: 0.59, alpha: 1).cgColor, UIColor(red: 0.00, green: 0.20, blue: 0.29, alpha: 1).cgColor]
} else if((GlobalVars.hour >= 6) && (GlobalVars.hour <= 7)){//Sunrise
print("sunrise")
gradient.colors = [UIColor(red: 0.02, green: 0.26, blue: 0.49, alpha: 1).cgColor, UIColor(red: 0.89, green: 0.68, blue: 0.60, alpha: 1).cgColor]
}
gradient.locations = [0.00, 1.00]
/*let gradientChangeAnimation = CABasicAnimation(keyPath: "colors")
gradientChangeAnimation.duration = 5.0
if((GlobalVars.hour >= 8) && (GlobalVars.hour <= 19)){ //Daytime
print("day")
gradientChangeAnimation.toValue = [UIColor(red: 0.00, green: 0.31, blue: 0.59, alpha: 1).cgColor, UIColor(red: 0.07, green: 0.45, blue: 0.87, alpha: 1).cgColor]
} else if((GlobalVars.hour >= 20) && (GlobalVars.hour <= 21)){//Sunset
print("sunset")
gradientChangeAnimation.toValue = [UIColor(red: 0.00, green: 0.31, blue: 0.59, alpha: 1).cgColor, UIColor(red: 1.00, green: 0.61, blue: 0.43, alpha: 1).cgColor]
} else if((GlobalVars.hour >= 22) || (GlobalVars.hour <= 5)){//Night
print("night")
gradientChangeAnimation.toValue = [
UIColor(red: 0.68, green: 0.67, blue: 1.0, alpha: 1).cgColor,
UIColor(red: 1.00, green: 0.00, blue: 0.09, alpha: 1).cgColor
]
} else if((GlobalVars.hour >= 6) && (GlobalVars.hour <= 7)){//Sunrise
print("sunrise")
gradientChangeAnimation.toValue = [UIColor(red: 0.02, green: 0.26, blue: 0.49, alpha: 1).cgColor, UIColor(red: 0.89, green: 0.68, blue: 0.60, alpha: 1).cgColor]
}
gradientChangeAnimation.autoreverses = true
gradientChangeAnimation.fillMode = CAMediaTimingFillMode.forwards
gradientChangeAnimation.isRemovedOnCompletion = false
gradient.add(gradientChangeAnimation, forKey: "colorChange")
*/
// add the gradient to the view
gradientView.layer.addSublayer(gradient)
if (MPMusicPlayerController.applicationMusicPlayer.playbackState == MPMusicPlaybackState.playing) {
GlobalVars.musicStarted = true
controlButton.setBackgroundImage(UIImage(systemName: "pause.circle"), for: UIControl.State.normal)
UIView.animate(withDuration: 0.4, delay: 0,usingSpringWithDamping: 0.5,initialSpringVelocity: 0){
self.PlayButtonSize.constant = 130
}
} else {
GlobalVars.musicStarted = false
controlButton.setBackgroundImage(UIImage(systemName: "play.circle"), for: UIControl.State.normal)
UIView.animate(withDuration: 0.4, delay: 0,usingSpringWithDamping: 0.5,initialSpringVelocity: 0){
self.PlayButtonSize.constant = 90
}
}
}
override func viewWillDisappear(_ animated: Bool) {
gradientView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
do {
try defaults.setObject(GlobalVars.musicSelection0, forKey: "savedMusicSelection0")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID0, forKey: "savedMusicSelectionID0")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection1, forKey: "savedMusicSelection1")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID1, forKey: "savedMusicSelectionID1")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection2, forKey: "savedMusicSelection2")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID2, forKey: "savedMusicSelectionID2")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection3, forKey: "savedMusicSelection3")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID3, forKey: "savedMusicSelectionID3")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelection4, forKey: "savedMusicSelection4")
} catch {
print(error.localizedDescription)
}
do {
try defaults.setObject(GlobalVars.musicSelectionID4, forKey: "savedMusicSelectionID4")
} catch {
print(error.localizedDescription)
}
}
@IBOutlet weak var controlButton: UIButton!
@IBOutlet var PlayButtonSize: NSLayoutConstraint!
@IBAction func play(_ sender: Any) {
if(!GlobalVars.musicStarted){
GlobalVars.musicStarted = true
musicHandler.updateMusic()
let musicPlayer = MPMusicPlayerController.applicationMusicPlayer
musicPlayer.play()
GlobalVars.musicStarted = true
controlButton.setBackgroundImage(UIImage(systemName: "pause.circle"), for: UIControl.State.normal)
UIView.animate(withDuration: 0.4,delay:0,usingSpringWithDamping: 0.5,initialSpringVelocity: 0){
self.PlayButtonSize.constant = 130
self.view.layoutIfNeeded()
}
}
else{
let musicPlayer = MPMusicPlayerController.applicationMusicPlayer
musicPlayer.pause()
GlobalVars.musicStarted = false
controlButton.setBackgroundImage(UIImage(systemName: "play.circle"), for: UIControl.State.normal)
UIView.animate(withDuration: 0.4, delay: 0,usingSpringWithDamping: 0.5,initialSpringVelocity: 0){
self.PlayButtonSize.constant = 90
self.view.layoutIfNeeded()
}
}
}
/*@objc func updateMusic(){
//timer.invalidate()
prevVol = Double(audioPlayer.volume)
audioPlayer.setVolume(0, fadeDuration: 3)
print("updating song")
hour = Calendar.current.component(.hour, from: date)
if(hour<10){
hourPadding = "0"
}
else{
hourPadding = ""
}
song = "acnh" + hourPadding + String(hour)
print(song)
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: song, ofType: "mp3")!))
audioPlayer.prepareToPlay()
audioPlayer.numberOfLoops = -1
let audioSession = AVAudioSession.sharedInstance()
do{
try audioSession.setCategory(.playback, mode: .default)
try audioSession.setActive(true)
}
}
catch{
print(error)
}
if(GlobalVars.musicStarted){
audioPlayer.play()
}
audioPlayer.setVolume(Float(prevVol), fadeDuration: 1)
date = date.addingTimeInterval(3600)
print(date)
timer = Timer(fireAt: date, interval: 0, target: self, selector: #selector(updateMusic), userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
}*/
}
enum IAPHandlerAlertType{
case disabled
case restored
case purchased
func message() -> String{
switch self {
case .disabled: return "Purchases are disabled in your device!"
case .restored: return "You've successfully restored your purchase!"
case .purchased: return "You've successfully bought this purchase!"
}
}
}
class IAPHandler: NSObject {
static let shared = IAPHandler()
let SMALL_TIP_PRODUCT_ID = "smalltip"
let MEDIUM_TIP_PRODUCT_ID = "mediumtip"
let LARGE_TIP_PRODUCT_ID = "largetip"
fileprivate var productID = ""
fileprivate var productsRequest = SKProductsRequest()
fileprivate var iapProducts = [SKProduct]()
var purchaseStatusBlock: ((IAPHandlerAlertType) -> Void)?
// MARK: - MAKE PURCHASE OF A PRODUCT
func canMakePurchases() -> Bool { return SKPaymentQueue.canMakePayments() }
func purchaseMyProduct(index: Int){
if iapProducts.count == 0 { return }
if self.canMakePurchases() {
let product = iapProducts[index]
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment)
print("PRODUCT TO PURCHASE: \(product.productIdentifier)")
productID = product.productIdentifier
} else {
purchaseStatusBlock?(.disabled)
}
}
// MARK: - RESTORE PURCHASE
func restorePurchase(){
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
// MARK: - FETCH AVAILABLE IAP PRODUCTS
func fetchAvailableProducts(){
// Put here your IAP Products ID's
let productIdentifiers = NSSet(objects: SMALL_TIP_PRODUCT_ID,MEDIUM_TIP_PRODUCT_ID,LARGE_TIP_PRODUCT_ID
)
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
productsRequest.delegate = self
productsRequest.start()
}
}
extension IAPHandler: SKProductsRequestDelegate, SKPaymentTransactionObserver{
// MARK: - REQUEST IAP PRODUCTS
func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
if (response.products.count > 0) {
iapProducts = response.products
for product in iapProducts{
let numberFormatter = NumberFormatter()
numberFormatter.formatterBehavior = .behavior10_4
numberFormatter.numberStyle = .currency
numberFormatter.locale = product.priceLocale
let price1Str = numberFormatter.string(from: product.price)
print(product.localizedDescription + "\nfor just \(price1Str!)")
}
}
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
purchaseStatusBlock?(.restored)
}
// MARK:- IAP PAYMENT QUEUE
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction:AnyObject in transactions {
if let trans = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .purchased:
print("purchased")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
purchaseStatusBlock?(.purchased)
break
case .failed:
print("failed")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
break
case .restored:
print("restored")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
break
default: break
}}}
}
}