Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
lbettrid opened this issue Mar 2, 2015 · 36 comments

Comments

@lbettrid
Copy link

lbettrid commented Mar 2, 2015

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.

@ufuf
Copy link
Owner

ufuf commented Mar 3, 2015

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.

@supreettare
Copy link

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.

@ufuf
Copy link
Owner

ufuf commented Apr 14, 2015

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.

@supreettare
Copy link

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.

@ufuf
Copy link
Owner

ufuf commented Apr 14, 2015

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.

@supreettare
Copy link

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

@rlingineni
Copy link

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

@RogerSchmidlin
Copy link

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

@ufuf
Copy link
Owner

ufuf commented Jan 17, 2016

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

@RogerSchmidlin
Copy link

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

@ossentoo
Copy link

ossentoo commented Feb 9, 2016

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.

@adrianknight89
Copy link

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.

@mannyvw
Copy link

mannyvw commented Feb 23, 2016

@adrianknight89 you maybe experiencing the same problem as me, each time you call DependencyService.Get(); 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
Copy link

mannyvw commented Feb 23, 2016

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>();

@ossentoo
Copy link

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 ().As ();

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

timer = ServiceLocator.Current.GetInstance();


Reply to this email directly or view it on GitHub:
#5 (comment)

@adrianknight89
Copy link

@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);

@yhax
Copy link

yhax commented Feb 27, 2016

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!

@SmartyP
Copy link

SmartyP commented Mar 11, 2016

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.

@thomashagstrom
Copy link

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

@mannyvw
Copy link

mannyvw commented May 9, 2016

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

N

@TravyDale
Copy link

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

@eclipsed4utoo
Copy link

eclipsed4utoo commented May 20, 2016

@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.

@TravyDale
Copy link

@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.

@dconlisk
Copy link

dconlisk commented Jun 6, 2016

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 :)

@sarbjit-longia
Copy link

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.

@victorarce
Copy link

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

@ErnieScott
Copy link

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();
    }
}

@swansca79
Copy link

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 {

@shrimantNikate
Copy link

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

@ufuf
Copy link
Owner

ufuf commented Jun 9, 2017

@shrimantNikate Yes issue still remains with the nuget package.

@shrimantNikate
Copy link

@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 ?

@ufuf
Copy link
Owner

ufuf commented Jun 10, 2017

@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.

@Corneliuskruger
Copy link

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

new AdvancedTimerImplementation();

right after I registered the dependency.

Thanks for the suggestion!

@d-m-wilson
Copy link

d-m-wilson commented Jun 3, 2019

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. 😪

d-m-wilson added a commit to d-m-wilson/AdvancedTimer that referenced this issue Jun 3, 2019
@ryanbuening
Copy link

@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.

@d-m-wilson
Copy link

@ryanbuening I was describing the fix for this issue, which I implemented in my fork of the library. You can see those changes here: d-m-wilson@01182d8

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests