Skip to content

Instantly share code, notes, and snippets.

@seanfisher
Last active April 10, 2023 12:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanfisher/66bdf388351c1c2a18931deac986bbff to your computer and use it in GitHub Desktop.
Save seanfisher/66bdf388351c1c2a18931deac986bbff to your computer and use it in GitHub Desktop.
A pattern for a Xamarin.iOS controller that permits "safe" async lifecycle methods.
using System;
using System.Threading.Tasks;
using UIKit;
namespace Seanfisher.Gists
{
public abstract class AsyncInitializationController : UIViewController
{
Task _viewDidLoadAsyncTask = Task.CompletedTask;
public virtual Task ViewDidLoadAsync()
{
return _viewDidLoadAsyncTask;
}
public sealed override async void ViewDidLoad()
{
try
{
base.ViewDidLoad();
_viewDidLoadAsyncTask = ViewDidLoadAsync();
await _viewDidLoadAsyncTask;
}
catch (Exception e)
{
// Handle
}
}
Task _viewWillAppearAsyncTask = Task.CompletedTask;
public virtual Task ViewWillAppearAsync()
{
return _viewWillAppearAsyncTask;
}
public sealed override async void ViewWillAppear(bool animated)
{
try
{
await _viewDidLoadAsyncTask;
base.ViewWillAppear(animated);
_viewWillAppearAsyncTask = ViewWillAppearAsync();
await _viewWillAppearAsyncTask;
}
catch (Exception e)
{
// Handle
}
}
Task _viewDidAppearAsyncTask = Task.CompletedTask;
public virtual Task ViewDidAppearAsync()
{
return _viewDidAppearAsyncTask;
}
public sealed override async void ViewDidAppear(bool animated)
{
try
{
await _viewDidLoadAsyncTask;
await _viewWillAppearAsyncTask;
base.ViewDidAppear(animated);
_viewDidAppearAsyncTask = ViewDidAppearAsync();
await _viewDidAppearAsyncTask;
}
catch (Exception e)
{
// Handle
}
}
}
// Example Usage
public class MyController : AsyncInitializationController
{
// Override ViewDidLoadAsync instead of ViewDidLoad
public override async Task ViewDidLoadAsync()
{
await SomeInitializationLogicAsync();
}
public override async Task ViewWillAppearAsync()
{
// Here it's guaranteed that the ViewDidLoadAsync finished completely
// before calling this line, which is NOT guaranteed
// with the normal UIViewController lifecycle methods if they run
// async tasks.
await SomeViewPreparationLogicAsync();
}
}
}
@BatriderLEL
Copy link

Any sample how to use it :|? Thanks!

@seanfisher
Copy link
Author

@BatriderLEL I added a simple sample controller class. Does that help?

@omatrot
Copy link

omatrot commented Apr 10, 2023

How can I access the Page (and its ViewModel) associated to the async controller? What to do into the page OnAppearing() method? Is it useless now?
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment