Senden und Empfangen von Bildern
Product deprecation notice
Effective April 30th, 2026, Vonage In-App Messaging will no longer be available. Access for new users will be closed, and the service will be discontinued for all existing users.
If you have any questions regarding this product’s discontinuation, please contact your account manager or our support team.
Übersicht
Diese Anleitung behandelt das Senden und Empfangen von Bildern innerhalb einer Konversation.
Bevor Sie beginnen, stellen Sie sicher, dass Sie das SDK zu Ihrer Anwendung hinzugefügt und Sie sind in der Lage ein Gespräch führen.
HINWEIS: Eine Schritt-für-Schritt-Anleitung zur Erstellung einer Chat-Anwendung ist verfügbar hier.
Dieser Leitfaden stützt sich auf die folgenden Concepts:
- Konversation Veranstaltungen -
messageEreignisse, die bei einer Konversation ausgelöst werden, nachdem Sie ein Mitglied sind
Ein Bild senden
Bei einer Unterhaltung, an der Sie bereits beteiligt sind:
// Scenario #1: Send an image from a URL
conversation.sendMessage({
"message_type": "image",
"image": {
"url": "https://example.com/image.jpg"
}
}).then((event) => {
console.log("message was sent", event);
}).catch((error)=>{
console.error("error sending the message", error);
});
// Scenario #2: Upload an image from a file input to Vonage, then send
// Note: the URL will need to be downloaded using the fetch image method mentioned in the next section.
const fileInput = document.getElementById('fileInput');
const params = {
quality_ratio : "90",
medium_size_ratio: "40",
thumbnail_size_ratio: "20"
}
conversation.uploadImage(fileInput.files[0], params).then((imageRequest) => {
imageRequest.onreadystatechange = () => {
if (imageRequest.readyState === 4 && imageRequest.status === 200) {
try {
const { original, medium, thumbnail } = JSON.parse(imageRequest.responseText);
const message = {
message_type: 'image',
image: {
url: original.url ?? medium.url ?? thumbnail.url
}
}
return conversation.sendMessage(message);
} catch (error) {
console.error("error sending the image", error);
}
}
if (imageRequest.status !== 200) {
console.error("error uploading the image");
}
};
return imageRequest;
}).catch((error) => {
console.error("error uploading the image ", error);
});
fun sendImage(file: File){
client.uploadAttachment(file, object : NexmoRequestListener<NexmoImage> {
override fun onSuccess(image: NexmoImage?) {
val message = image?.original?.let { NexmoMessage.fromImage(it.url) }
if (message != null) {
conversation?.sendMessage(message, object: NexmoRequestListener<Void?> {
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Error: failed to send message, ${apiError.message}")
}
override fun onSuccess(aVoid: Void?) {}
})
}
}
override fun onError(error: NexmoApiError) {
Log.d("TAG", "Error: Image not uploaded, ${error.message}")
}
})
}
public void sendImage(File file){
client.uploadAttachment(file, new NexmoRequestListener<NexmoImage>() {
@Override
public void onSuccess(@Nullable NexmoImage result) {
if (result != null){
NexmoMessage message = NexmoMessage.fromImage(result.getOriginal().getUrl());
conversation.sendMessage(message, new NexmoRequestListener<Void>() {
@Override
public void onError(@NonNull NexmoApiError error) {
Log.d("TAG", "Error: failed to send message, " + error.getMessage());
}
@Override
public void onSuccess(@Nullable Void result) {}
});
}
}
@Override
public void onError(@NonNull NexmoApiError error) {
Log.d("TAG", "Error: Image not uploaded, " + error.getMessage());
}
});
}
let image = UIImage(named: "file.png")
guard let imageData = image?.pngData() else { return }
client.uploadAttachment(with: .image, name: "File name", data: imageData) { error, data in
if let error = error {
print("Error sending image: \(error.localizedDescription)")
return
}
if let imageObject = data?["original"] as? [String: Any],
let imageUrl = imageObject["url"] as? String {
let imageMessage = NXMMessage(imageUrl: imageUrl)
conversation.sendMessage(imageMessage, completionHandler: { [weak self] (error) in
...
})
}
}
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"file.png"]);
[self.client uploadAttachmentWithType:NXMAttachmentTypeImage
name:@"File name 2"
data:imageData
completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable data) {
if (error == nil) {
NSLog(@"Error sending image");
}
NSString *imageUrl = [data valueForKeyPath:@"original.url"];
NXMMessage *imageMessage = [[NXMMessage alloc] initWithImageUrl:imageUrl];
[conversation sendMessage:message completionHandler:^(NSError * _Nullable error) {
...
}];
}];
Empfangen einer Bild-URL
A message Konversationsereignis wird empfangen, wenn ein Mitglied ein Bild an eine Konversation sendet:
conversation.on('message', (sender, event) => {
if (event.body.message_type === 'image'){
console.log('*** Image sender: ', sender);
console.log('*** Image event: ', event);
}
});
private val messageListener = object : NexmoMessageEventListener {
override fun onTypingEvent(typingEvent: NexmoTypingEvent) {}
override fun onMessageEvent(messageEvent: NexmoMessageEvent) {
val userName = messageEvent.embeddedInfo.user.name
val imageURL = messageEvent.message.imageUrl
Log.d("TAG", "Message received. User $userName : $imageURL")
}
override fun onAttachmentEvent(attachmentEvent: NexmoAttachmentEvent) {}
override fun onTextEvent(textEvent: NexmoTextEvent) {}
override fun onSeenReceipt(seenEvent: NexmoSeenEvent) {}
override fun onEventDeleted(deletedEvent: NexmoDeletedEvent) {}
override fun onDeliveredReceipt(deliveredEvent: NexmoDeliveredEvent) {}
}
conversation?.addMessageEventListener(messageListener)
private NexmoMessageEventListener messageListener = new NexmoMessageEventListener() {
@Override
public void onTextEvent(@NonNull NexmoTextEvent textEvent) {}
@Override
public void onMessageEvent(@NonNull NexmoMessageEvent messageEvent) {
String userName = messageEvent.getEmbeddedInfo().getUser().getName();
String imageURL = messageEvent.getMessage().getImageUrl();
Log.d("TAG", "Message received. User " + userName + " : " + imageURL);
}
@Override
public void onAttachmentEvent(@NonNull NexmoAttachmentEvent attachmentEvent) {}
@Override
public void onEventDeleted(@NonNull NexmoDeletedEvent deletedEvent) {}
@Override
public void onSeenReceipt(@NonNull NexmoSeenEvent seenEvent) {}
@Override
public void onDeliveredReceipt(@NonNull NexmoDeliveredEvent deliveredEvent) {}
@Override
public void onTypingEvent(@NonNull NexmoTypingEvent typingEvent) {}
};
conversation.addMessageEventListener(messageListener);
hinzufügen NXMConversationDelegate als Erweiterung zu einer ViewController oder ähnlich, und implementieren conversation(_ conversation: NXMConversation, didReceive event: NXMMessageEvent):
Hinweis: Die erste Methode unten ist erforderlich, wenn die NXMConversationDelegate:
extension ViewController: NXMConversationDelegate {
func conversation(_ conversation: NXMConversation, didReceive error: Error) {
NSLog("Conversation error: \(error.localizedDescription)")
}
func conversation(_ conversation: NXMConversation, didReceive event: NXMMessageEvent) {
NSLog("Received image: \(event.imageUrl)")
}
}
Haben Sie eine ViewControlleroder ähnlich, entsprechen NXMConversationDelegate und umsetzen conversation:didReceiveMessageEvent::
Hinweis: Die erste Methode unten ist erforderlich, wenn die NXMConversationDelegate:
- (void)conversation:(NXMConversation *)conversation didReceive:(NSError *)error {
NSLog(@"Conversation error: %@", error.localizedDescription);
}
- (void)conversation:(NXMConversation *)conversation didReceiveMessageEvent:(NXMMessageEvent *)event {
NSLog(@"Received image event: %@", event.imageUrl);
}
Bilder von Vonage herunterladen
Web-Client
Um ein Bild herunterzuladen, müssen Sie die Bild abrufen Methode.
Mobiler Client (Android, iOS)
Um ein Bild herunterzuladen, müssen Sie der Bildabrufanfrage einen JWT hinzufügen. Das JWT wird als Autorisierungs-Header übergeben (Authorization: Bearer <JWT> Format). Dies ist das JWT, das zur Anmeldung des Benutzers verwendet wurde.
Verschiedene Bildbibliotheken handhaben Anfrage-Header unterschiedlich, daher finden Sie unten ein vollständiges Beispiel für die gängigsten Bibliotheken. Beachten Sie, dass der JWT als Authorization Header für die Anfrage:
// ==== LOAD IMAGE USING COIL ====
// https://github.com/coil-kt/coil
private fun loadImageUsingCoil(url: String, jwt: String, context: Context) {
imageView.load(
Uri.parse(url),
context.imageLoader,
) {
addHeader("Authorization", "bearer $jwt")
}
}
// ==== LOAD IMAGE USING GLIDE ====
// https://github.com/bumptech/glide
private fun loadImageUsingGlide(url: String, jwt: String, context: Context) {
val build = LazyHeaders.Builder()
.addHeader("Authorization", "bearer $jwt")
.build()
val glideUrl = GlideUrl(url, build)
Glide.with(context)
.load(glideUrl)
.into(imageView)
}
// ==== LOAD IMAGE USING PICASSO ====
// https://github.com/square/picasso
// Define custom Authentication interceptor
class AuthenticationInterceptor(private val jwt: String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response = chain.request().let {
val newRequest = it.newBuilder()
.header("Authorization", "bearer $jwt")
.build()
chain.proceed(newRequest)
}
}
// Create Picasso instance that uses the Authenticator
private fun getPicassoInstance(jwt: String): Picasso {
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(AuthenticationInterceptor(jwt))
.build()
return Picasso.Builder(requireContext()).downloader(OkHttp3Downloader(okHttpClient)).build()
}
// Load image using custom picasso instance (that under the hood uses the authentication interceptor)
private fun loadImageUsingPicasso(url: String, jwt: String, context: Context) {
getPicassoInstance(jwt)
.load(url)
.into(imageView)
}
// ==== LOAD IMAGE USING GLIDE ====
// https://github.com/bumptech/glide
private void loadImageUsingGlide(String url, String jwt, Context context) {
LazyHeaders build = new LazyHeaders.Builder()
.addHeader("Authorization", "bearer " + jwt)
.build();
GlideUrl glideUrl = new GlideUrl(url, build);
Glide.with(context)
.load(glideUrl)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
}
// ==== LOAD IMAGE USING PICASSO ====
// https://github.com/square/picasso
// Define custom Authentication interceptor
class AuthenticationInterceptor implements Interceptor {
private String jwt;
public AuthenticationInterceptor(String jwt) {
this.jwt = jwt;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request request = chain.request();
Request newRequest = request.newBuilder()
.header("Authorization", "bearer " + jwt)
.build();
return chain.proceed(newRequest);
}
}
// Create Picasso instance that uses the Authenticator
private Picasso getPicassoInstance(String jwt) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new AuthenticationInterceptor(jwt))
.build();
return new Picasso.Builder(requireContext())
.downloader(new OkHttp3Downloader(okHttpClient))
.build();
}
// Load image using custom picasso instance (that under the hood uses the authentication interceptor)
private void loadImageUsingPicasso(String url, String jwt, Context context) {
getPicassoInstance(jwt)
.load(url)
.into(imageView);
}
Sie können das Bild herunterladen mit URLSession:
func loadImage(urlString: String, token: String, completionHandler: @escaping (UIImage?) -> Void) {
if let url = URL(string: urlString) {
var request = URLRequest(url: url)
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode),
error == nil else {
completionHandler(nil)
return
}
completionHandler(UIImage(data: data))
}
task.resume()
}
}
Wenn Sie die obige Funktion aufrufen, stellen Sie sicher, dass Sie Ihre UIImageView auf dem Hauptthread:
loadImage(urlString: "IMAGE_URL", token: "JWT") { image in
if let image = image {
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
Sie können das Bild herunterladen mit URLSession:
- (void)loadImageWithURLString:(NSString *)urlString
token:(NSString *)token
completionHandler:(void (^_Nonnull)(UIImage * _Nullable image))completionHandler {
NSURL *url = [[NSURL alloc] initWithString:urlString];
if (url) {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setValue:[NSString stringWithFormat:@"Bearer %@", token] forHTTPHeaderField:@"Authorization"];
NSURLSessionTask *task = [NSURLSession.sharedSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error && data && response) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if (httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299) {
completionHandler([[UIImage alloc] initWithData:data]);
}
}
completionHandler(nil);
}];
[task resume];
}
}
Wenn Sie die obige Funktion aufrufen, stellen Sie sicher, dass Sie Ihre UIImageView auf dem Hauptthread:
[self loadImageWithURLString:@"IMAGE_URL" token:@"JWT" completionHandler:^(UIImage * _Nullable image) {
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.imageView setImage:image];
});
}
}];