0

Have an app that works but uses the deprecated NSURL calls - downloads data that is used to create bar graphs. With the new NSURLSESSION calls it appears one needs to manage queuing/threading - have to wait for the download before the parsing and drawing can happen.

I create a new single view project (objective-c); File + New and create a UIView that I then associate to the view (so get the 'void drawRect:(CGRect) rect { // code goes here }' .m file

Have tried many things including following the 268 upvote answer in this thread :

Waiting until two async blocks are executed before starting another block

No matter what I do the CGRect code fires before the NSURL call completes (and it's not even a huge amount of data - as little as 4 sets of X,Y coord points to be used to create a bar chart). And also get the 'Invalid Context 0x0' error - even if I hardcode in the start, end values for the line drawing.

Edited to show complete .m file......

- (void)drawRect:(CGRect)rect {
    // Drawing code

    dispatch_group_t group = dispatch_group_create();

    // pair a dispatch_group_enter for each dispatch_group_leave
    dispatch_group_enter(group);     // pair 1 enter
    [self computeInBackground:1 completion:^{


        // NSURLSESSION - get x,y coord data
        //                parse
        //                save values
        NSLog(@"1 done");
        dispatch_group_leave(group); // pair 1 leave
    }];

    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{



                dispatch_async( dispatch_get_main_queue(),
               ^{
                  UIColor * greenColor = [UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:1.0];
                    CGContextRef context = UIGraphicsGetCurrentContext();

                    CGContextSetLineWidth (context, 24.0);
                    CGContextSetStrokeColorWithColor (context, greenColor.CGColor);

                    CGContextMoveToPoint(context, 10.0, 100.0);
                CGContextAddLineToPoint(context, 150.0, 100.0);

                CGContextStrokePath (context);


        NSLog(@"finally!");

        });


    });


}

- (void)computeInBackground:(int)no completion:(void (^)(void))block {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"%d starting", no);
        sleep(no*2);
        block();
    });
}


@end
user3741598
  • 297
  • 1
  • 12
  • Sorry but I don’t see any URLSession code in your question. Since that is what the question is apparently about, and since we have no idea what you doing with the session, wouldn’t it be a helpful thing to show us that? – matt Feb 18 '20 at 01:16
  • Also you cannot do anything asynchronous in drawRect. It doesn’t matter if this seemed to work before. The architecture of your code is totally wrong. You do your asynchronous stuff and then call `setNeedsDisplay` which calls `drawRect` See http://www.apeth.com/iOSBook/ch38.html#_grand_central_dispatch for an example. – matt Feb 18 '20 at 01:18
  • I wanted to post the least amount of code to replicate the problem. (very easy for you to create a new project, create the UIView, associate, and paste my code in your .m and see the error). The problem isn't with the NSURLSESSION - if you re-read my initial comments you'll see I said 'even if I hardcode in'. But thanks for at least looking. – user3741598 Feb 18 '20 at 01:28
  • NSURLSession already are inheriting the NSQueue class so you do not need to manage it yourself, just use the readily available completion blocks. – GeneCode Feb 19 '20 at 07:36

0 Answers0