AdvancedTimer icon indicating copy to clipboard operation
AdvancedTimer copied to clipboard

iOS PCL project using AdvancedTimer will not run on iPhone unless Debugging is enabled

Open lbettrid opened this issue 10 years ago • 36 comments

I have an app which uses a PCL and 2 platform specific projects for iOS and Android and makes use of the AdvancedTimers.

The android app works fine, but the iOS app will only work on a device with debugging enabled in the iOS Build options. If I comment out all the code associated with the AdvancedTimers then the app will work again.

lbettrid avatar Mar 02 '15 17:03 lbettrid

You are right. It is fine with emulator, but it crashes on a device on release mode. I will try to get crash logs from the device and symbolicate to what's wrong with it.

I'll let you know.

ufuf avatar Mar 03 '15 22:03 ufuf

I am facing the same issue. I released the app for client testing & they were not even able to go to the second screen where timer was used. The instance of the timer is always null in release mode.

supreettare avatar Apr 14 '15 06:04 supreettare

I'm sorry I couldn't find time to fix that. There is something wrong with nuget package. You can fork and directly use code from github to fix that. Imported code just works fine on release mode.

ufuf avatar Apr 14 '15 07:04 ufuf

No Sorry. I don't think this is nuget issue here. I forked your code, build locally in release mode & hooked the DLL thus generated in my code. All works fine as long as you are running the app in debug mode, it crashes the app in release mode. Same results.

supreettare avatar Apr 14 '15 14:04 supreettare

Try by directly adding code to your project instead of compiling and adding DLL. I tried by copying code into a sample project and it worked fine with release mode.

ufuf avatar Apr 14 '15 20:04 ufuf

I implemented your code in my app (copied the interface & its implementation for IOS) & so far it seems like its working fine. Thanks

supreettare avatar Apr 15 '15 05:04 supreettare

Ran into same issue, implementing code directly seems to be working. Nice implementation.

rlingineni avatar Sep 13 '15 05:09 rlingineni

Is this still an issue? Or has it been fixed?

RogerSchmidlin avatar Jan 17 '16 15:01 RogerSchmidlin

It was fixed on the project but I am not sure if the fix is pushed here.

ufuf avatar Jan 17 '16 16:01 ufuf

I am using NuGet version 1.0.1.0. Is it fix in there?

RogerSchmidlin avatar Jan 18 '16 03:01 RogerSchmidlin

This issue is still happening for me. Integrating the code into my project didn't help. However, setting the IoS Build to Debugging Enabled didn't help. The downside is that it doubled the size of my IPA file.

ossentoo avatar Feb 09 '16 00:02 ossentoo

For some reason, advanced timer is not working for me on either iOS or Android. It works in one PCL class but not in another. Seems odd.

adrianknight89 avatar Feb 17 '16 06:02 adrianknight89

@adrianknight89 you maybe experiencing the same problem as me, each time you call DependencyService.Get<IAdvancedTimer>(); you get the same object back, so the first time it works great, however if you want to use it again elsewhere its already bound to the callback when you used it the first time you called it, so appears to not work.

Looking into DependencyService it looks like its suited to more singleton model, where there is only a single instance returned, however timers you would expect to be able to create multiple objects.

mannyvw avatar Feb 23 '16 15:02 mannyvw

Actually don't have to use DependencyService at all can use any IOC container

e.g. using Autofac which xamarin.forms uses,

So on iOS/Android side call following to register :-

builder.RegisterType<AdvancedTimerImplementation> ().As<IAdvancedTimer> ();

then on PCL side, you can use following code which will create a new object each time

timer = ServiceLocator.Current.GetInstance<IAdvancedTimer>();

mannyvw avatar Feb 23 '16 15:02 mannyvw

I'm not sure my issue is the same as that above. I'm not even able to call the timer once before some kind of exception occurs (which unfortunately I can't trap). All I see is that when stepping through code and starting the timer, it is as if the current thread is terminated and execution appears elsewhere in my app. The timer doesn't appear to start either.

Although setting the iOS build with the debug option does work for me, my IPA size has pretty much doubled in size.

On 23/02/2016, mannyvw [email protected] wrote:

Actually don't have to use DependencyService at all can use any IOC container

e.g. using Autofac which xamarin.forms uses,

So on iOS/Android side call following to register :-

builder.RegisterType<AdvancedTimerImplementation> ().As<IAdvancedTimer> ();

then on PCL side, can you following code which will create a new object each time

timer = ServiceLocator.Current.GetInstance<IAdvancedTimer>();


Reply to this email directly or view it on GitHub: https://github.com/ufuf/AdvancedTimer/issues/5#issuecomment-187753052

ossentoo avatar Feb 24 '16 22:02 ossentoo

@mannyvw You're correct that DependencyService always returns the same instance. However, I figured there is a way to return a new instance each time. Try:

timer = DependencyService.Get<IAdvancedTimer>(DependencyFetchTarget.NewInstance);

adrianknight89 avatar Feb 25 '16 02:02 adrianknight89

I've been having the same issue with release mode, and a different issue where the timer would not re-init, so it only worked the first time.

@rlingineni suggestion of integrating the code directly, fixed my issue with release mode.

@adrianknight89 suggestion with the new instance, fixed the issue of the timer not re-initializing.

Thanks guys!

yhax avatar Feb 27 '16 14:02 yhax

Can confirm this is still an issue. Works fine until you try and use it in release mode on a device. Will try integrating the code directly. Thanks for the implementation!

Edit: worked fine by moving over the interface to the X.F PCL and the iOS and Android .cs files to their respective client projects.

SmartyP avatar Mar 11 '16 14:03 SmartyP

We ran in to this exact issue and have no resolution. Will have to move away from AdvancedTimer if it can't be resolved.

Tested on several iOS devices, running >= 8.1

  • Xamarin.Forms 2.1.0.6529
  • AdvancedTimer 1.0.1.0

thomashagstrom avatar May 09 '16 09:05 thomashagstrom

Only way i got it to work was include the code directly in project rather than use nuget package.

N

mannyvw avatar May 09 '16 10:05 mannyvw

Also running into this. Took me forever to figure out the problem but thank you all for letting me know of a workaround.

TravyDale avatar May 18 '16 03:05 TravyDale

@TravyDale what did you do to fix the problem? I tried building from source and include the UnifiedIOS and Abstractions DLLs, but now I am getting this error....

MTOUCH: Error MT2002: Failed to resolve "System.Void AdvancedTimer.Forms.Plugin.Abstractions.IAdvancedTimer::initTimer(System.Int32,System.EventHandler,System.Boolean)" reference from "AdvancedTimer.Forms.Plugin.Abstractions, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null" (MT2002)

Should I include anything else?

Is there another timer available for Xamarin.Forms that allows of cancelling the timer before it's Elapsed event? That's the only reason I'm using this library.

EDIT: Nevermind. I ripped the code out of the library and just put it directly into my app and it works fine.

eclipsed4utoo avatar May 20 '16 10:05 eclipsed4utoo

@eclipsed4utoo lol sorry for the delay in response. I see your EDIT and that is what I did and it works for me now too.

TravyDale avatar May 20 '16 12:05 TravyDale

Thanks all for posting the solution here, removing the nuget package and including the code directly into my project solved the issue for me. App successfully submitted to the app store :)

