diff --git a/bin/jni/data_view.i b/bin/jni/data_view.i
index 2debc8309143fcc0e745c7b0a211d6f8f481ee27..4cbc91d87d7990142f98ec6d77941848f89346cc 100644
--- a/bin/jni/data_view.i
+++ b/bin/jni/data_view.i
@@ -8,6 +8,10 @@ struct DataView {
 struct Data {
     std::vector<uint8_t> data;
 };
+struct String {
+    std::string str;
+};
+
 }
 
 %}
@@ -15,6 +19,7 @@ struct Data {
 namespace jami {
 struct DataView;
 struct Data;
+struct String;
 
 %typemap(jni) DataView "jbyteArray"
 %typemap(jtype) DataView "byte[]"
@@ -24,7 +29,12 @@ struct Data;
 %typemap(jtype) Data "byte[]"
 %typemap(jstype) Data "byte[]"
 
+%typemap(jni) String "jbyteArray"
+%typemap(jtype) String "byte[]"
+%typemap(jstype) String "byte[]"
+
 %typemap(javadirectorin) Data "$jniinput"
+%typemap(javadirectorin) String "$jniinput"
 %typemap(javadirectorout) DataView "$javacall"
 
 %typemap(in) Data
@@ -36,6 +46,15 @@ struct Data;
     $1.data.resize(len);
     jenv->GetByteArrayRegion($input, 0, len, (jbyte*)$1.data.data()); %}
 
+%typemap(in) String
+%{ if(!$input) {
+     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+     return $null;
+    }
+    jsize len = jenv->GetArrayLength($input);
+    $1.str.resize(len);
+    jenv->GetByteArrayRegion($input, 0, len, (jbyte*)$1.str.data()); %}
+
 %typemap(out) DataView {
   jbyteArray r = jenv->NewByteArray($1.size);
   jenv->SetByteArrayRegion(r, 0, $1.size, (const jbyte *)$1.data);
@@ -43,6 +62,7 @@ struct Data;
 }
 
 %typemap(javain) Data "$javainput"
+%typemap(javain) String "$javainput"
 
 %typemap(javaout) DataView {
   return $jnicall;
diff --git a/bin/jni/jni_interface.i b/bin/jni/jni_interface.i
index 7d532408022a83b817ae4a663b029fea3f333ea6..f99ea63c573e1c1b886f99c6d6242c92df49f61d 100644
--- a/bin/jni/jni_interface.i
+++ b/bin/jni/jni_interface.i
@@ -126,6 +126,9 @@ namespace std {
       }
       return out;
   }
+  public void setUnicode(String key, String value) {
+    setRaw(key, Blob.bytesFromString(value));
+  }
 %}
 
 %extend map<string, string> {
@@ -137,11 +140,11 @@ namespace std {
         }
         return k;
     }
-    void setRaw(const std::string& key, const vector<uint8_t>& value) {
-        (*$self)[key] = std::string(value.data(), value.data()+value.size());
+    void setRaw(const std::string& key, jami::String value) {
+        (*$self)[key] = std::move(value.str);
     }
     jami::DataView getRaw(const std::string& key) {
-        auto& v = $self->at(key);
+        const auto& v = $self->at(key);
         return {(const uint8_t*)v.data(), v.size()};
     }
 }
@@ -151,8 +154,9 @@ namespace std {
 
 %typemap(javacode) vector< map<string,string> > %{
   public java.util.ArrayList<java.util.Map<String, String>> toNative() {
-    java.util.ArrayList<java.util.Map<String, String>> out = new java.util.ArrayList<>(size());
-    for (int i = 0; i < size(); ++i) {
+    int size = size();
+    java.util.ArrayList<java.util.Map<String, String>> out = new java.util.ArrayList<>(size);
+    for (int i = 0; i < size; ++i) {
         out.add(get(i).toNative());
     }
     return out;
@@ -164,15 +168,16 @@ namespace std {
 %template(UintVect) vector<uint32_t>;
 
 %typemap(javacode) vector<uint8_t> %{
-  public static Blob fromString(String in) {
-    byte[] dat;
+  public static byte[] bytesFromString(String in) {
     try {
-      dat = in.getBytes("UTF-8");
+      return in.getBytes("UTF-8");
     } catch (java.io.UnsupportedEncodingException e) {
-      dat = in.getBytes();
+      return in.getBytes();
     }
+  }
+  public static Blob fromString(String in) {
     Blob n = new Blob();
-    n.setBytes(dat);
+    n.setBytes(bytesFromString(in));
     return n;
   }
 %}