flutter compile time conditional - flutter

i've added a baclground isolate and it works fine on macos and android, but as soon as i flutter run -d chrome i.e. compile for web i get a compile time error:
[...] Error: Member not found:
'BackgroundIsolateBinaryMessenger.ensureInitialized'.
BackgroundIsolateBinaryMessenger.ensureInitialized(input.rootIsolateToken);
^^^^^^^^^^^^^^^^^
which makes sence since thats not supported in web
but how can i omit this when compiling for web, i tried this but it wont work:
if (!kIsWeb) {
// Register the background isolate with the root isolate.
// comiler still unhappy that this member doenst exist, but it should simply skip this block
BackgroundIsolateBinaryMessenger.ensureInitialized(input.rootIsolateToken);
}
similar to c's #if, #endif
but how can i omit this when compiling for web, i tried this but it wont work:
if (!kIsWeb) {
// Register the background isolate with the root isolate.
// comiler still unhappy that this member doenst exist, but it should simply skip this block
BackgroundIsolateBinaryMessenger.ensureInitialized(input.rootIsolateToken);
}
similar to c's #if, #endif
is this a flutter bug or am i supposed to wrap the BackGroundIsolateBinaryMessenger in my own lib like described in this answer?

Related

Building DLL for Unity with functions with callback fails

I want to build DLL for Unity with functions with callback.
When I build with X64, Callback function works.
But when I build with arm64 and deploy it on HoloLens2, it doesnot work.
Here is my code to build DLL
enter image description here
Here is my code to use it.
enter image description here
Accroding to the result shown in HoloLens. It shows "20". So the fuction "Add" runs, But callback doesnot run.
Thanks if someone can help me.
I've had some experience with native->managed callbacks in my day. Yours is simple and should work without a hitch. One thing that raises a bit of a suspicion is the calling convention of the delegate. In general calling conventions are more of a 32bit era thing. In 64bit code there is one convention so it should just be left at the default. I'd suggest you remove the explicit calling convention declarations from the attributes.
Another thing I've noticed is that squiggly green line on your screenshot. Since you already declared the callback type as typedef int (*addP)(int) why not actually use it in the function definition?
int TestAddWithCallBack(addP callback)
{
int result = Add(3,5);
return callback(result);
}
You may also want to test if the TestAddWithCallBack function is even getting called at all. Change it to:
int TestAddWithCallBack(addP callback)
{
int result = Add(3,5);
return result;
}
and see if it returns properly.

Avoid `print` calls in production code. (Documentation)

