Bug 58167 - Notification Service extension just dies on call
Summary: Notification Service extension just dies on call
Status: RESOLVED DUPLICATE of bug 53207
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: XI 10.10 (d15-2)
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-07-14 16:15 UTC by Philipp Sumi
Modified: 2017-07-19 22:09 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Build output (3.91 MB, text/plain)
2017-07-15 09:59 UTC, Philipp Sumi
Details
The whole extension project (5.47 KB, application/zip)
2017-07-15 10:02 UTC, Philipp Sumi
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED DUPLICATE of bug 53207

Description Philipp Sumi 2017-07-14 16:15:10 UTC
I have a trivial notification service that is properly invoked. The received payload contains some JSON I want to parse using JSON.net. Now, the problem is that as soon as I attempt to do some work (in this case deserialize some JSON), the extension just seems to die and the alert is being displayed as received from the server. There's no exception or invocation of TimeWillExpire - it's just as if the handler wasn't called.

The snippet is below. Note that I'm not doing anything here but attempting to serialize a tiny DTO (which doesn't make sense, but it illustrates the issue). When I comment out that line, the alert shows as set on the next line.



        public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
        {
            ContentHandler = contentHandler;
            NotificationContent = (UNMutableNotificationContent)request.Content.MutableCopy();

            var payload = request.Content.UserInfo[new NSString("payload")] as NSString;
            string json = payload?.ToString();

            try
            {
                //invoking JsonConvert "kills" the extension
                json = JsonConvert.SerializeObject(new UserNotificationDto());                        

                NotificationContent.Title = $"has data";
                NotificationContent.Body = json;
            }
            catch
            {
                NotificationContent.Title = "damn";
                NotificationContent.Body = "an error occurred.";
            }

            contentHandler(NotificationContent);
        }
Comment 1 Vincent Dondain [MSFT] 2017-07-14 22:03:45 UTC
Please include your full build logs, crash reports (if any), test case (to reproduce) and all version information.

To get full build logs just set the log verbosity to diagnostic at the following locations:
- On Visual Studio for Mac: Preferences > Projects > Build
- On Visual Studio for Windows: Tools > Options > Projects and Solutions > Build and Run

On Visual Studio Windows you also want to add `-v -v -v -v` to the mtouch additional arguments by right-clicking the project in the solution explorer and selecting `Properties`.
Note: this is done automatically on Visual Studio for Mac when the log verbosity is set to diagnostic.

Easiest way to get exact version information:
- On Visual Studio for Mac: "Visual Studio" menu, "About Visual Studio" item, "Show Details" button.
- On Visual Studio for Windows: "Help menu", "About Microsoft Visual Studio" item.
Then copy/paste the version information (you can use the "Copy Information" button).
Comment 2 Philipp Sumi 2017-07-15 09:59:59 UTC
Created attachment 23578 [details]
Build output

Too long to paste as a comment...
Comment 3 Philipp Sumi 2017-07-15 10:02:06 UTC
Created attachment 23579 [details]
The whole extension project
Comment 4 Philipp Sumi 2017-07-15 10:02:47 UTC
Version information:

=== Visual Studio Enterprise 2017 for Mac ===

Version 7.0.1 (build 24)
Installation UUID: f02e2613-da3c-43b5-a91e-02e9d6b3c6d6
Runtime:
	Mono 5.0.1.1 (2017-02/5077205) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 500010001

=== NuGet ===

Version: 4.0.0.2323

=== .NET Core ===

Runtime: Not installed
SDK: Not installed
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.0.1/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.5.4
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Xamarin.Android ===

Version: 7.3.1.2 (Visual Studio Enterprise)
Android SDK: /Users/asli/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		6.0 (API level 23)

SDK Tools Version: 25.2.3
SDK Platform Tools Version: 25.0.1
SDK Build Tools Version: 25.0.1

Java SDK: /usr
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Inspector ===

Version: 1.2.2
Hash: b71b035
Branch: d15-1
Build date: Fri, 21 Apr 2017 17:57:12 GMT

=== Apple Developer Tools ===

Xcode 8.3.3 (12175.1)
Build 8E3004b

=== Xamarin.iOS ===

Version: 10.10.0.36 (Visual Studio Enterprise)
Hash: d2270eec
Branch: d15-2
Build date: 2017-05-22 16:30:53-0400

=== Xamarin.Mac ===

Version: 3.4.0.36 (Visual Studio Enterprise)

=== Build Information ===

Release ID: 700010024
Git revision: 7ab1ca2ced6f584e56b7a0d4d321d00775cd95c9
Build date: 2017-05-19 05:44:51-04
Xamarin addins: 08d17158f3365beee5e60f67999e607cce4b3f93
Build lane: monodevelop-lion-d15-2

=== Operating System ===

Mac OS X 10.12.5
Darwin 16.6.0 Darwin Kernel Version 16.6.0
    Fri Apr 14 16:21:16 PDT 2017
    root:xnu-3789.60.24~6/RELEASE_X86_64 x86_64
Comment 5 Philipp Sumi 2017-07-15 11:22:50 UTC
Comment on attachment 23579 [details]
The whole extension project

I'm serializing a dummy DTO there, which causes push notifications to appear as received (as if there was no service extension in the mix). Comment out call to JsonConvert, and the modified alert will show up instead. There doesn't seem to be a non-fatal exception, otherwise the code in the catch block would have executed instead.
Comment 6 Philipp Sumi 2017-07-15 16:34:24 UTC
Btw, when I attach the debugger to the extension, I'm also just falling out of the debug session without any debug output in the console as soon as `JsonConvert.Serialize` is being invoked. VS seems to be aware that the session ended, as I have to restart the debugger (pressing play in VS for Mac).
Comment 7 Rolf Bjarne Kvinge [MSFT] 2017-07-17 09:26:09 UTC
I think the problem is that your app is running out of memory.

Unfortunately Apple gives extensions a fairly low memory limit, and JSON.Net is quite memory hungry.

I suggest you read this bug report completely (another customer running into the exact same problem with JSON.Net, and he was able to solve it using a different json library): bug #53207.
Comment 8 Philipp Sumi 2017-07-17 14:53:49 UTC
Hi Rolf

Thanks for chiming in! I tried switching to SimpleJson, but the result is still the same. I'm currently referencing a small shared library that contains my DTOs plus a shared library with the parser that processes the DTOs to generate the messages, that's it. None of those libs have dependencies other than .NET, so the linker should strip pretty much everything. I really wouldn't know how to optimize this - after all, there's only very little code involved :/

