4

I am new to iOS development, I am using monotouch for developing the iOS apps, i want to know the time since the app was idle, i got the ObjC code but am unable to convert it into c#. Here is the code:

- (void)sendEvent:(UIEvent *)event {
    [super sendEvent:event];

    // Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets.
    NSSet *allTouches = [event allTouches];
    if ([allTouches count] > 0) {
        // allTouches count only ever seems to be 1, so anyObject works here.
        UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
        if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
            [self resetIdleTimer];
    }
}

- (void)resetIdleTimer {
    if (idleTimer) {
        [idleTimer invalidate];
        [idleTimer release];
    }

    idleTimer = [[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO] retain];
}

 - (void)idleTimerExceeded {
    NSLog(@"idle time exceeded");
}

Can anyone help me in converting this to c#.

vzm
  • 2,440
  • 6
  • 28
  • 47
Saurabh Sashank
  • 280
  • 1
  • 5
  • 18

1 Answers1

8

There's certainly better way to achieve this, but let's do a almost line to line translation fo this Obj-C code to Xamarin.iOS C#:

sendEvent is a method of UIApplication. It's very uncommon to subclass it, see Subclassing notes on UIApplication class reference

Once you subclassed it, you have to instruct the runtime to use it, that's done in the Main method, normally found in Main.cs. Here's what the modified Main.cs looks like now.

public class Application
{
    // This is the main entry point of the application.
    static void Main (string[] args)
    {
        UIApplication.Main (args, "MyApplication", "AppDelegate");
    }
}

[Register ("MyApplication")]
public class MyApplication : UIApplication
{

}

Notice the Register attribute on the class, used as second argument of UIApplication.Main.

Now, let's translate your code for real:

[Register ("MyApplication")]
public class MyApplication : UIApplication
{
    public override void SendEvent (UIEvent uievent)
    {
        base.SendEvent (uievent);
        var allTouches = uievent.AllTouches;
        if (allTouches.Count > 0) {
            var phase = ((UITouch)allTouches.AnyObject).Phase;
            if (phase == UITouchPhase.Began || phase == UITouchPhase.Ended)
                ResetIdleTimer ();
        }
    }

    NSTimer idleTimer;
    void ResetIdleTimer ()
    {
        if (idleTimer != null) {
            idleTimer.Invalidate ();
            idleTimer.Release ();
        }

        idleTimer = NSTimer.CreateScheduledTimer (TimeSpan.FromHours (1), TimerExceeded);
    }

    void TimerExceeded ()
    {
        Debug.WriteLine ("idle time exceeded");
    }
}

I replaced maxIdleTime by TimeSpan.FromHours (1). Otherwise, you'll have the same behaviour as the Obj-C one, including bugs if any (it looks ok though).

Stephane Delcroix
  • 16,134
  • 5
  • 57
  • 85
  • Thanks, Stephane for doing this great workaround for me its working like a charm, I also got some idea from your answer here http://stackoverflow.com/questions/16331680/session-maintenance-in-monotouch which i got today. – Saurabh Sashank Nov 13 '13 at 06:21
  • haha, I was quite sure I answered something that required overriding UIApplication already ! – Stephane Delcroix Nov 13 '13 at 15:47
  • Awesome. Just found that it should be idleTimer.Dispose(); instead of "release" and TimerExceeded(NSTimer obj). – Ph0b0x Jun 21 '17 at 20:10