iOS Urban Airship progress and HUD

598 views Asked by At

I'm really stuck on this one. We have an IAP where the list view is our own and we point directly to the UADetailView for purchasing. Because of this we don't have a progress bar to tell the user how the download is going, and our downloads are big. I thought I could use the MBProgressHud, but I have run into a problem. I don't seem to be able to pass the progress from UA to the HUD. Everything works fine with the HUD if I use a simple counter to clock it up. Much as their own sample.

Here is the HUD call;

- (void)showWithLabelDeterminate {

HUD = [[MBProgressHUD alloc] initWithView:self.view.window];
[self.view.window addSubview:HUD];

// Set determinate mode
HUD.mode = MBProgressHUDModeDeterminate;

HUD.delegate =self;
HUD.labelText = NSLocalizedString(@"DownLoading","");

// myProgressTask uses the HUD instance to update progress
[HUD showWhileExecuting:@selector(refreshProgress) onTarget:self withObject:nil animated:YES];

}

and the refresh that I'm trying to use;

- (void)refreshProgress:(float)progress {
   while (progress < 1.0f)
    NSLog(@"++ progress for HUD: %f", progress);
  HUD.progress = progress;

}

However, when I run it the app crashes with this log...

2012-01-30 12:23:18.838 isengua-en[12730:3827] -[UAProductDetailViewController refreshProgress]: unrecognized selector sent to instance 0x3e2c10 2012-01-30 12:23:18.840 isengua-en[12730:3827] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UAProductDetailViewController refreshProgress]: unrecognized selector sent to instance 0x3e2c10' * First throw call stack: (0x30caa8bf 0x37e4f1e5 0x30cadacb 0x30cac945 0x30c07680 0x30c0922b 0xf4e59 0x37cbca91 0x37d505a1 0x36447c1d 0x36447ad8) terminate called throwing an exception[

Anyone out there that has had the same problem and solved it?

Update with chages...

- (void)showWithLabelDeterminate {

HUD = [[MBProgressHUD alloc] initWithView:self.view.window];
[self.view.window addSubview:HUD];

// Set determinate mode
HUD.mode = MBProgressHUDModeDeterminate;

HUD.delegate =self;
HUD.labelText = NSLocalizedString(@"DownLoading","");

// myProgressTask uses the HUD instance to update progress
[HUD showWhileExecuting:@selector(productsDownloadProgress:) onTarget:self withObject:nil animated:YES];

}

- (void)productsDownloadProgress:(float)progress count:(int)count {
    HUD.progress = progress;
    UALOG(@"[StoreFrontDelegate] productsDownloadProgress: %f count: %d", progress, count);
    if (count == 0) {
        NSLog(@"Downloads complete !");

    }
}

and this on the purchase button

- (void)purchase:(id)sender {
self.navigationItem.rightBarButtonItem.enabled = NO;
[UAStoreFront purchase:product.productIdentifier];         
[self.navigationController popViewControllerAnimated:NO];
[[UAStoreFront shared] setDelegate:self];
[self showWithLabelDeterminate];

}

Crash log:

2012-01-30 13:12:45.555 isengua-en[12886:6e27] -[UAProductDetailViewController productsDownloadProgress:]: unrecognized selector sent to instance 0x3f7f70 2012-01-30 13:12:45.557 isengua-en[12886:6e27] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UAProductDetailViewController productsDownloadProgress:]: unrecognized selector sent to instance 0x3f7f70' * First throw call stack: (0x30caa8bf 0x37e4f1e5 0x30cadacb 0x30cac945 0x30c07680 0x30c0922b 0xf5e21 0x37cbca91 0x37d505a1 0x36447c1d 0x36447ad8) terminate called throwing an exception

3

There are 3 answers

4
Nick Lockwood On

Your refresh progress method takes a parameter (float) so your selector should have a colon on the end:

In objective C, this:

@selector(refreshProgress:)

Is not the same as this:

@selector(refreshProgress)

They are different method names.

0
Sean On

If you have a method

- (void)productsDownloadProgress:(float)progress count:(int)count

then its selector is

productsDownloadProgress:count:

not

productsDownloadProgress:

So, by giving the selector "productsDownloadProgress:" instead of "productsDownloadProgress:count:" you are giving a selector to a method that doesn't exist. When HUD tries to call that selector, the Objective-C runtime looks for it in the target you specified ("self" in this case), can't find it, and throws an NSInvalidArgument exception.

You will probably still have trouble, though, even if you fix the invalid selector problem. Your productsDownloadProgress:count: method takes two arguments, both of which are basic types, yet the [HUD showWhileExecuting:onTarget:withObject:animated:] method seems to want a selector that only takes one argument and that argument should be an Objective-C object.

That's what the withObject: part is for -- you give it an Objective-C object and it will get passed to the method as its first argument.

Of course, I don't know anything about Urban Airship, so maybe it will work fine.

0
Matej Bukovinski On

The crashes here are pretty clear and have been appropriately explained by Nick and Sean.

The more important problem is that you're applying an incorrect usage pattern for MBProgressHUD for a download operation. What you should be doing is creating a hud and updating it's progress in some sort of download progress delegate callback.

The example you should be looking at is https://github.com/jdg/MBProgressHUD/blob/master/Demo/Classes/HudDemoViewController.m#L156 , together with the following delegate callbacks https://github.com/jdg/MBProgressHUD/blob/master/Demo/Classes/HudDemoViewController.m#L226.