dconlisk avatar Jun 06 '16 15:06 dconlisk

Never thought that such a popular nuget package can have issue like this. I wasted my whole day on this issue. But thanks everyone for posting the solution. It worked for me after integrating the source code directly.

sarbjit-longia avatar Aug 06 '16 06:08 sarbjit-longia

Adding the untouched projects to the solution didn't worked either, You have to include the files directly in your current app. Sadly I wasted 2 hours with this looking at clueless ios logs =( anyway, it is what it is ... thanks guys

victorarce avatar Aug 10 '16 06:08 victorarce

An alternative solution to including the code directly into the iOS project is to simply include a dummy use of the AdvancedTimerImplementation class, so the linker does not blow away this class. For example, include the following class in the iOS project.

public class AdvancedTimerBootstrap
{
    public AdvancedTimerBootstrap()
    {
        new AdvancedTimerImplementation();
    }
}

ErnieScott avatar Sep 07 '16 20:09 ErnieScott

If anyone still maintains this project, adding the preserve attribute on the platform implementations should fix DLL issue.

[Preserve(AllMembers = true)]
public class AdvancedTimerImplementation : IAdvancedTimer {

swansca79 avatar Dec 29 '16 20:12 swansca79

Is this issue still persist with nuget package ? still need to add the files into the project ?

shrimantNikate avatar Jun 09 '17 07:06 shrimantNikate

@shrimantNikate Yes issue still remains with the nuget package.

ufuf avatar Jun 09 '17 13:06 ufuf

@ufuf I have implemented nuget package in my ongoing project, but seems working correctly. Can you pls let me know how can i reproduce this issue ?

shrimantNikate avatar Jun 09 '17 15:06 shrimantNikate

@shrimantNikate I don't use this library anymore but others state that the app is working fine on debug mode but not working on release mode with the nuget package.

ufuf avatar Jun 10 '17 10:06 ufuf

@ErnieScott Your solution worked for me. I just added the

new AdvancedTimerImplementation();

right after I registered the dependency.

Thanks for the suggestion!

Corneliuskruger avatar Dec 06 '17 04:12 Corneliuskruger

I just uploaded https://www.nuget.org/packages/info.dmwilson.AdvancedTimer.Forms.Plugin/1.0.2-alpha5 which appears to resolve this issue. I just used TestFlight to test a Release build of my iOS app, and the crash did not happen anymore.

Instead of using attributes to register the implementations with the Xamarin.Forms DependencyService, I just call DependencyService.Register() from the AdvancedTimerImplementation.Init() static method. If you try the updated NuGet package, please let me know how it goes.

~~FYI, my fork is not updated with these code changes yet. I'll try to get that done tomorrow.~~ I just checked in the changes on my fork: https://github.com/d-m-wilson/AdvancedTimer

P.S. I just noticed that I left the Preserve attribute on the iOS implementation. This was not intentional. At first, I tried decorating the Android and iOS implementations with the Preserve attribute as suggested by @swansca79, but the crash continued. And now I'm much too tired to remove the attribute, make a new AdvancedTimer build, make a new build of my app, submit new build to Apple, et cetera. :sleepy:

d-m-wilson avatar Jun 03 '19 07:06 d-m-wilson

@d-m-wilson I'm trying to use your fork. Can you explain what you mean by: Instead of using attributes to register the implementations with the Xamarin.Forms DependencyService, I just call DependencyService.Register() from the AdvancedTimerImplementation.Init() static method ?

What does that exactly look like? I'm assuming you are putting that in MainActivity.cs for Android and AppDelegate.cs for iOS?

Do you have a sample repo of how you implemented your fork? Thanks for any tips.

ryanbuening avatar Jan 22 '20 20:01 ryanbuening

@ryanbuening I was describing the fix for this issue, which I implemented in my fork of the library. You can see those changes here: https://github.com/d-m-wilson/AdvancedTimer/commit/01182d84a4a409109ab37e0d990bf82259852c38

No change to your app's code is needed beyond what is described in the README. Sorry, but I do not currently have sample code available.

d-m-wilson avatar Jan 23 '20 00:01 d-m-wilson