How to get to use GsonSerializer for ktor? - gson

In https://ktor.io/docs/json.html#gson, I can see we can have GsonSerialzer as the code
install(JsonFeature) {
serializer = GsonSerializer() {
setPrettyPrinting()
disableHtmlEscaping()
}
}
But I can't seem to get to include this class. Which library should I import (in my Gradle) to have access to them?

implementation "io.ktor:ktor-client-gson:$ktor_version"
From the docs

A quick note, GSON will only work for JVM targets as its a java serialization/deserialization library.
If you have native targets then you probably want to use kotlinx-serialization (ktor-client-serialization)

Related

Get the project instance from kotlin's gradle

I'm trying to migrate a script from Groovy's gradle to Kotlin's gradle.
The function:
def Group(Closure closure) {
closure.delegate = dependencies
return closure
}
ext {
aGroup = Group {
implementation xyz
kapt xpto
...
}
...
}
What I manage to do:
object Group {
operator fun <T> invoke(project: Project, closure: Closure<T>):Closure<T> {
closure.delegate = project.dependencies
return closure
}
}
Notice that I've added the extra arg Project.
Groovy access the project property directly, I would like to know how can I get this directly from kotlin too, so I'll be able to remove that extra arg and keep the previous syntax.
Short answer: You can't
Long answer:
You can't due to the strong/statically typed nature of Kotlin (and Java). Groovy is a dynamic language and lets you get away with many things, to an extent. In addition to the dynamic nature of Groovy, Gradle implements a lot of the metaprogramming that Groovy offers.
So even though you do not explicitly pass in a Project in your Groovy script, behind the scenes it is being looked up dynamically.
You could make Group an extension of Project to have a reference of project.

Xamarin.Forms DependencyService not for all platforms

In the docs it is clearly stated that you need an implementation for all platforms:
You must provide an implementation in every platform project. If no
Interface implementation is registered, then the DependencyService
will be unable to resolve the Get<T>() method at runtime.
I haven't provided an implementation and so the app crashed. But what should I do in the case, that I don't need an implementation for that platform? Providing a bodyless method like this?
public void HideKeyboard()
{
// We need an implementation for the DependencyService, even it is empty.
}
Should I provide an implementation nevertheless?
public void HideKeyboard()
{
try
{
InputPane myInputPane = InputPane.GetForCurrentView();
myInputPane.TryHide();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
Or is the use of DependencyService the wrong option here?
I am assuming that you do not need an implementation on one platform, but do on the other.
There is basically two things you can do:
Provide a bodyless implementation on the platform where you don't need an actual implementation, like you suggested yourself
or; put a check for the platform around the DependencyService call.
If you need it only on iOS, just do it like this in your shared code:
if (Device.RuntimePlatform == Device.iOS)
DependencyService.Get<IKeyboardService>().HideKeyboard();
This way you don't litter your code with a redundant class. You do need to add this in all places where you're going to execute this code. So what the better option is here is up to you.
Using the DependencyService isn't wrong and actually the only way to reach this kind of platform specific functionality.
In addition to the two options Gerald mentioned of having a bodyless implementation or only calling Get on select platforms, you can also just check the return value of Get and only use the service if there is one. In code, this would be:
var ds = DependencyService.Get<IKeyboardService>();
if (ds != null)
ds.HideKeyboard();
or as a one-liner:
DependencyService.Get<IKeyboardService>()?.HideKeyboard();

How to move a gradle function from build.gradle into a plugin?

Currently, I have a few utility functions defined in the top level build.gradle in a multi-project setup, for example like this:
def utilityMethod() {
doSomethingWith(project) // project is magically defined
}
I would like to move this code into a plugin, which will make the utilityMethod available within a project that applies the plugin. How do I do that? Is it a project.extension?
This seems to work using:
import org.gradle.api.Plugin
import org.gradle.api.Project
class FooPlugin implements Plugin<Project> {
void apply(Project target) {
target.extensions.create("foo", FooExtension)
target.task('sometask', type: GreetingTask)
}
}
class FooExtension{
def sayHello(String text) {
println "Hello " + text
}
}
Then in the client build.gradle file you can do this:
task HelloTask << {
foo.sayHello("DOM")
}
c:\plugintest>gradle -q HelloTask
Hello DOM
https://docs.gradle.org/current/userguide/custom_plugins.html
I implemented this recently, a full example is available at Github.
The injection basically boils down to
target.ext.utilityMethod = SomeClass.&utilityMethod
Beware:
This method could potentially conflict with some other plugin, so you should consider whether to use static imports instead.
Based on Answer 23290820.
Plugins are not meant to provide common methods but tasks.
When it comes to extensions they should be used to gather input for the applied plugins:
Most plugins need to obtain some configuration from the build script.
One method for doing this is to use extension objects.
More details here.
Have a look at Peter's answer, using closures carried via ext might be what you are looking for.

Trying to use getArgumentAtIndexAsObject from NSInvocation+OCMAdditions.h

maybe it's a silly thing... I'm trying to use
- (id)getArgumentAtIndexAsObject:(NSInteger)argIndex;
From NSInvocation+OCMAdditions.h, but I can't import the Category and if try to use the method is not available.
I'm using cocoaPods to get OCMock and I imported the header class:
#import <OCMock/OCMock.h>
maybe is a setting in cocoaPods?
Any help is appreciated.
Thanks
Finally as Erick said is not possible to use that method, so I used this way:
//We mock the methods loginWithUser
[[[controllerMocked stub] andDo:^(NSInvocation *invocation) {
void (^sucessBlock)(NSString *token);
[invocation getArgument:&sucessBlock atIndex:4];
sucessBlock(#"1234567890");
}] loginWithUser:[OCMArg any] andPassword:[OCMArg any] withSuccess:[OCMArg any] withFailure:[OCMArg any]];
However the right answer is the Erick one :)
This is a private method intended to be used by OCMock internally. It is not exported as part of the pod.
The reason is that I'm trying to keep the public API of OCMock, which must be supported for a long time, as small as possible.
If you want to use getArgumentAtIndexAsObject: in your project do so by adding the corresponding header file to your project. However, there is no guarantee that the method will be available in future versions of OCMock.

An alternative to TaskEx.FromResult on a platform where it's not available

I am converting a portable class library to use a different profile (78). Most of the changes were related to reflection API, and now I have few last lines that don't compile, all of them are using TaskEx.FromResult.
TaskEx.FromResult is handy when a method returns Task, and a value of T needs to be wrapped and returned from the method, e.g.:
public Task<int> ReturnTaskOfInt()
{
return TaskEx.FromResult(42);
}
Unfortunately TaskEx is not available for some PCL profiles. Perhaps it shouldn't be hard to write a replacement for it, and I will appreciate an advise.
Oops, it was damn easy. TaskEx.FromResult is not available, but Task.FromResult is there.

Resources