(Link-all just crashes on me with some exceptions, and even trying to evaluate the stack trace already kills the extension. However, since those aren't any further dependencies, I assume even without the exceptiopn, the outcome would be the same).

Any further advice on how to get this working?
Philipp
Comment 9 Rolf Bjarne Kvinge [MSFT] 2017-07-18 18:58:45 UTC
First I'd confirm the problem really is that the app is running out of memory, see here: https://bugzilla.xamarin.com/show_bug.cgi?id=53207#c6 (and here: https://bugzilla.xamarin.com/show_bug.cgi?id=53207#c3)

Once that's confirmed, I'd try minimizing the project as much as possible (simplifying the sample json you're using, removing extra libraries, etc), and try to localize exactly where you hit the limit. This may enable you to find a workaround.
Comment 10 Philipp Sumi 2017-07-18 19:39:53 UTC
Yeah, I think I'm giving up on this. A library that requires me to basically fight for bytes in order not to crash on my customers is not production-ready IMO, also with regards to future use / different devices etc. I'll bite the bullet and generate all the messages on the server where I have more control.
Comment 11 Rolf Bjarne Kvinge [MSFT] 2017-07-19 07:13:52 UTC
Ok, I'll close this as a duplicate of bug #53207 then.

Please feel free to reopen if you have more questions or problems with this issue, and I'll be happy to help.

*** This bug has been marked as a duplicate of bug 53207 ***
Comment 12 Philipp Sumi 2017-07-19 13:20:43 UTC
Thanks Rolf!

Just made an accidental discovery, so I'll quickly reopen it: I just deployed a test version to TestFlight, and the notification service is working if I install that version on my phone. I'm a bit in a bind here now - a part of me want to keep it (because it's the much cleaner approach than generating localized content on the server), the other has severe trust issues :)

The build settings for Debug / Ad-hoc are completely identical, so I don't really have a clue what the difference would be. I just deployed a new local build (same sources) without the debugger, and this failed again.
Comment 13 Rolf Bjarne Kvinge [MSFT] 2017-07-19 13:29:43 UTC
You can try using release builds instead, those use slightly less memory, maybe it's enough to get below the limit.
Comment 14 Philipp Sumi 2017-07-19 15:23:19 UTC
Yes, release builds work as well. Damn, that's really a close call - not the least because Xamarin.iOS may just the same grow a little bit with any future release.

How substantial would you say is the debug build penalty, and how reliable do you think is the memory usage across different device / iOS versions? Can't shake the feeling that I'm playing with fire here ;)
Comment 15 Rolf Bjarne Kvinge [MSFT] 2017-07-19 15:49:41 UTC
(In reply to Philipp Sumi from comment #14)
> Yes, release builds work as well. Damn, that's really a close call - not the
> least because Xamarin.iOS may just the same grow a little bit with any
> future release.

We're planning on shrinking, but yes, it's not impossible that instead we grow just enough for you to hit the limit.

> How substantial would you say is the debug build penalty

Quite substantial in fact, I did a test here: https://bugzilla.xamarin.com/show_bug.cgi?id=53207#c1, and the debug build required ~1.3mb.

> and how reliable do you think is the memory usage across different device / iOS versions?

In our code there should be very little difference in memory usage between different iOS devices / versions, but one thing that may cause differences is the page size (iirc 64-bit devices have a 16kb page size, while 32-bit devices have a 4kb page size; it's possible 64-bit devices will use somewhat more memory in total because memory allocations are less granular due to the bigger page size).

> Can't shake the feeling that I'm playing with fire here ;)

That's a general description of software development ;)

My suggestion would be to test frequently on both 32-bit and 64-bit devices, as well as test when alphas are released for new Xamarin.iOS versions to catch bugs on our side that cause the memory usage to grow (if we break your app because our memory usage grows, we'll treat it as a regression / serious bug and try to fix it asap, but at the same time that requires us to know about it as early as possible - in other words if you file a bug once the broken version of Xamarin.iOS is in the stable channel, we won't be able to fix it until the next major stable version, which can be months away).

Also if the notifications have user-input, you should test with the biggest/most complex notification you can run into.

My opinion is that if you have comprehensive testing in place, you should go for it. Worst-case scenario you also have a fallback plan (go server-side, or even re-write the extension in swift/objective-c, which breaks my heart, but I know other people have done it fairly quickly).
Comment 16 Philipp Sumi 2017-07-19 16:43:30 UTC
Ok, I'll go for it and close the ticket now. Thanks for the comprehensive feedback Rolf - I really appreciate it!
Comment 17 Rolf Bjarne Kvinge [MSFT] 2017-07-19 17:26:44 UTC

*** This bug has been marked as a duplicate of bug 53207 ***
Comment 18 Philipp Sumi 2017-07-19 22:09:09 UTC
For general information: I'm back to square one. I added some more strings to the resources I have to localize, and that already caused the service to trip again. Weird enough, it's still working on release builds but not ad-hoc. Anyway - going server-side now. This seems to be too brittle to invest more time at this point, unfortunately.