1

In my chatting application, I have a ChatViewController.m that allows users to message with the QuickBlox framework.

When a user sends an image, a background upload begins and a UIProgressView displays the progress of the upload.

But what if the user backs out of that view during the upload, and returns in, say, 10 seconds while the upload is still happening. I want the UIProgressView to still be active and accurate based on that upload. But dismissing the ViewController doesn't allow me to do that.

Can someone suggest what I should be doing in this situation?

EDIT: This is how I present the ChatViewController.m, depending on the chat selected from the CollectionView:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.destinationViewController isKindOfClass:ChatViewController.class]){

        ChatViewController *destinationViewController = (ChatViewController *)segue.destinationViewController;

        if(self.createdDialog != nil){
            destinationViewController.dialog = self.createdDialog;
            self.createdDialog = nil;
        }else{

            QBChatDialog *dialog = [ChatService shared].dialogs[((UICollectionViewCell *)sender).tag];

            AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
            appDelegate.dialog = dialog;

        }
    }
}

EDIT 2: I have implemented the ViewController as a singleton in my didSelectItemAtIndexPath. But now, the app presents only a black screen.

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

        QBChatDialog *dialog = [ChatService shared].dialogs[indexPath.row];

        ChatViewController *chatView = [[ChatViewController alloc] init];
        chatView.dialog = dialog;
        [self presentViewController:chatView animated:YES completion:nil];

}
Adam G
  • 1,188
  • 10
  • 24
  • 1
    Hold a reference to your chat view controller, then when presenting the Chatviewcontroller, present that instance – BenJammin Oct 03 '15 at 19:06
  • The comments/answers you've gotten have been right on the money, but in order for us to really help you, you need to explain how you create and link to your ChatViewController. Is it invoked through an automatic segue attached to a button? Is it being presented as a modal? Pushed onto a navigation stack? We need to know the specifics before we can offer more than generalized answers. – Duncan C Oct 03 '15 at 19:15
  • 1
    I'm agree with @BenJammin. You should save a Strong reference to your view controller and save it in a safe place (Not disposed when ViewController dismissed) – Mehdi Hosseinzadeh Oct 03 '15 at 19:16
  • @BenJammin I have added an edit which shows how I create the ViewController – Adam G Oct 03 '15 at 19:22
  • @DuncanC please see my edit. The user selects a chat from the CollectionView and fires a modal segue – Adam G Oct 03 '15 at 19:23
  • @Mehdihosseinzadeh can you look at my edit showing how I present the view controller and perhaps offer some suggestions on how to best create/hold that strong reference – Adam G Oct 03 '15 at 19:30
  • I have problem with your logic. I think your logic is incorrect. You shouldn't use strong references to your View related objects because It's alloc and dealloc is out of your control. Instead I suggest upload your content in background and connect it to a view which may be showed or dismissed but that task is in progress in the background – Mehdi Hosseinzadeh Oct 03 '15 at 19:34
  • The fact that you want to do this is a Bad Smell. You should rearchitect. There is no need to keep a view controller around when its view has vanished. For example, you seem to think you cannot return to your view controller and restore its state to _look_ like it was running all this time, even though in fact it was dismissed and destroyed. But of course you absolutely can. – matt Oct 03 '15 at 20:36
  • Matt, I disagree. If the user can exit from and return to a chat view at will then it's reasonable to keep it around. That said, it's still a good idea to refactor so that the file upload/download is handled from a separate networking class. – Duncan C Oct 03 '15 at 21:28
  • To the OP, your new code is not using the singleton design pattern. I don't know what the dialog property of your VC is, but you are still alloc/init'ing a new instance of your VC. You need to replace `[[ChatViewController alloc] init]` with `[ChatViewController sharedChatViewController]` in the code that you posted (and then create the `sharedChatViewController` class method that loads the shared instance of your chat view controller (probably by using `instantiateViewControllerWithIdentifier`.) – Duncan C Oct 03 '15 at 21:31

2 Answers2

1

You should change the way you display your chat view controller. Don't use a segue.

Instead, set up your chat view controller as a singleton. Set up an IBAction or other code triggered by the user selecting an item in your collection view.

In that IBAction or didSelectItem code, fetch a reference to your singleton, configure it as needed, and present it modally yourself using presentViewController:animated:completion:

That way your view controller will preserve it's contents between views.

As the other poster said in a comment, you might pull the download logic out of your view controller and into a separate download manager class. It depends on whether you need the ability to do asynchronous downloads in places other than your chat view controller.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
0

I'm assuming based on your question that you are creating the view controller each time that you are presenting it. Instead of re-allocating and creating a new view controller each time you present the messaging view, make only one view controller that you can call and present from any other view controller.

A couple possible ways to do this are:

  1. Create a singleton that has the messaging view controller as a property

  2. Add the messaging view controller as a property on your route view controller

  3. Make the messaging view a singleton itself so only one gets created in the entire life of the application

Doing any of these will make sure that the view persists each time that it's dismissed.

If that still doesn't fix the problem, you may be resetting the view in viewDidLoad or viewDidAppear which I don't think is actually what you want to do.

Fennelouski
  • 2,411
  • 1
  • 18
  • 26