React native-отправка фото на почту
Я пытаюсь отправить недавно в app - captured фото по почте и сталкиваюсь со следующей ошибкой:
(для функциональности рассылки я использую этот модуль:var Mailer = require('NativeModules').RNMail;
Я пытаюсь отправить фотографию по почте с помощью этого модуля и получить следующую ошибку:
index.ios.bundle:28842Exception '-[MFMailComposeInternalViewController addAttachmentData:mimeType:fileName:] attachment must not be nil.' was thrown while invoking mail on target RNMail with params (
{
attachment = {
name = Ladunek;
path = "assets-library://asset/asset.JPG?id=3B7DBB2E-1271-4D86-A5F2-A0CEEE7CC4DE&ext=JPG";
type = jpg;
};
body = "body";
isHTML = 1;
recipients = (
"placeholder@mail.com"
);
subject = Ladunek;
},
9
)
это код вызова:
.then((data, path) => {
console.log(data)
console.log(data.path)
Mailer.mail({
subject: 'Ladunek',
recipients: ['placeholder@mail.com'],
body: 'body',
isHTML: true, // iOS only, exclude if false
attachment: {
path: data.path, // The absolute path of the file from which to read data.
type: 'jpg', // Mime Type: jpg, png, doc, ppt, html, pdf
name: 'Ladunek', // Optional: Custom filename for attachment
}
}, (error, event) => {
if(error) {
AlertIOS.alert('Error', 'Could not send mail. Please send a mail to support@example.com');
}
});
})
- это неверный путь? Или это может быть что-то еще.
редактировать
Я получаю путь к файлу с помощью этого модуля react-native-camera
вот так:
событие:
takePicture() {
this.camera.capture()
.then((data, path) =>
элемент:
<Camera
ref={(cam) => {
this.camera = cam;
}}
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
height: 400,
width: Dimensions.get('window').width
}}
aspect={Camera.constants.Aspect.fill}>
<Text style={{
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
color: '#000',
padding: 10,
margin: 40
}} onPress={this.takePicture.bind(this)}>{cameraIcon}</Text>
</Camera>
обновление 2
после, в том числе файл obj-c для преобразования uri в путь я получаю следующую ошибку:
ExceptionsManager.js:76 JSON value '<null>' of type NSNull cannot be converted to NSString
Я "удалил" неправильные строки из следующего кода? :/
файл Obj-c содержание:
#import "RCTBridgeModule.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <UIKit/UIKit.h>
@interface ReadImageData : NSObject <RCTBridgeModule>
@end
@implementation ReadImageData
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(readImage:(NSString *)input callback:(RCTResponseSenderBlock)callback)
{
// Create NSURL from uri
NSURL *url = [[NSURL alloc] initWithString:input];
// Create an ALAssetsLibrary instance. This provides access to the
// videos and photos that are under the control of the Photos application.
//ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Using the ALAssetsLibrary instance and our NSURL object open the image.
//[library assetForURL:url resultBlock:^(ALAsset *asset) {
// Create an ALAssetRepresentation object using our asset
// and turn it into a bitmap using the CGImageRef opaque type.
//CGImageRef imageRef = [asset thumbnail];
// Create UIImageJPEGRepresentation from CGImageRef
// NSData *imageData = UIImageJPEGRepresentation([UIImage imageWithCGImage:imageRef], 0.1);
// Convert to base64 encoded string
// NSString *base64Encoded = [imageData base64EncodedStringWithOptions:0];
callback(@[url]);
//} failureBlock:^(NSError *error) {
//NSLog(@"that didn't work %@", error);
//}];
}
@end
1 ответов
------ ОТРЕДАКТИРОВАННЫЙ ОТВЕТ НИЖЕ ------
Хорошо, Итак, у меня наконец-то есть Mac и я смог изучить эту проблему более подробно.
это то, что я нашел для Android и iOS.
предполагается, что вы используете реагировать родной камеры вместе с react-native-mail
- 1: Абсолютный Путь
добавить свойство captureTarget={Camera.constants.CaptureTarget.disk}
to Camera
компонент, как Итак:
<Camera
captureTarget={Camera.constants.CaptureTarget.disk}
ref={(cam) => {
this.camera = cam;
}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>
теперь компонент камеры должен возвратить абсолютное путь к файлу вместо uri.
и Android вы должны увидеть нечто вроде этого:
"file:///storage/emulated/0 / Pictures / RCTCameraModule / IMG_20160730_060652.формат JPG"
вместо:
"содержание: / / медиа / внешний/изображения / медиа / 86"
и iOS вы должны сделать что-то вроде этого:
"/Users/anton/Library/Developer/CoreSimulator/Devices/9A15F203-9A58-41C5-A4FC-EA25FAAE92BD/data/Containers/Data/Application/79FF93F9-BA89-4F4C-8809-277BEECD447D/Documents/EFFF0ECE-4063-4FE5-984E-E76506788350.формат JPG"
вместо:
"assets-library: / / актив / актив.В JPG?id=0058FA4A-268F-408A-9150-017A3DA368D2 & ext=JPG"
- 2: подводные камни
iOS:
если сбой MFMailComposeViewController от Apple, и вы видите следующее сообщение об ошибке:
Это скорее всего потому, что вы используете приложение на iOS 9 симулятор. Решение: либо протестируйте приложение на реальном устройстве или загрузите старый симулятор, такой как iOS 8.4.
более подробную информацию по этому вопросу можно найти здесь
Android:
на момент написания этой статьи нет крепления для Android.
устранение: (PR был сделан, чтобы добавить эту функцию, но если вы не можете ждать)
добавить следующий код в файл RNMAILModule.java
if (options.hasKey("attachment") && !options.isNull("attachment")) {
i.putExtra(Intent.EXTRA_STREAM, Uri.parse(options.getMap("attachment").getString("path")));
}
когда как Android, так и iOS работают, у вас должно быть что-то вроде этого:
и вот рабочий код:
var Mailer = require('NativeModules').RNMail;
import Camera from 'react-native-camera';
import React, {Component} from 'react';
import
{
View,
TouchableHighlight,
Text,
StyleSheet,
Dimensions,
CameraRoll
}
from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
height: Dimensions.get('window').height,
width: Dimensions.get('window').width
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
color: '#000',
padding: 10,
margin: 40
}
});
class SendPhoto extends Component {
takePicture() {
this.camera.capture()
.then((data) => {
console.log(data.path)
Mailer.mail({
subject: 'Ladunek',
recipients: ['placeholder@mail.com'],
body: 'body',
isHTML: true, // iOS only, exclude if false
attachment: {
path: data.path, // The absolute path of the file from which to read data.
type: 'jpg', // Mime Type: jpg, png, doc, ppt, html, pdf
name: 'Ladunek', // Optional: Custom filename for attachment
}
}, (error, event) => {
if(error) {
AlertIOS.alert('Error', 'Could not send mail. Please send a mail to support@example.com');
}
})
})
.catch(err => console.error(err));
}
render() {
return(
<View>
<View style={styles.container}>
<Camera
captureTarget={Camera.constants.CaptureTarget.disk}
ref={(cam) => {
this.camera = cam;
}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>
</View>
</View>
);
}
}
export default SendPhoto;
------ СТАРЫЙ ОТВЕТ НИЖЕ ------
Я никогда не использовал этот модуль раньше, но похоже, что он ожидает абсолютный путь к файлу, однако вы предоставляете файл uri.
как вы получаете этот файл uri?
попробуйте использовать react-native-get-real-path модуль, чтобы увидеть, если это поможет, вы можете найти его здесь:react-native-get-real-path
т. е. преобразуйте uri файла для получения реального пути и используйте его как путь