XHMM / react-native-cloud-store

A react-native module for icloud drive
https://react-native-cloud-store.vercel.app/docs/install/with-crna
MIT License
68 stars 11 forks source link

Query callbacks, events, etc don't work #5

Closed heyalexchoi closed 2 years ago

heyalexchoi commented 2 years ago

I have noticed that the callbacks and event callbacks for methods like persist do not work.

In debugging, I've noticed that the NSMetadataQuery in initAndStartQuery does not return results, and so the notification observers and callbacks do not behave as expected. It looks like the query is started and quickly finished without matching files.

XHMM commented 2 years ago

I tried persist and upload on my device, both works and events are triggered, could you provide some code for me to debug?

XHMM commented 2 years ago

Sorry I found that document for persist was wrong, I have updated doc and published a new release 0.6.1 with a bug fix, please have a try it

heyalexchoi commented 2 years ago

I switched the calls to persist to use a full path with a localized name, eg:

'/private/var/mobile/Library/Mobile Documents/iCloudContainer/Documents/device-x/captions/captions-883cc579-24c3-49a1-85b7-dc69257189f1.json'

instead of

'/private/var/mobile/Library/Mobile Documents/iCloudContainer/Documents/device-x/captions/.captions-883cc579-24c3-49a1-85b7-dc69257189f1.json.icloud'

but still am not seeing any onICloudDocuments___Gathering events.

Also, not sure if this library is supposed to do this, but what I really want is to know when the persist finishes to then copy/move the file. And the callback returns before the file is finished saving locally.

Basically, I'm doing:

// icloud.js

import {
  isICloudAvailable,
  writeFile,
  readFile,
  readDir,
  exist,
  copy,
  iCloudContainerPath,
  persist,
  createDir,
  stat,
  unlink,
  onICloudDocumentsStartGathering,
  onICloudDocumentsGathering,
  onICloudDocumentsFinishGathering,
  onICloudDocumentsUpdateGathering,
} from 'react-native-cloud-store'

const persistICloudFileIfNeeded = async (iCloudPath) => {
  const statResult = await stat(iCloudPath)
  console.log('statResult: ', statResult)

  const RNFSStatResult = await RNFS.stat(iCloudPath)
  console.log('RNFS stat result: ', RNFSStatResult)

  // this needs to call path with localized name

  if (statResult.downloadStatus == 'NSURLUbiquitousItemDownloadingStatusNotDownloaded') {

    console.log(`persistICloudFileIfNeeded PERSISTING. NOT DOWNLOADED ${iCloudPath}`)
    const path = await pathWithoutFilename(iCloudPath)
    const localizedPath = `${path}/${statResult.localizedName}`
    // localized is the "proper name" of the file without '.' prefix or '.icloud' suffix
    // need to call persist on this name for callbacks and event listeners to work properly

    console.log(`persistICloudFileIfNeeded LOCALIZED PATH ${localizedPath}`)
    return await persist(localizedPath)
            .then(result => console.log('persist result: ', result))
            .catch(error => console.error('persist error: ', error))

  }

  console.log('persistICloudFileIfNeeded file downloaded or current. skipping persist')
}

export const persistFiles = async () => {

  const persistPromises = readDirResult.map(path => persistICloudFileIfNeeded(path))
  const persistSettled = await Promise.allSettled(persistPromises)
  console.log('persist results: ', persistSettled.map(promise => promise.value))

  // after persist see if files are downloaded
  // answer question - does persist wait for completion

  const readDirResult2 = await readDir(await getCaptionsBackupDirectory())
  console.log('after persist captions directory: ', readDirResult)
  // these still show the .filename.icloud files

  const statPromises = readDirResult.map(path => stat(path))
  const statSettled = await Promise.allSettled(statPromises)
  const statResults = statSettled.map(promise => promise.value)
  console.log('after persist statResult: ', statResults)
  // these show files still downloading after persist resolves

 // [{ 
 //   isDownloading: true,
 //    isUploading: false,
 //    isUploaded: true,
 //    isInICloud: true,
 //    createTimestamp: 1662764308000,
 //    localizedName: 'captions-97dc2d89-3b99-4248-bcda-f68304956e8c.json',
 //    hasUnresolvedConflicts: false,
 //    downloadStatus: 'NSURLUbiquitousItemDownloadingStatusNotDownloaded',
 //    containerDisplayName: 'Innocaption Staging',
 //    hasCalledDownload: true,
 //    modifyTimestamp: 1662764308000,
 //    name: '.captions-97dc2d89-3b99-4248-bcda-f68304956e8c.json.icloud' 
 //  }]

}

