Fix #28: install multiple apps at once

The fix was pretty straightforward except for one interesting caveat:
since we add a new download observer every time we start downloading a
new purchase, we also have to remove it when the download finishes.
Otherwise there will be multiple observers reporting download progress
for the same purchase (i.e. user will see duplicate output)
This commit is contained in:
Dmitry Rodionov 2016-09-06 20:37:12 +07:00
parent d18a5799a3
commit 319300e7a1
2 changed files with 19 additions and 10 deletions

View file

@ -16,6 +16,7 @@ func download(adamId: UInt64) -> MASError? {
let purchase = SSPurchase(adamId: adamId, account: account)
var purchaseError: MASError?
var observerIdentifier: AnyObject? = nil
dispatch_group_enter(group)
purchase.perform { purchase, unused, error, response in
@ -27,7 +28,7 @@ func download(adamId: UInt64) -> MASError? {
if let downloads = response.downloads where downloads.count > 0 {
let observer = PurchaseDownloadObserver(purchase: purchase)
observer.errorHandler = { error in
purchaseError = error
dispatch_group_leave(group)
@ -36,8 +37,9 @@ func download(adamId: UInt64) -> MASError? {
observer.completionHandler = {
dispatch_group_leave(group)
}
CKDownloadQueue.sharedDownloadQueue().addObserver(observer)
let downloadQueue = CKDownloadQueue.sharedDownloadQueue()
observerIdentifier = downloadQueue.addObserver(observer)
}
else {
print("No downloads")
@ -47,5 +49,10 @@ func download(adamId: UInt64) -> MASError? {
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
if let observerIdentifier = observerIdentifier {
CKDownloadQueue.sharedDownloadQueue().removeObserver(observerIdentifier)
}
return purchaseError
}

View file

@ -12,23 +12,25 @@ struct InstallCommand: CommandType {
let function = "Install from the Mac App Store"
func run(options: Options) -> Result<(), MASError> {
if let error = download(options.appId) {
return .Failure(error)
for id in options.appIds {
if let error = download(id) {
return .Failure(error)
}
}
return .Success(())
}
}
struct InstallOptions: OptionsType {
let appId: UInt64
let appIds: [UInt64]
static func create(appId: Int) -> InstallOptions {
return InstallOptions(appId: UInt64(appId))
static func create(appIds: [Int]) -> InstallOptions {
return InstallOptions(appIds: appIds.map{UInt64($0)})
}
static func evaluate(m: CommandMode) -> Result<InstallOptions, CommandantError<MASError>> {
return create
<*> m <| Argument(usage: "the app ID to install")
<*> m <| Argument(usage: "the list of app IDs to install")
}
}