Session maintenance in monotouch?

2019-05-28 01:56发布

问题:

My application based on banking domain, need session handling. When application is idle (without any touch events after application open) have to calculate the time in background.

I handle the session maintenance when application entered into foreground and onResignInactive events in AppDelegate.

I need to handle application when live. Please help me to figure out this feature

回答1:

There's an answer for obj-C there: iOS perform action after period of inactivity (no user interaction)

So, at the application level, you keep a timer, and reset it on any event. Then you can do your business (like hiding any sensitive information) in the timer's handler.

Now, to the code.

First, you have to subclass UIApplication and make sure yours is instantiated:

//Main.cs
public class Application
{
    static void Main (string[] args)
    {
        //Here I specify the UIApplication name ("Application") in addition to the AppDelegate
        UIApplication.Main (args, "Application", "AppDelegate");
    }
}

//UIApplicationWithTimeout.cs

//The name should match with the one defined in Main.cs
[Register ("Application")]
public class UIApplicationWithTimeout : UIApplication
{
    const int TimeoutInSeconds = 60;
    NSTimer idleTimer;

    public override void SendEvent (UIEvent uievent)
    {
        base.SendEvent (uievent);

        if (idleTimer == null)
            ResetTimer ();

        var allTouches = uievent.AllTouches;
        if (allTouches != null && allTouches.Count > 0 && ((UITouch)allTouches.First ()).Phase == UITouchPhase.Began)
            ResetTimer ();
    }

    void ResetTimer ()
    {
        if (idleTimer != null)
            idleTimer.Invalidate ();
        idleTimer = NSTimer.CreateScheduledTimer (new TimeSpan (0, 0, TimeoutInSeconds), TimerExceeded);
    }

    void TimerExceeded ()
    {
        NSNotificationCenter.DefaultCenter.PostNotificationName ("timeoutNotification", null);
    }
}

This will ensure you have a timer running (caveat: the time starts only at the first event), that the timer will resets itself at any touch, and that a timeout will send a notification (named "timeoutNotification").

You now can listen to that notification and act on it (probably pushing a cover ViewController)

//AppDelegate.cs
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
    UIWindow window;
    testViewController viewController;

    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        window = new UIWindow (UIScreen.MainScreen.Bounds);

        viewController = new testViewController ();
        window.RootViewController = viewController;
        window.MakeKeyAndVisible ();

        //Listen to notifications !
        NSNotificationCenter.DefaultCenter.AddObserver ("timeoutNotification", ApplicationTimeout);

        return true;
    }

    void ApplicationTimeout (NSNotification notification)
    {
        Console.WriteLine ("Timeout !!!");
        //push any viewcontroller
    }
}

@Jason had a very good point that you shouldn't rely on client timeout for your session management but you should probably maintain a server state - and timeout - as well.



回答2:

If you were writing this as a web app, you would put the session timeout logic on the server, not the client. I would take the same approach with a mobile client also - have the server manage the session and timeout.