Skip to content

Commit 25492e6

Browse files
nicklockwoodTj
authored and
Tj
committed
Added logic to detect text encoding for downloaded data
Summary: @​public RCTNetworking currently relies on network responses to include an accurate text encoding, otherwise it is unable to convert the response data to text unless it's encoded as UTF8. See: facebook#1780 (comment) for details. This diff makes use of a new feature in iOS8 to detect the encoding of the text authomatically Reviewed By: @sahrens Differential Revision: D2443446
1 parent e5b5a43 commit 25492e6

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

Examples/UIExplorer/XHRExample.ios.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,53 @@ class FormUploader extends React.Component {
302302
}
303303
}
304304

305+
class FetchTest extends React.Component {
306+
307+
constructor(props) {
308+
super(props);
309+
this.state = {
310+
responseText: null,
311+
};
312+
}
313+
314+
submit(uri: String) {
315+
fetch(uri).then((response) => {
316+
return response.text();
317+
}).then((body) => {
318+
this.setState({responseText: body});
319+
});
320+
}
321+
322+
render() {
323+
324+
var response = this.state.responseText ? (
325+
<View style={{marginTop: 10}}>
326+
<Text style={styles.label}>Server response:</Text>
327+
<TextInput
328+
editable={false}
329+
multiline={true}
330+
defaultValue={this.state.responseText}
331+
style={styles.textOutput}
332+
/>
333+
</View>
334+
) : null;
335+
336+
return (
337+
<View>
338+
<Text style={styles.label}>Edit URL to submit:</Text>
339+
<TextInput
340+
returnKeyType="go"
341+
defaultValue="http://www.posttestserver.com/post.php"
342+
onSubmitEditing={(event)=> {
343+
this.submit(event.nativeEvent.text);
344+
}}
345+
style={styles.textInput}
346+
/>
347+
{response}
348+
</View>
349+
);
350+
}
351+
}
305352

306353
exports.framework = 'React';
307354
exports.title = 'XMLHttpRequest';
@@ -316,6 +363,11 @@ exports.examples = [{
316363
render() {
317364
return <FormUploader/>;
318365
}
366+
}, {
367+
title: 'fetch test',
368+
render() {
369+
return <FetchTest/>;
370+
}
319371
}];
320372

321373
var styles = StyleSheet.create({
@@ -373,4 +425,19 @@ var styles = StyleSheet.create({
373425
fontSize: 16,
374426
fontWeight: '500',
375427
},
428+
label: {
429+
flex: 1,
430+
color: '#aaa',
431+
fontWeight: '500',
432+
height: 20,
433+
},
434+
textOutput: {
435+
flex: 1,
436+
fontSize: 17,
437+
borderRadius: 3,
438+
borderColor: 'grey',
439+
borderWidth: 1,
440+
height: 200,
441+
paddingLeft: 8,
442+
},
376443
});

Libraries/Network/RCTNetworking.m

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,27 @@ - (void)sendData:(NSData *)data forTask:(RCTDownloadTask *)task
271271
encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
272272
}
273273

274+
// Attempt to decode text
274275
NSString *responseText = [[NSString alloc] initWithData:data encoding:encoding];
275276
if (!responseText && data.length) {
276-
RCTLogWarn(@"Received data was invalid.");
277-
return;
277+
278+
// We don't have an encoding, or the encoding is incorrect, so now we
279+
// try to guess (unfortunately, this feature is available of iOS 8+ only)
280+
if ([NSString respondsToSelector:@selector(stringEncodingForData:
281+
encodingOptions:
282+
convertedString:
283+
usedLossyConversion:)]) {
284+
[NSString stringEncodingForData:data
285+
encodingOptions:nil
286+
convertedString:&responseText
287+
usedLossyConversion:NULL];
288+
}
289+
290+
// If we still can't decode it, bail out
291+
if (!responseText) {
292+
RCTLogWarn(@"Received data was not a string, or was not a recognised encoding.");
293+
return;
294+
}
278295
}
279296

280297
NSArray *responseJSON = @[task.requestID, responseText ?: @""];

0 commit comments

Comments
 (0)