I started seeing this warning in all my print statements.
print('Foo'); // Warning: Avoid `print` calls in production code.
It is because of the flutter_lints package which is implicitly added to new projects created after Flutter 2.3.0.
You can use any of the following solutions.
To remove the warning in that single line:
// ignore: avoid_print
print('Hello World');
To remove the warning in that file
// ignore_for_file: avoid_print
print('Hello World');
To remove the warning from the whole project.
Open analysis_options.yaml file and add this linter rule:
include: package:flutter_lints/flutter.yaml
linter:
rules:
avoid_print: false
Why not debugPrint or log?
Although you can also use debugPrint, or log (from dart:developer), but there are a few reasons why I don't like them.
They both work only in Flutter apps (not Dart apps)
You'll have to manually import a library for them to work (importing is such a pain unless imports on fly is implemented in IDE)
They accept only a String as an argument, unlike print which accepts an Object? (everything)
Developers shouldn't suppress such analyzer warnings as well as not use print() for apps they are building. print() will print logs in release builds as well, which is something that shouldn't happen as some developers might log sensitive information.
The suggested by other people debugPrint() is just a wrapper for print() to avoid losing some logs on Android in case the print() function called too often or the output there is too big.
What should be used instead is log() function available in dart.developer, which allows to also attach an error object, severity level, name, etc. of the logged event and won't print anything in release mode, so no information will leak.
Here is more information about proper logging approach, which also describes log() function: https://docs.flutter.dev/testing/code-debugging#logging
If you're printing a lot of logs for debugging, it's better to use debugPrint(String) as mentioned in this answer. Printing numerous amount of lines could sometimes lead the Android kernel to drop some of the lines if you're hitting the limit.
If using print(String) is really needed for your use-case, you're right on adding the lint check for avoid_print since it seems to be set to true by default.
other answers helps to avoid the warning, but why this warning appear and how to fix it?
using print method make your logs available to users when using flutter logs command, so if you log any sensitive data that would be dangerous,
does debugPrint solve this issue and print only in debug mode?
the answer is no, not by default, but the good point with debugPrint that you can override its behavior in a way that makes it not printing in release mode
void main() {
if (kReleaseMode) {
debugPrint = (String message, { int wrapWidth }) {} //
}
}
Null safe working version in 2022:
import 'package:flutter/foundation.dart';
void main() async {
if (kReleaseMode) {
debugPrint = (String? message, {int? wrapWidth}) => '';
}
Replace all print( to logPrint(
Create a new Function
logPrint(String s){print(s);}
And you can remark all the print commands in one line

Why does Dart have so many silent runtime exceptions/errors?

I have been getting very frustrated with Dart as runtime exceptions seem to fail silently. Program execution will continue after some type of failure and leave me totally stumped about what is not working and why. For example, in using aqueduct for dart server (this is not an issue unique to aqueduct, but dart in general) I have this code:
jsonData.forEach((jsonObject) async {
ManagedObject record = Document();
record.read(jsonObject);
print(Util.jsonFormatToString(record.asMap()));
....more code
}
In this case, the application fails silently on record.read() falls out of the forEach loop and then continues code execution. During debugging, the application returns completely strange results and after debugging, presumably there is a problem with the jsonObject attempting to be read into the managed object, but Dart gives no notice that there is a problem or what that problem might be.
This is one example of many I have been running into.
Why does Dart fail so silently or am I missing some setting somewhere that is hiding critical info? I am using IntelliJ IDE.

Xcode compiler error not highlighted in editor

Xcode has started displaying a compiler error as soon as I open my project (i.e. a build is not required) but it's all a bit odd. One error is shown in the build time tab but when I open the compiler message window there are three identical errors spread across multiple files. The errors are not highlighted in the editor window so I can't trace them but as they're flagged in files I haven't touched recently I suspected the problem was with Xcode rather than my code.
The error is shown in the build time window as:
Swift Compiler Error - cannot convert value of type '()' to closure result type 'Observable<Void>'
In the messages window:
<unknown>:0: error: cannot convert value of type '()' to closure result type 'Observable<Void>'
These errors are spread across three files in the messages window, all of which use at least one RxSwift dependency (RxDataSources, RxSwift, and RxCocoa) and, as noted above, I haven't touched a couple of them for a week or two and my dependencies have not been recently amended so I can be reasonably certain they are not the issue.
I've done all the usual (clean, clear cache, reboot, checked error display settings, roll back to an earlier version, update dependencies, reinstall Xcode) but the error persists and I'm effectively locked out of further development until I can resolve it. To say that I'm frustrated would be an understatement!
I'm running Xcode 10.2.1 (10E1001)
Help!!
I took the app apart and then added in each class individually until the error popped up again. The problem was a typo (syntax error) in a view model struct, specifically, the line:
let editTapped = CocoaAction { return }
which should have been:
let editTapped = CocoaAction {
// do stuff
return .empty()
}
I'm guessing the failure of the compiler to highlight the error in the editor pane is a bug so I'll report it (unless anyone has views to the contrary?) as it was very time consuming to sort out. The odd things was that rolling back to a previous working version didn't fix it - I had to delete the entire app and then rebuild it from scratch manually adding the files as I went. Weird...

Why does assert simply terminate a program compiled for iPhone?

I'm debugging a heavily assert()'ed iPhone app (Xcode, Objective-C++, and device simulator). In some cases, the assert failure would just terminate the app, instead of breaking into the debugger as I'd expect.
I made a workaround by implementing my own kinda-assert to the effect of:
#define AssertLite(b) if(!(b)) {asm {int 3}}
(fluff omitted), but I wonder if anyone ever encountered this. I could not determine a pattern as to when does it break and when does it terminate. The code is not threaded; all it does is done in event handlers.
Why does this happen and how do I make vanilla assert() behave like a conditional breakpoint it should be?
First off, since you are working on an iPhone app, you should probably use NSAssert() instead of the vanilla BSD assert function.
e.g. NSAssert(the_object, #"NIL object encountered");
The NSAssert macro will throw an Objective-C exception (NSInternalInconsistencyException) if the assertion fails.
Since your goal is to break on the exception, the next step is to make the Xcode debugger break on Objective-C exceptions. This is probably a good thing to do anyway.
In the Breakpoints window (Run->Show->Breakpoints menu item), click where it says "Double-Click for Symbol" to enter the symbol -[NSException raise]
The last thing to be careful off is that NSAsserts do not compile out in a release build. That means that you have to either be prepared to handle the exception in your application, or you need to create your own macro that does compile out in release builds.
Here's the macro I use to compile out assertions in runtime code (note that I then use HMAssert in my code instead of NSAssert):
#ifdef DEBUG
# define HMAssert(A,B) NSAssert(A,B)
#else
# define HMAssert(A,B)
#endif
This requires a DEBUG preprocessor macro to be defined. Here's how to set that up:
Right-click on your project in Xcode. That will be the top item in the left panel where your projects files are listed
Select "Get Info" from the context menu that pops up.
Go to the "Build" tab.
Make sure the "Configuration" is set to "Debug".
Type DEBUG into the field next to "Preprocessor Macros" under "GCC 4.2 - Preprocessing".
First of all, if you "Add Exception Breakpoint..." in the Breakpoint Navigator (⌘6), the debugger will stop on NSAssert's failures, allowing you to look at the stack and understand what went wrong.
You should use the standard NSAssert. If you use it correctly, there is not a lot that you need to manually create -- everything Mike mention is similar to the default NSAssert implementation.
You should run you release configuration with NS_BLOCK_ASSERTIONS set in your precompiled headers (follow Mike's steps), to disable assertions. If you need more info on why to do so, check out: http://myok12.wordpress.com/2010/10/10/to-use-or-not-to-use-assertions/
In Xcode 4 and new iOS, NSAssert may actually take a variable list of parameters. This may be useful to log some values together with the assert. The compiling-out assert (see answer by Mike above) could be defined like this:
#ifdef DEBUG
# define DAssert(A, B, ...) NSAssert(A, B, ##__VA_ARGS__);
#else
# define DAssert(...);
#endif
Also, there is no longer Run → Show → Breakpoints menu item. See this post to set up Xcode 4 to break on an assert as defined above.
One time I saw a different behavior from the assert() calls once. It was caused by the compiler picking up different macro definitions at different portions of the build process.
Once the include paths were straightened out, they all worked the same.