暫無描述

index.js 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * @author wkh237
  3. * @version 0.4.2
  4. */
  5. import {
  6. NativeModules,
  7. DeviceEventEmitter,
  8. NativeAppEventEmitter,
  9. Platform,
  10. } from 'react-native'
  11. import base64 from 'base-64'
  12. const emitter = (Platform.OS === 'android' ? DeviceEventEmitter : NativeAppEventEmitter)
  13. const RNFetchBlob = NativeModules.RNFetchBlob
  14. // Show warning if native module not detected
  15. if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
  16. console.warn(
  17. 'react-native-fetch-blob could not find valid native module.',
  18. 'please make sure you have linked native modules using `rnpm link`,',
  19. 'and restart RN packager or manually compile IOS/Android project.'
  20. )
  21. }
  22. const config = function(options) {
  23. return { fetch : fetch.bind(options) }
  24. }
  25. // Promise wrapper function
  26. const fetch = function(...args) {
  27. let options = this || {}
  28. // create task ID for receiving progress event
  29. let taskId = getUUID()
  30. let promise = new Promise((resolve, reject) => {
  31. let [method, url, headers, body] = [...args]
  32. let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
  33. // on progress event listener
  34. let subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
  35. if(e.taskId === taskId && promise.onProgress) {
  36. promise.onProgress(e.written, e.total)
  37. }
  38. })
  39. let req = RNFetchBlob[nativeMethodName]
  40. req(taskId, method, url, headers || {}, body, (err, ...data) => {
  41. // task done, remove event listener
  42. subscription.remove()
  43. if(err)
  44. reject(new Error(err, ...data))
  45. else
  46. resolve(new FetchBlobResponse(...data))
  47. })
  48. })
  49. promise.progress = (fn) => {
  50. promise.onProgress = fn
  51. return promise
  52. }
  53. return promise
  54. }
  55. /**
  56. * RNFetchBlob response object class.
  57. */
  58. class FetchBlobResponse {
  59. constructor(data) {
  60. this.data = data
  61. /**
  62. * Convert result to javascript Blob object.
  63. * @param {string} contentType MIME type of the blob object.
  64. * @param {number} sliceSize Slice size.
  65. * @return {blob} Return Blob object.
  66. */
  67. this.blob = (contentType, sliceSize) => {
  68. console.warn('FetchBlobResponse.blob() is deprecated and has no funtionality.')
  69. return null
  70. }
  71. /**
  72. * Convert result to text.
  73. * @return {string} Decoded base64 string.
  74. */
  75. this.text = () => {
  76. return base64.decode(this.data)
  77. }
  78. /**
  79. * Convert result to JSON object.
  80. * @return {object} Parsed javascript object.
  81. */
  82. this.json = () => {
  83. return JSON.parse(base64.decode(this.data))
  84. }
  85. /**
  86. * Return BASE64 string directly.
  87. * @return {string} BASE64 string of response body.
  88. */
  89. this.base64 = () => {
  90. return this.data
  91. }
  92. }
  93. }
  94. function getUUID(){
  95. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  96. let r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  97. return v.toString(16);
  98. });
  99. }
  100. export default {
  101. fetch, FetchBlobResponse, base64
  102. }