working model for network layer, added user object
This commit is contained in:
parent
d91ce89670
commit
b80152ba13
@ -7,6 +7,12 @@
|
||||
objects = {
|
||||
|
||||
/* 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 */; };
|
||||
E98254C223F9FFF90056D9D3 /* PlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254C123F9FFF90056D9D3 /* PlaylistView.swift */; };
|
||||
E98254C823FA25D20056D9D3 /* PlaylistList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98254C723FA25D20056D9D3 /* PlaylistList.swift */; };
|
||||
@ -42,6 +48,10 @@
|
||||
/* End PBXContainerItemProxy 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>"; };
|
||||
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>"; };
|
||||
@ -69,7 +79,9 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E97AF45923FC50EC00635494 /* SwiftyJSON in Frameworks */,
|
||||
E98254D923FB53780056D9D3 /* Alamofire in Frameworks */,
|
||||
E97AF45E23FC83AF00635494 /* KeychainAccess in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -94,6 +106,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E98254BC23F9B7A90056D9D3 /* Playlist.swift */,
|
||||
E97AF45523FC4E7800635494 /* User.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
@ -102,6 +115,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E98254DA23FB64740056D9D3 /* Network.swift */,
|
||||
E97AF45A23FC748D00635494 /* UserApi.swift */,
|
||||
E97AF45F23FC85D600635494 /* PlaylistApi.swift */,
|
||||
);
|
||||
path = Network;
|
||||
sourceTree = "<group>";
|
||||
@ -124,6 +139,7 @@
|
||||
E9EA691523F9A54B0012C3E8 /* LaunchScreen.storyboard */,
|
||||
E9EA690A23F9A5430012C3E8 /* AppDelegate.swift */,
|
||||
E9EA690C23F9A5430012C3E8 /* SceneDelegate.swift */,
|
||||
E97AF46123FC89CB00635494 /* Main.storyboard */,
|
||||
);
|
||||
path = Application;
|
||||
sourceTree = "<group>";
|
||||
@ -206,6 +222,8 @@
|
||||
name = "Music Tools";
|
||||
packageProductDependencies = (
|
||||
E98254D823FB53780056D9D3 /* Alamofire */,
|
||||
E97AF45823FC50EC00635494 /* SwiftyJSON */,
|
||||
E97AF45D23FC83AF00635494 /* KeychainAccess */,
|
||||
);
|
||||
productName = "Music Tools";
|
||||
productReference = E9EA690723F9A5430012C3E8 /* Music Tools.app */;
|
||||
@ -281,6 +299,8 @@
|
||||
mainGroup = E9EA68FE23F9A5430012C3E8;
|
||||
packageReferences = (
|
||||
E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */,
|
||||
E97AF45723FC50EC00635494 /* XCRemoteSwiftPackageReference "swiftyjson" */,
|
||||
E97AF45C23FC83AF00635494 /* XCRemoteSwiftPackageReference "keychainaccess" */,
|
||||
);
|
||||
productRefGroup = E9EA690823F9A5430012C3E8 /* Products */;
|
||||
projectDirPath = "";
|
||||
@ -301,6 +321,7 @@
|
||||
E9EA691723F9A54B0012C3E8 /* LaunchScreen.storyboard in Resources */,
|
||||
E9EA691423F9A54B0012C3E8 /* Preview Assets.xcassets in Resources */,
|
||||
E9EA691123F9A54A0012C3E8 /* Assets.xcassets in Resources */,
|
||||
E97AF46223FC89CC00635494 /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -329,11 +350,14 @@
|
||||
E9EA690B23F9A5430012C3E8 /* AppDelegate.swift in Sources */,
|
||||
E9EA690D23F9A5430012C3E8 /* SceneDelegate.swift in Sources */,
|
||||
E98254DB23FB64740056D9D3 /* Network.swift in Sources */,
|
||||
E97AF46023FC85D600635494 /* PlaylistApi.swift in Sources */,
|
||||
E98254C823FA25D20056D9D3 /* PlaylistList.swift in Sources */,
|
||||
E9EA690F23F9A5430012C3E8 /* RootView.swift in Sources */,
|
||||
E98254BD23F9B7A90056D9D3 /* Playlist.swift in Sources */,
|
||||
E98254C223F9FFF90056D9D3 /* PlaylistView.swift in Sources */,
|
||||
E97AF45623FC4E7800635494 /* User.swift in Sources */,
|
||||
E98254D023FB00B60056D9D3 /* LoginScreen.swift in Sources */,
|
||||
E97AF45B23FC748D00635494 /* UserApi.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -660,6 +684,22 @@
|
||||
/* End XCConfigurationList 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" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/alamofire/alamofire.git";
|
||||
@ -671,6 +711,16 @@
|
||||
/* End XCRemoteSwiftPackageReference 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 */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = E98254D723FB53770056D9D3 /* XCRemoteSwiftPackageReference "alamofire" */;
|
||||
|
@ -9,6 +9,24 @@
|
||||
"revision": "0c8cb78d05b6d067ee331c05058ff4dedcb45ffa",
|
||||
"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 SwiftUI
|
||||
import KeychainAccess
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
@ -22,6 +23,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
// Create the SwiftUI view that provides the window contents.
|
||||
let contentView = RootView()
|
||||
|
||||
let keychain = Keychain(service: "xyz.sarsoo.music.login")
|
||||
keychain["username"] = ""
|
||||
keychain["password"] = ""
|
||||
|
||||
// Use a UIHostingController as window root view controller.
|
||||
if let windowScene = scene as? UIWindowScene {
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import SwiftyJSON
|
||||
|
||||
class Playlist: Identifiable {
|
||||
|
||||
@ -55,5 +55,19 @@ class Playlist: Identifiable {
|
||||
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 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,
|
||||
method: Alamofire.HTTPMethod,
|
||||
parameters: [String:String]? ,
|
||||
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)
|
||||
let keychain = Keychain(service: "xyz.sarsoo.music.login")
|
||||
txHeaders.add(.authorization(username: keychain["username"] ?? "", password: keychain["password"] ?? ""))
|
||||
return txHeaders
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
AF.request(baseBath + path,
|
||||
method: method,
|
||||
parameters: uwParameters,
|
||||
headers: headers ).response { response in
|
||||
debugPrint(response)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class BasicAuthNetwork: MusicToolsNetwork {
|
||||
var username: String
|
||||
var password: String
|
||||
struct RequestBuilder {
|
||||
static func buildRequest(apiRequest: ApiRequest) -> Alamofire.DataRequest {
|
||||
|
||||
init(username: String, password: String) {
|
||||
self.username = username
|
||||
self.password = password
|
||||
let txHeaders = apiRequest.authMethod?.auth(headers: apiRequest.headers)
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
public func authedRequest(path: String,
|
||||
method: Alamofire.HTTPMethod,
|
||||
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)
|
||||
|
||||
return AF.request(apiRequest.domain + apiRequest.path,
|
||||
method: apiRequest.httpMethod,
|
||||
headers: txHeaders)
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
|
||||
func toBase64() -> String {
|
||||
return Data(self.utf8).base64EncodedString()
|
||||
struct ApiRequestDefaults {
|
||||
static let authMethod: AuthMethod = .basic
|
||||
static let domain: String = "https://music.sarsoo.xyz/"
|
||||
}
|
||||
|
||||
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 body: some View {
|
||||
NavigationLink(destination: PlaylistView(playlist: playlist)){
|
||||
HStack {
|
||||
Text(playlist.name)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaylistRow_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
|
@ -10,6 +10,8 @@ import SwiftUI
|
||||
|
||||
struct PlaylistView: View {
|
||||
var playlist: Playlist
|
||||
@State private var recommendations: Bool = false
|
||||
@State private var library_Tracks: Bool = false
|
||||
|
||||
var body: some View {
|
||||
|
||||
@ -25,10 +27,11 @@ struct PlaylistView: View {
|
||||
.cornerRadius(18)
|
||||
.padding(.bottom, 20)
|
||||
|
||||
Toggle(isOn: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant(true)/*@END_MENU_TOKEN@*/) {
|
||||
Toggle(isOn: $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@*/){
|
||||
Text("#:")
|
||||
.foregroundColor(Color.gray)
|
||||
@ -38,15 +41,18 @@ struct PlaylistView: View {
|
||||
.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()
|
||||
.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 Alamofire
|
||||
import SwiftyJSON
|
||||
|
||||
struct RootView: View {
|
||||
@State private var selection = 0
|
||||
@State private var playlists: Array<Playlist> = []
|
||||
|
||||
var body: some View {
|
||||
TabView(selection: $selection){
|
||||
NavigationView {
|
||||
List(/*@START_MENU_TOKEN@*/0 ..< 5/*@END_MENU_TOKEN@*/) { item in
|
||||
Text("Playlist")
|
||||
.font(.title)
|
||||
|
||||
List(playlists) { playlist in
|
||||
PlaylistRow(playlist: playlist)
|
||||
}
|
||||
.navigationBarTitle(Text("Playlists").font(.title))
|
||||
}
|
||||
@ -63,12 +63,21 @@ struct RootView: View {
|
||||
}
|
||||
|
||||
private func fetch() {
|
||||
let net: BasicAuthNetwork = BasicAuthNetwork(username: "", password: "")
|
||||
net.authedRequest(path: "api/playlist",
|
||||
method: Alamofire.HTTPMethod.get,
|
||||
parameters: ["name": ""],
|
||||
encoder: nil,
|
||||
headers: nil)
|
||||
let api = PlaylistApi.getPlaylists
|
||||
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
|
||||
|
||||
guard let data = response.data else {
|
||||
fatalError("error getting playlists")
|
||||
}
|
||||
|
||||
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