working model for network layer, added user object
This commit is contained in:
parent
d91ce89670
commit
b80152ba13
@ -7,6 +7,12 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
E97AF45623FC4E7800635494 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97AF45523FC4E7800635494 /* User.swift */; };
|
||||||
|
E97AF45923FC50EC00635494 /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = E97AF45823FC50EC00635494 /* SwiftyJSON */; };
|
||||||
|
E97AF45B23FC748D00635494 /* UserApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97AF45A23FC748D00635494 /* UserApi.swift */; };
|
||||||
|
E97AF45E23FC83AF00635494 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = E97AF45D23FC83AF00635494 /* KeychainAccess */; };
|
||||||
|
E97AF46023FC85D600635494 /* PlaylistApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = E97AF45F23FC85D600635494 /* PlaylistApi.swift */; };
|
||||||
|
E97AF46223FC89CC00635494 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E97AF46123FC89CB00635494 /* Main.storyboard */; };
|
||||||
E98254BD23F9B7A90056D9D3 /* Playlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254BC23F9B7A90056D9D3 /* Playlist.swift */; };
|
E98254BD23F9B7A90056D9D3 /* Playlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254BC23F9B7A90056D9D3 /* Playlist.swift */; };
|
||||||
E98254C223F9FFF90056D9D3 /* PlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254C123F9FFF90056D9D3 /* PlaylistView.swift */; };
|
E98254C223F9FFF90056D9D3 /* PlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254C123F9FFF90056D9D3 /* PlaylistView.swift */; };
|
||||||
E98254C823FA25D20056D9D3 /* PlaylistList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254C723FA25D20056D9D3 /* PlaylistList.swift */; };
|
E98254C823FA25D20056D9D3 /* PlaylistList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254C723FA25D20056D9D3 /* PlaylistList.swift */; };
|
||||||
@ -42,6 +48,10 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
E97AF45523FC4E7800635494 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
|
||||||
|
E97AF45A23FC748D00635494 /* UserApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserApi.swift; sourceTree = "<group>"; };
|
||||||
|
E97AF45F23FC85D600635494 /* PlaylistApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistApi.swift; sourceTree = "<group>"; };
|
||||||
|
E97AF46123FC89CB00635494 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
|
||||||
E98254BC23F9B7A90056D9D3 /* Playlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Playlist.swift; sourceTree = "<group>"; };
|
E98254BC23F9B7A90056D9D3 /* Playlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Playlist.swift; sourceTree = "<group>"; };
|
||||||
E98254C123F9FFF90056D9D3 /* PlaylistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistView.swift; sourceTree = "<group>"; };
|
E98254C123F9FFF90056D9D3 /* PlaylistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistView.swift; sourceTree = "<group>"; };
|
||||||
E98254C723FA25D20056D9D3 /* PlaylistList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistList.swift; sourceTree = "<group>"; };
|
E98254C723FA25D20056D9D3 /* PlaylistList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistList.swift; sourceTree = "<group>"; };
|
||||||
@ -69,7 +79,9 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
E97AF45923FC50EC00635494 /* SwiftyJSON in Frameworks */,
|
||||||
E98254D923FB53780056D9D3 /* Alamofire in Frameworks */,
|
E98254D923FB53780056D9D3 /* Alamofire in Frameworks */,
|
||||||
|
E97AF45E23FC83AF00635494 /* KeychainAccess in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -94,6 +106,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E98254BC23F9B7A90056D9D3 /* Playlist.swift */,
|
E98254BC23F9B7A90056D9D3 /* Playlist.swift */,
|
||||||
|
E97AF45523FC4E7800635494 /* User.swift */,
|
||||||
);
|
);
|
||||||
path = Model;
|
path = Model;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -102,6 +115,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E98254DA23FB64740056D9D3 /* Network.swift */,
|
E98254DA23FB64740056D9D3 /* Network.swift */,
|
||||||
|
E97AF45A23FC748D00635494 /* UserApi.swift */,
|
||||||
|
E97AF45F23FC85D600635494 /* PlaylistApi.swift */,
|
||||||
);
|
);
|
||||||
path = Network;
|
path = Network;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -124,6 +139,7 @@
|
|||||||
E9EA691523F9A54B0012C3E8 /* LaunchScreen.storyboard */,
|
E9EA691523F9A54B0012C3E8 /* LaunchScreen.storyboard */,
|
||||||
E9EA690A23F9A5430012C3E8 /* AppDelegate.swift */,
|
E9EA690A23F9A5430012C3E8 /* AppDelegate.swift */,
|
||||||
E9EA690C23F9A5430012C3E8 /* SceneDelegate.swift */,
|
E9EA690C23F9A5430012C3E8 /* SceneDelegate.swift */,
|
||||||
|
E97AF46123FC89CB00635494 /* Main.storyboard */,
|
||||||
);
|
);
|
||||||
path = Application;
|
path = Application;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -206,6 +222,8 @@
|
|||||||
name = "Music Tools";
|
name = "Music Tools";
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
E98254D823FB53780056D9D3 /* Alamofire */,
|
E98254D823FB53780056D9D3 /* Alamofire */,
|
||||||
|
E97AF45823FC50EC00635494 /* SwiftyJSON */,
|
||||||
|
E97AF45D23FC83AF00635494 /* KeychainAccess */,
|
||||||
);
|
);
|
||||||
productName = "Music Tools";
|
productName = "Music Tools";
|
||||||
productReference = E9EA690723F9A5430012C3E8 /* Music Tools.app */;
|
productReference = E9EA690723F9A5430012C3E8 /* Music Tools.app */;
|
||||||
@ -281,6 +299,8 @@
|
|||||||
mainGroup = E9EA68FE23F9A5430012C3E8;
|
mainGroup = E9EA68FE23F9A5430012C3E8;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */,
|
E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */,
|
||||||
|
E97AF45723FC50EC00635494 /* XCRemoteSwiftPackageReference "swiftyjson" */,
|
||||||
|
E97AF45C23FC83AF00635494 /* XCRemoteSwiftPackageReference "keychainaccess" */,
|
||||||
);
|
);
|
||||||
productRefGroup = E9EA690823F9A5430012C3E8 /* Products */;
|
productRefGroup = E9EA690823F9A5430012C3E8 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -301,6 +321,7 @@
|
|||||||
E9EA691723F9A54B0012C3E8 /* LaunchScreen.storyboard in Resources */,
|
E9EA691723F9A54B0012C3E8 /* LaunchScreen.storyboard in Resources */,
|
||||||
E9EA691423F9A54B0012C3E8 /* Preview Assets.xcassets in Resources */,
|
E9EA691423F9A54B0012C3E8 /* Preview Assets.xcassets in Resources */,
|
||||||
E9EA691123F9A54A0012C3E8 /* Assets.xcassets in Resources */,
|
E9EA691123F9A54A0012C3E8 /* Assets.xcassets in Resources */,
|
||||||
|
E97AF46223FC89CC00635494 /* Main.storyboard in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -329,11 +350,14 @@
|
|||||||
E9EA690B23F9A5430012C3E8 /* AppDelegate.swift in Sources */,
|
E9EA690B23F9A5430012C3E8 /* AppDelegate.swift in Sources */,
|
||||||
E9EA690D23F9A5430012C3E8 /* SceneDelegate.swift in Sources */,
|
E9EA690D23F9A5430012C3E8 /* SceneDelegate.swift in Sources */,
|
||||||
E98254DB23FB64740056D9D3 /* Network.swift in Sources */,
|
E98254DB23FB64740056D9D3 /* Network.swift in Sources */,
|
||||||
|
E97AF46023FC85D600635494 /* PlaylistApi.swift in Sources */,
|
||||||
E98254C823FA25D20056D9D3 /* PlaylistList.swift in Sources */,
|
E98254C823FA25D20056D9D3 /* PlaylistList.swift in Sources */,
|
||||||
E9EA690F23F9A5430012C3E8 /* RootView.swift in Sources */,
|
E9EA690F23F9A5430012C3E8 /* RootView.swift in Sources */,
|
||||||
E98254BD23F9B7A90056D9D3 /* Playlist.swift in Sources */,
|
E98254BD23F9B7A90056D9D3 /* Playlist.swift in Sources */,
|
||||||
E98254C223F9FFF90056D9D3 /* PlaylistView.swift in Sources */,
|
E98254C223F9FFF90056D9D3 /* PlaylistView.swift in Sources */,
|
||||||
|
E97AF45623FC4E7800635494 /* User.swift in Sources */,
|
||||||
E98254D023FB00B60056D9D3 /* LoginScreen.swift in Sources */,
|
E98254D023FB00B60056D9D3 /* LoginScreen.swift in Sources */,
|
||||||
|
E97AF45B23FC748D00635494 /* UserApi.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -660,6 +684,22 @@
|
|||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
E97AF45723FC50EC00635494 /* XCRemoteSwiftPackageReference "swiftyjson" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/swiftyjson/swiftyjson";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 5.0.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
E97AF45C23FC83AF00635494 /* XCRemoteSwiftPackageReference "keychainaccess" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/kishikawakatsumi/keychainaccess";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 4.1.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */ = {
|
E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/alamofire/alamofire.git";
|
repositoryURL = "https://github.com/alamofire/alamofire.git";
|
||||||
@ -671,6 +711,16 @@
|
|||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
E97AF45823FC50EC00635494 /* SwiftyJSON */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = E97AF45723FC50EC00635494 /* XCRemoteSwiftPackageReference "swiftyjson" */;
|
||||||
|
productName = SwiftyJSON;
|
||||||
|
};
|
||||||
|
E97AF45D23FC83AF00635494 /* KeychainAccess */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = E97AF45C23FC83AF00635494 /* XCRemoteSwiftPackageReference "keychainaccess" */;
|
||||||
|
productName = KeychainAccess;
|
||||||
|
};
|
||||||
E98254D823FB53780056D9D3 /* Alamofire */ = {
|
E98254D823FB53780056D9D3 /* Alamofire */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */;
|
package = E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */;
|
||||||
|
@ -9,6 +9,24 @@
|
|||||||
"revision": "0c8cb78d05b6d067ee331c05058ff4dedcb45ffa",
|
"revision": "0c8cb78d05b6d067ee331c05058ff4dedcb45ffa",
|
||||||
"version": "5.0.0"
|
"version": "5.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "KeychainAccess",
|
||||||
|
"repositoryURL": "https://github.com/kishikawakatsumi/keychainaccess",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "b920ad7df3c73189dcdd4aa05c540849b2010dbf",
|
||||||
|
"version": "4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "SwiftyJSON",
|
||||||
|
"repositoryURL": "https://github.com/swiftyjson/swiftyjson",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "2b6054efa051565954e1d2b9da831680026cd768",
|
||||||
|
"version": "5.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
7
Music Tools/Application/Main.storyboard
Normal file
7
Music Tools/Application/Main.storyboard
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes/>
|
||||||
|
</document>
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import KeychainAccess
|
||||||
|
|
||||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
|
||||||
@ -22,6 +23,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
// Create the SwiftUI view that provides the window contents.
|
// Create the SwiftUI view that provides the window contents.
|
||||||
let contentView = RootView()
|
let contentView = RootView()
|
||||||
|
|
||||||
|
let keychain = Keychain(service: "xyz.sarsoo.music.login")
|
||||||
|
keychain["username"] = ""
|
||||||
|
keychain["password"] = ""
|
||||||
|
|
||||||
// Use a UIHostingController as window root view controller.
|
// Use a UIHostingController as window root view controller.
|
||||||
if let windowScene = scene as? UIWindowScene {
|
if let windowScene = scene as? UIWindowScene {
|
||||||
let window = UIWindow(windowScene: windowScene)
|
let window = UIWindow(windowScene: windowScene)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import SwiftyJSON
|
||||||
|
|
||||||
class Playlist: Identifiable {
|
class Playlist: Identifiable {
|
||||||
|
|
||||||
@ -55,5 +55,19 @@ class Playlist: Identifiable {
|
|||||||
self.shuffle = shuffle
|
self.shuffle = shuffle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func fromDict(dictionary: JSON) -> Playlist {
|
||||||
|
return Playlist(name: dictionary["name"].stringValue,
|
||||||
|
uri: dictionary["uri"].stringValue,
|
||||||
|
username: dictionary["username"].stringValue,
|
||||||
|
|
||||||
|
include_recommendations: dictionary["include_recommendations"].boolValue,
|
||||||
|
recommendation_sample: dictionary["recommendation_sample"].intValue,
|
||||||
|
include_library_tracks: dictionary["include_library_tracks"].boolValue,
|
||||||
|
|
||||||
|
parts: dictionary["parts"].arrayObject as! Array<String>,
|
||||||
|
playlist_references: dictionary["playlist_references"].arrayObject as! Array<String>,
|
||||||
|
|
||||||
|
shuffle: dictionary["shuffle"].boolValue)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
58
Music Tools/Model/User.swift
Normal file
58
Music Tools/Model/User.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// User.swift
|
||||||
|
// Music Tools
|
||||||
|
//
|
||||||
|
// Created by Andy Pack on 18/02/2020.
|
||||||
|
// Copyright © 2020 Sarsoo. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SwiftyJSON
|
||||||
|
|
||||||
|
enum UserType: String {
|
||||||
|
case user = "user"
|
||||||
|
case admin = "admin"
|
||||||
|
}
|
||||||
|
|
||||||
|
class User: Identifiable {
|
||||||
|
|
||||||
|
//MARK: Properties
|
||||||
|
|
||||||
|
var username: String
|
||||||
|
var email: String?
|
||||||
|
var type: UserType
|
||||||
|
|
||||||
|
var last_login: String
|
||||||
|
var spotify_linked: Bool
|
||||||
|
var lastfm_username: String?
|
||||||
|
|
||||||
|
//MARK: Initialization
|
||||||
|
|
||||||
|
init(username: String,
|
||||||
|
email: String?,
|
||||||
|
type: UserType = .user,
|
||||||
|
|
||||||
|
last_login: String,
|
||||||
|
spotify_linked: Bool,
|
||||||
|
lastfm_username: String?){
|
||||||
|
|
||||||
|
self.username = username
|
||||||
|
self.email = email
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
self.last_login = last_login
|
||||||
|
self.spotify_linked = spotify_linked
|
||||||
|
self.lastfm_username = lastfm_username
|
||||||
|
}
|
||||||
|
|
||||||
|
static func fromDict(dictionary: JSON) -> User {
|
||||||
|
return User(username: dictionary["username"].stringValue,
|
||||||
|
email: dictionary["username"].stringValue,
|
||||||
|
type: UserType(rawValue: dictionary["type"].stringValue) ?? .user,
|
||||||
|
last_login: dictionary["last_login"].stringValue,
|
||||||
|
spotify_linked: dictionary["spotify_linked"].boolValue,
|
||||||
|
lastfm_username: dictionary["lastfm_username"].stringValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -8,73 +8,63 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import Alamofire
|
import Alamofire
|
||||||
|
import SwiftyJSON
|
||||||
|
import KeychainAccess
|
||||||
|
|
||||||
class MusicToolsNetwork {
|
public enum AuthMethod {
|
||||||
|
case basic
|
||||||
|
|
||||||
var baseBath: String = "https://music.sarsoo.xyz/"
|
func auth(headers: Alamofire.HTTPHeaders?) -> Alamofire.HTTPHeaders {
|
||||||
|
switch self {
|
||||||
|
case .basic:
|
||||||
|
var txHeaders = headers ?? HTTPHeaders()
|
||||||
|
|
||||||
public func request(path: String,
|
let keychain = Keychain(service: "xyz.sarsoo.music.login")
|
||||||
method: Alamofire.HTTPMethod,
|
txHeaders.add(.authorization(username: keychain["username"] ?? "", password: keychain["password"] ?? ""))
|
||||||
parameters: [String:String]? ,
|
return txHeaders
|
||||||
encoder: Alamofire.ParameterEncoder?,
|
|
||||||
headers: Alamofire.HTTPHeaders? ) {
|
|
||||||
|
|
||||||
guard let uwParameters = parameters else {
|
|
||||||
AF.request(baseBath + path,
|
|
||||||
method: method,
|
|
||||||
headers: headers ).validate().response { response in
|
|
||||||
debugPrint(response)
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
AF.request(baseBath + path,
|
|
||||||
method: method,
|
|
||||||
parameters: uwParameters,
|
|
||||||
headers: headers ).response { response in
|
|
||||||
debugPrint(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicAuthNetwork: MusicToolsNetwork {
|
struct RequestBuilder {
|
||||||
var username: String
|
static func buildRequest(apiRequest: ApiRequest) -> Alamofire.DataRequest {
|
||||||
var password: String
|
|
||||||
|
|
||||||
init(username: String, password: String) {
|
let txHeaders = apiRequest.authMethod?.auth(headers: apiRequest.headers)
|
||||||
self.username = username
|
|
||||||
self.password = password
|
if apiRequest.parameters != nil {
|
||||||
|
if apiRequest.parameterType != nil {
|
||||||
|
|
||||||
|
let txEncoder = apiRequest.parameterType ?? JSONParameterEncoder.default
|
||||||
|
|
||||||
|
return AF.request(apiRequest.domain + apiRequest.path,
|
||||||
|
method: apiRequest.httpMethod,
|
||||||
|
parameters: apiRequest.parameters,
|
||||||
|
encoder: txEncoder,
|
||||||
|
headers: txHeaders)
|
||||||
|
} else {
|
||||||
|
return AF.request(apiRequest.domain + apiRequest.path,
|
||||||
|
method: apiRequest.httpMethod,
|
||||||
|
parameters: apiRequest.parameters,
|
||||||
|
headers: txHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHeader() -> String {
|
|
||||||
return "\(username):\(password)".toBase64()
|
|
||||||
}
|
}
|
||||||
|
return AF.request(apiRequest.domain + apiRequest.path,
|
||||||
public func authedRequest(path: String,
|
method: apiRequest.httpMethod,
|
||||||
method: Alamofire.HTTPMethod,
|
headers: txHeaders)
|
||||||
parameters: [String:String]?,
|
|
||||||
encoder: Alamofire.ParameterEncoder?,
|
|
||||||
headers: Alamofire.HTTPHeaders? ) {
|
|
||||||
|
|
||||||
let encoded = "\(username):\(password)".toBase64()
|
|
||||||
|
|
||||||
var txHeaders = headers
|
|
||||||
|
|
||||||
if headers == nil {
|
|
||||||
txHeaders = Alamofire.HTTPHeaders()
|
|
||||||
}
|
|
||||||
txHeaders?.add(name: "Authorization", value: "Basic \(encoded)")
|
|
||||||
|
|
||||||
request(path: path, method: method, parameters: parameters, encoder: encoder, headers: txHeaders)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension String {
|
struct ApiRequestDefaults {
|
||||||
|
static let authMethod: AuthMethod = .basic
|
||||||
func toBase64() -> String {
|
static let domain: String = "https://music.sarsoo.xyz/"
|
||||||
return Data(self.utf8).base64EncodedString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocol ApiRequest {
|
||||||
|
var domain: String { get }
|
||||||
|
var path: String { get }
|
||||||
|
var httpMethod: Alamofire.HTTPMethod { get }
|
||||||
|
var parameters: JSON? { get }
|
||||||
|
var parameterType: Alamofire.ParameterEncoder? { get }
|
||||||
|
var headers: HTTPHeaders? { get }
|
||||||
|
var authMethod: AuthMethod? { get }
|
||||||
}
|
}
|
||||||
|
54
Music Tools/Network/PlaylistApi.swift
Normal file
54
Music Tools/Network/PlaylistApi.swift
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// PlaylistApi.swift
|
||||||
|
// Music Tools
|
||||||
|
//
|
||||||
|
// Created by Andy Pack on 18/02/2020.
|
||||||
|
// Copyright © 2020 Sarsoo. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
import SwiftyJSON
|
||||||
|
|
||||||
|
public enum PlaylistApi {
|
||||||
|
case getPlaylists
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PlaylistApi: ApiRequest {
|
||||||
|
var domain: String {
|
||||||
|
return ApiRequestDefaults.domain
|
||||||
|
}
|
||||||
|
|
||||||
|
var path: String {
|
||||||
|
switch self {
|
||||||
|
case .getPlaylists:
|
||||||
|
return "api/playlists"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpMethod: Alamofire.HTTPMethod {
|
||||||
|
switch self {
|
||||||
|
case .getPlaylists:
|
||||||
|
return .get
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameters: JSON? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameterType: ParameterEncoder? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var headers: HTTPHeaders? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var authMethod: AuthMethod? {
|
||||||
|
return ApiRequestDefaults.authMethod
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
53
Music Tools/Network/UserApi.swift
Normal file
53
Music Tools/Network/UserApi.swift
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// UserApi.swift
|
||||||
|
// Music Tools
|
||||||
|
//
|
||||||
|
// Created by Andy Pack on 18/02/2020.
|
||||||
|
// Copyright © 2020 Sarsoo. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
import SwiftyJSON
|
||||||
|
|
||||||
|
public enum UserApi {
|
||||||
|
case getUser
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UserApi: ApiRequest {
|
||||||
|
var domain: String {
|
||||||
|
return ApiRequestDefaults.domain
|
||||||
|
}
|
||||||
|
|
||||||
|
var path: String {
|
||||||
|
switch self {
|
||||||
|
case .getUser:
|
||||||
|
return "api/user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpMethod: Alamofire.HTTPMethod {
|
||||||
|
switch self {
|
||||||
|
case .getUser:
|
||||||
|
return .get
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameters: JSON? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameterType: ParameterEncoder? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var headers: HTTPHeaders? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var authMethod: AuthMethod? {
|
||||||
|
return ApiRequestDefaults.authMethod
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -12,12 +12,14 @@ struct PlaylistRow: View {
|
|||||||
var playlist: Playlist
|
var playlist: Playlist
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
NavigationLink(destination: PlaylistView(playlist: playlist)){
|
||||||
HStack {
|
HStack {
|
||||||
Text(playlist.name)
|
Text(playlist.name)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PlaylistRow_Previews: PreviewProvider {
|
struct PlaylistRow_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
@ -10,6 +10,8 @@ import SwiftUI
|
|||||||
|
|
||||||
struct PlaylistView: View {
|
struct PlaylistView: View {
|
||||||
var playlist: Playlist
|
var playlist: Playlist
|
||||||
|
@State private var recommendations: Bool = false
|
||||||
|
@State private var library_Tracks: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|
||||||
@ -25,10 +27,11 @@ struct PlaylistView: View {
|
|||||||
.cornerRadius(18)
|
.cornerRadius(18)
|
||||||
.padding(.bottom, 20)
|
.padding(.bottom, 20)
|
||||||
|
|
||||||
Toggle(isOn: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant(true)/*@END_MENU_TOKEN@*/) {
|
Toggle(isOn: $recommendations) {
|
||||||
Text("Spotify Recommendations")
|
Text("Spotify Recommendations")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if $recommendations.wrappedValue {
|
||||||
Stepper(value: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant(4)/*@END_MENU_TOKEN@*/, in: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Range@*/1...10/*@END_MENU_TOKEN@*/){
|
Stepper(value: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant(4)/*@END_MENU_TOKEN@*/, in: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Range@*/1...10/*@END_MENU_TOKEN@*/){
|
||||||
Text("#:")
|
Text("#:")
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
@ -38,15 +41,18 @@ struct PlaylistView: View {
|
|||||||
.multilineTextAlignment(.trailing)
|
.multilineTextAlignment(.trailing)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Toggle(isOn: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant(true)/*@END_MENU_TOKEN@*/) {
|
|
||||||
Text("Library Tracks")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EditButton()
|
Toggle(isOn: $library_Tracks) {
|
||||||
|
Text("Library Tracks")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
|
||||||
|
.onAppear {
|
||||||
|
self.$recommendations.wrappedValue = self.playlist.include_recommendations
|
||||||
|
self.$library_Tracks.wrappedValue = self.playlist.include_library_tracks
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Alamofire
|
import Alamofire
|
||||||
|
import SwiftyJSON
|
||||||
|
|
||||||
struct RootView: View {
|
struct RootView: View {
|
||||||
@State private var selection = 0
|
@State private var selection = 0
|
||||||
|
@State private var playlists: Array<Playlist> = []
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
TabView(selection: $selection){
|
TabView(selection: $selection){
|
||||||
NavigationView {
|
NavigationView {
|
||||||
List(/*@START_MENU_TOKEN@*/0 ..< 5/*@END_MENU_TOKEN@*/) { item in
|
List(playlists) { playlist in
|
||||||
Text("Playlist")
|
PlaylistRow(playlist: playlist)
|
||||||
.font(.title)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
.navigationBarTitle(Text("Playlists").font(.title))
|
.navigationBarTitle(Text("Playlists").font(.title))
|
||||||
}
|
}
|
||||||
@ -63,12 +63,21 @@ struct RootView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func fetch() {
|
private func fetch() {
|
||||||
let net: BasicAuthNetwork = BasicAuthNetwork(username: "", password: "")
|
let api = PlaylistApi.getPlaylists
|
||||||
net.authedRequest(path: "api/playlist",
|
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
|
||||||
method: Alamofire.HTTPMethod.get,
|
|
||||||
parameters: ["name": ""],
|
guard let data = response.data else {
|
||||||
encoder: nil,
|
fatalError("error getting playlists")
|
||||||
headers: nil)
|
}
|
||||||
|
|
||||||
|
guard let json = try? JSON(data: data) else {
|
||||||
|
fatalError("error parsing reponse")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.playlists = json["playlists"].arrayValue.map({ dict in
|
||||||
|
Playlist.fromDict(dictionary: dict)
|
||||||
|
}).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user