Skip to content

Commit

Permalink
ios 17 bugfixes
Browse files Browse the repository at this point in the history
fix Handouts view
fix Certificate view
fix DownloadManager issues (user can’t stop downloading, and all downloaded videos disappear after restarting the app)
EditProfileView – return alert "You are leaving profile without savings"
  • Loading branch information
IvanStepanok committed Sep 20, 2023
1 parent a92a22c commit ec74bcd
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22G90" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G91" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="CDDownloadData" representedClassName="CDDownloadData" syncable="YES" codeGenerationType="class">
<attribute name="courseId" optional="YES" attributeType="String"/>
<attribute name="fileName" optional="YES" attributeType="String"/>
<attribute name="id" optional="YES" attributeType="String"/>
<attribute name="path" optional="YES" attributeType="String"/>
<attribute name="progress" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="resumeData" optional="YES" attributeType="Binary"/>
<attribute name="state" optional="YES" attributeType="String"/>
Expand Down
2 changes: 1 addition & 1 deletion Core/Core/Data/Persistence/CorePersistenceProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public protocol CorePersistenceProtocol {
func getNextBlockForDownloading() -> DownloadData?
func getDownloadsForCourse(_ courseId: String) -> [DownloadData]
func downloadData(by blockId: String) -> DownloadData?
func updateDownloadState(id: String, state: DownloadState, path: String?, resumeData: Data?)
func updateDownloadState(id: String, state: DownloadState, resumeData: Data?)
func deleteDownloadData(id: String) throws
func saveDownloadData(data: DownloadData)
}
Expand Down
39 changes: 15 additions & 24 deletions Core/Core/Network/DownloadManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public struct DownloadData {
public let id: String
public let courseId: String
public let url: String
public let path: String?
public let fileName: String
public let progress: Double
public let resumeData: Data?
Expand All @@ -35,7 +34,6 @@ public struct DownloadData {
id: String,
courseId: String,
url: String,
path: String?,
fileName: String,
progress: Double,
resumeData: Data?,
Expand All @@ -45,7 +43,6 @@ public struct DownloadData {
self.id = id
self.courseId = courseId
self.url = url
self.path = path
self.fileName = fileName
self.progress = progress
self.resumeData = resumeData
Expand Down Expand Up @@ -148,28 +145,25 @@ public class DownloadManager: DownloadManagerProtocol {
persistence.updateDownloadState(
id: download.id,
state: .inProgress,
path: nil,
resumeData: download.resumeData
)
self.isDownloadingInProgress = true
let fileName = url.lastPathComponent
if let resumeData = download.resumeData {
downloadRequest = AF.download(resumingWith: resumeData)
} else {
downloadRequest = AF.download(url)
}
// downloadRequest?.downloadProgress { prog in
// let completed = Double(prog.fractionCompleted * 100)
// print(">>>>> Downloading", download.url, completed, "%")
// }
downloadRequest?.downloadProgress { prog in
let completed = Double(prog.fractionCompleted * 100)
print(">>>>> Downloading", download.url, completed, "%")
}
downloadRequest?.responseData(completionHandler: { [weak self] data in
guard let self else { return }
if let data = data.value, let url = self.videosFolderUrl() {
let fileUrl = self.saveFile(fileName: fileName, data: data, folderURL: url)
self.saveFile(fileName: download.fileName, data: data, folderURL: url)
self.persistence.updateDownloadState(
id: download.id,
state: .finished,
path: fileUrl?.absoluteString,
resumeData: nil
)
try? self.newDownload()
Expand All @@ -188,22 +182,20 @@ public class DownloadManager: DownloadManagerProtocol {
self.persistence.updateDownloadState(
id: currentDownload.id,
state: .paused,
path: nil,
resumeData: resumeData
)
})
}

public func deleteFile(blocks: [CourseBlock]) {
for block in blocks {
let downloadData = persistence.downloadData(by: block.id)
guard let path = persistence.downloadData(by: block.id)?.path,
let fileUrl = URL(string: path) else { return }

do {
print(">>>>>", block.displayName, block.id)
try persistence.deleteDownloadData(id: block.id)
try FileManager.default.removeItem(at: fileUrl)
print("File deleted successfully")
if let fileUrl = fileUrl(for: block.id) {
try FileManager.default.removeItem(at: fileUrl)
print("File deleted successfully")
}
} catch {
print("Error deleting file: \(error.localizedDescription)")
}
Expand All @@ -213,7 +205,7 @@ public class DownloadManager: DownloadManagerProtocol {
public func deleteAllFiles() {
let downloadData = persistence.getAllDownloadData()
downloadData.forEach {
if let path = $0.path, let fileURL = URL(string: path) {
if let fileURL = fileUrl(for: $0.id) {
do {
try FileManager.default.removeItem(at: fileURL)
} catch {
Expand All @@ -227,8 +219,9 @@ public class DownloadManager: DownloadManagerProtocol {
guard let data = persistence.downloadData(by: blockId),
data.url.count > 0,
data.state == .finished else { return nil }

return URL(string: data.path ?? "")
let path = videosFolderUrl()
let fileName = data.fileName
return path?.appendingPathComponent(fileName)
}

private func videosFolderUrl() -> URL? {
Expand All @@ -252,15 +245,13 @@ public class DownloadManager: DownloadManagerProtocol {
}
}

private func saveFile(fileName: String, data: Data, folderURL: URL) -> URL? {
private func saveFile(fileName: String, data: Data, folderURL: URL) {
let fileURL = folderURL.appendingPathComponent(fileName)
do {
try data.write(to: fileURL)
return fileURL
} catch {
print("SaveFile Error", error.localizedDescription)
}
return nil
}
}

Expand Down
20 changes: 10 additions & 10 deletions Core/Core/View/Base/WebBrowser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,28 @@ public struct WebBrowser: View {

public var body: some View {
ZStack(alignment: .top) {

CoreAssets.background.swiftUIColor.ignoresSafeArea()
// MARK: - Page name
VStack(alignment: .center) {
NavigationBar(title: pageTitle,
leftButtonAction: { presentationMode.wrappedValue.dismiss() })

// MARK: - Page Body
VStack {
ZStack(alignment: .top) {
NavigationView {
// NavigationView {
WebView(
viewModel: .init(url: url, baseURL: ""),
isLoading: $isShowProgress,
refreshCookies: {}
)
.navigationBarTitle(Text("")) // Needed for hide navBar on ios 14, 15
.navigationBarHidden(true)
.ignoresSafeArea()
}
}

// }
}.navigationBarTitle(Text("")) // Needed for hide navBar on ios 14, 15
.navigationBarHidden(true)
.ignoresSafeArea()
}
}
.navigationBarHidden(false)
.navigationBarBackButtonHidden(false)
.navigationTitle(pageTitle)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public struct HandoutsUpdatesDetailView: View {

public var body: some View {
ZStack(alignment: .top) {
Theme.Colors.background
.ignoresSafeArea()
GeometryReader { reader in

// MARK: - Page Body
Expand Down Expand Up @@ -121,10 +123,10 @@ public struct HandoutsUpdatesDetailView: View {
}
Spacer(minLength: 84)

.background(
Theme.Colors.background
.ignoresSafeArea()
)
// .background(
// Theme.Colors.background
// .ignoresSafeArea()
// )
}

}
Expand Down
5 changes: 3 additions & 2 deletions Course/Course/Presentation/Handouts/HandoutsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ struct HandoutsView: View {

private let courseID: String

@ObservedObject
@StateObject
private var viewModel: HandoutsViewModel

public init(
courseID: String,
viewModel: HandoutsViewModel
) {
self.courseID = courseID
self.viewModel = viewModel
// self.viewModel = viewModel
self._viewModel = StateObject(wrappedValue: { viewModel }())
}

public var body: some View {
Expand Down
1 change: 1 addition & 0 deletions Course/Course/Presentation/Outline/CourseOutlineView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public struct CourseOutlineView: View {
)
.frame(width: 141)
.padding(.top, 8)

.fullScreenCover(
isPresented: $openCertificateView,
content: {
Expand Down
105 changes: 65 additions & 40 deletions Course/Course/Presentation/Unit/CourseUnitView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public struct CourseUnitView: View {
GeometryReader { reader in
VStack(spacing: 0) {
VStack {}.frame(height: 100)
if viewModel.connectivity.isInternetAvaliable {
LazyVStack(spacing: 0) {
let data = Array(viewModel.verticals[viewModel.verticalIndex].childs.enumerated())
ForEach(data, id: \.offset) { index, block in
Expand All @@ -54,40 +53,58 @@ public struct CourseUnitView: View {
switch LessonType.from(block) {
// MARK: YouTube
case let .youtube(url, blockID):
YouTubeView(
name: block.displayName,
url: url,
courseID: viewModel.courseID,
blockID: blockID,
playerStateSubject: playerStateSubject,
languages: block.subtitles ?? [],
isOnScreen: index == viewModel.index
).frameLimit()
Spacer(minLength: 100)
if viewModel.connectivity.isInternetAvaliable {
YouTubeView(
name: block.displayName,
url: url,
courseID: viewModel.courseID,
blockID: blockID,
playerStateSubject: playerStateSubject,
languages: block.subtitles ?? [],
isOnScreen: index == viewModel.index
).frameLimit()
Spacer(minLength: 100)
} else {
NoInternetView(playerStateSubject: playerStateSubject)
}
// MARK: Encoded Video
case let .video(encodedUrl, blockID):
EncodedVideoView(
name: block.displayName,
url: viewModel.urlForVideoFileOrFallback(
blockId: blockID,
url: encodedUrl
),
courseID: viewModel.courseID,
blockID: blockID,
playerStateSubject: playerStateSubject,
languages: block.subtitles ?? [],
isOnScreen: index == viewModel.index
).frameLimit()
Spacer(minLength: 100)
let url = viewModel.urlForVideoFileOrFallback(
blockId: blockID,
url: encodedUrl
)
if viewModel.connectivity.isInternetAvaliable || url?.isFileURL == true {
EncodedVideoView(
name: block.displayName,
url: url,
courseID: viewModel.courseID,
blockID: blockID,
playerStateSubject: playerStateSubject,
languages: block.subtitles ?? [],
isOnScreen: index == viewModel.index
).frameLimit()
Spacer(minLength: 100)
} else {
NoInternetView(playerStateSubject: playerStateSubject)
}
// MARK: Web
case .web(let url):
WebView(url: url, viewModel: viewModel)
if viewModel.connectivity.isInternetAvaliable {
WebView(url: url, viewModel: viewModel)
} else {
NoInternetView(playerStateSubject: playerStateSubject)
}
// MARK: Unknown
case .unknown(let url):
if viewModel.connectivity.isInternetAvaliable {
UnknownView(url: url, viewModel: viewModel)
Spacer()
} else {
NoInternetView(playerStateSubject: playerStateSubject)
}
// MARK: Discussion
case let .discussion(blockID, blockKey, title):
if viewModel.connectivity.isInternetAvaliable {
VStack {
if showDiscussion {
DiscussionView(
Expand All @@ -104,6 +121,9 @@ public struct CourseUnitView: View {
}
}
}.frameLimit()
} else {
NoInternetView(playerStateSubject: playerStateSubject)
}
}
} else {
EmptyView()
Expand All @@ -126,21 +146,7 @@ public struct CourseUnitView: View {
}

})
} else {

// MARK: No internet view
VStack(spacing: 28) {
Image(systemName: "wifi").resizable()
.scaledToFit()
.frame(width: 100)
Text(CourseLocalization.Error.noInternet)
.multilineTextAlignment(.center)
.padding(.horizontal, 20)
UnitButtonView(type: .reload, action: {
playerStateSubject.send(VideoPlayerState.kill)
}).frame(width: 100)
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}

}.frame(maxWidth: .infinity)
.clipped()

Expand Down Expand Up @@ -334,3 +340,22 @@ struct CourseUnitView_Previews: PreviewProvider {
}
//swiftlint:enable all
#endif

struct NoInternetView: View {

let playerStateSubject: CurrentValueSubject<VideoPlayerState?, Never>

var body: some View {
VStack(spacing: 28) {
Image(systemName: "wifi").resizable()
.scaledToFit()
.frame(width: 100)
Text(CourseLocalization.Error.noInternet)
.multilineTextAlignment(.center)
.padding(.horizontal, 20)
UnitButtonView(type: .reload, action: {
playerStateSubject.send(VideoPlayerState.kill)
}).frame(width: 100)
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
Loading

0 comments on commit ec74bcd

Please sign in to comment.