// setup listeners at the module level for now
onICloudDocumentsStartGathering((data) => {
  console.log('onICloudDocumentsStartGathering data: ', data)
})
onICloudDocumentsGathering((data) => {
  console.log('onICloudDocumentsGathering data: ', data)
})
onICloudDocumentsFinishGathering((data) => {
  console.log('onICloudDocumentsFinishGathering data: ', data)
})
onICloudDocumentsUpdateGathering((data) => {
  console.log('onICloudDocumentsUpdateGathering data: ', data)
})

Not seeing any logs from js.

I am seeing some logs in XCode:

["[gather results]:\n"]
["[download-info]:\n", "url  file:///private/var/mobile/Library/Mobile%20Documents/x/Documents/x/captions/captions-97dc2d89-3b99-4248-bcda-f68304956e8c.json\nisDownloading  nil\nstatus  nil\nprogress  Optional(0.0)\n"]
["[start results]:\n"]
2022-09-17 16:39:48.024818-0400 InnocaptionMobile[32585:1742843] [javascript] 'persist result: ', undefined
["[finish results]:\n"]
["[download-info]:\n", "url  file:///private/var/mobile/Library/Mobile%20Documents/x/Documents/x/captions/captions-97dc2d89-3b99-4248-bcda-f68304956e8c.json\nisDownloading  nil\nstatus  nil\nprogress  Optional(0.0)\n"]
["[gather results]:\n"]
["persist query stopped"]
["[update results]:\n"]
["[download-info]:\n", "url  file:///private/var/mobile/Library/Mobile%20Documents/Container/Documents/device-x/captions/captions-..8402afa7-e588-48bd-9674-1ed2a20eec9f.icloud.icloud.json\nisDownloading  Optional(false)\nstatus  Optional(__C.NSURLUbiquitousItemDownloadingStatus(_rawValue: NSURLUbiquitousItemDownloadingStatusCurrent))\nprogress  Optional(100.0)\n"]
heyalexchoi commented 2 years ago

update:

In Swift, I see that hasListeners is true and that the code reaches the parts where the events should be sent. I do not see the events reaching the js side, even within the react-native-cloud-store module.

heyalexchoi commented 2 years ago

Never got the events to work, but changed the way the callbacks work which is better for me, and was easier to do.

Personally, this is how I assumed these functions would work already so I think it makes sense for them to do this. Curious to hear your thoughts.

https://github.com/XHMM/react-native-cloud-store/pull/6

XHMM commented 2 years ago

I see xcode has logged event info, and you said in swift code reaches the parts where the events should be sent, so js side should call events as expected, did you setup your event listeners after calling persist? listeners should be set before calling persist/upload.

If you set your listeners correctly, but event still not triggered, you can try with the example project to check if something not correct, or you can also provide an demo repo for me.

XHMM commented 2 years ago

Never got the events to work, but changed the way the callbacks work which is better for me, and was easier to do.

Personally, this is how I assumed these functions would work already so I think it makes sense for them to do this. Curious to hear your thoughts.

6

Thanks for your suggestion, current persist and upload api designs were not so convenient and easy-to-use to track progress and finish event , it need to be changed in future to like this:

upload(filePath, {
  onProgress(event) { setProgress(event.progress) }
})
.then(finishFn)
.catch(errFn)
heyalexchoi commented 2 years ago

Looks compatible with changes in my PR. You could add the second param for the onProgress handler in the future.

XHMM commented 2 years ago

yes, I will refactor this soon

XHMM commented 2 years ago

Hi, you can reopen if you still has problem

heyalexchoi commented 2 years ago

Are you interested in this PR? https://github.com/XHMM/react-native-cloud-store/pull/6

XHMM commented 2 years ago

yes and I will process this PR when working with onProgress, it may wait for a while but not too long