Skip to content

Instantly share code, notes, and snippets.

@NunoAlexandre
Created March 23, 2019 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NunoAlexandre/85a0b73410fdb44e776bc6a5ea58042b to your computer and use it in GitHub Desktop.
Save NunoAlexandre/85a0b73410fdb44e776bc6a5ea58042b to your computer and use it in GitHub Desktop.
A callback hell downloading an item
@discardableResult
func downloadSpecificActivity(activityInfo: SpecificActivityFirebase, completion: @escaping ((URL?, Error?) -> Void), progress: ((Double?) -> Void)? = nil) -> ContentDownload? {
if SettingsManager.shared.wifiOnlyEnabled && SettingsManager.shared.reachabilityManager?.isReachableOnWWAN ?? false {
completion(nil, ContentError.notAllowedOnWWanError)
} else if SettingsManager.shared.reachabilityManager != nil && !SettingsManager.shared.reachabilityManager!.isReachable {
completion(nil, ContentError.notConnected)
} else {
let downloadStartDate = Date.now()
if let tempUrl = temporaryDownloadUrl(forSpecificActivity: activityInfo) {
let contentDownloadTask = ContentDownload()
GeoblockManager.shared.currentLocationIsInAllowedLocations(allowedLocations: activityInfo.allowedGeolocations, completion: { (allowed) in
if allowed {
let downloadTask = self.storageReference(forSpecificActivity: activityInfo)?.write(toFile: tempUrl, completion: { (url, error) in
if let url = url, error == nil {
if Zip.isValidFileExtension(url.pathExtension) {
if let destinationUrl = self.temporaryUnzipUrl(forSpecificActivity: activityInfo) {
do {
try Zip.unzipFile(url, destination: destinationUrl, overwrite: true, password: nil, progress: { (perc) in
progress?(perc / 10.0 + 0.9)
})
let fm = FileManager()
let finalDestinationUrl = self.localStorageUrl(forSpecificActivity: activityInfo)
try? fm.removeItem(at: finalDestinationUrl)
try fm.moveItem(at: destinationUrl, to: finalDestinationUrl)
if let version = self.version(forSpecificActivity: activityInfo) {
let url = finalDestinationUrl.appendingPathComponent(".version", isDirectory: false)
try? version.write(to: url, atomically: true, encoding: .utf8)
}
// We need this check as the app crashes because activityInfo
// missed some fields, in a download NOT fired by the user.
// That just shouldn't happen but we will fix it in a deeper refactoring.
// TODO(nuno): refactor this whole thing.
if activityInfo.character != nil && activityInfo.type != nil {
Analytics.track.event(
Tracking.Event.contentDownloaded(
from: activityInfo,
durationInSeconds: downloadStartDate.secondsPassedUntilNow()
)
)
}
completion(finalDestinationUrl, nil)
} catch {
completion(nil, error)
}
} else {
completion(nil, ContentError.cacheNotAvailableError)
}
} else {
completion(url, ContentError.invalidExtensionError)
}
} else {
completion(url, error)
}
})
downloadTask?.observe(.progress, handler: { (snapshot) in
if let p = snapshot.progress?.fractionCompleted {
progress?(p * 9.0 / 10.0)
} else {
progress?(nil)
}
})
contentDownloadTask.firebaseDownload = downloadTask
} else {
completion(nil, ContentError.notAllowedOnGeolocationError)
}
})
return contentDownloadTask
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment