Further re-work of document saving in the iOS app

Now, finally, I think it works as it should, knock on wood. After an
auto-save (or explicit save by tapping the button), the edited
document does show up with its auto-saved contents if you open it from
iCloud Drive or Nextcloud while it is still open in the iOS app.

What I was missing was that the document hadn't actually been saved by
the core (to the temporary copy) until we get the
LOK_CALLBACK_UNO_COMMAND_RESULT for the .uno:Save. We must call the
-[UIDocumentsaveToURL:forSaveOperation:completionHandler:] only upon
receiving that callback.

Change-Id: I10486f3bc587c871ee2644a0c097493f33baf420
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91880
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
This commit is contained in:
Tor Lillqvist 2020-04-08 12:37:46 +03:00
parent bdef8193b8
commit 5270284701
2 changed files with 29 additions and 15 deletions

View file

@ -32,6 +32,10 @@
#include <Poco/Net/AcceptCertificateHandler.h> #include <Poco/Net/AcceptCertificateHandler.h>
#endif #endif
#ifdef IOS
#import "DocumentViewController.h"
#endif
#include <common/FileUtil.hpp> #include <common/FileUtil.hpp>
#include <common/JsonUtil.hpp> #include <common/JsonUtil.hpp>
#include <common/Authorization.hpp> #include <common/Authorization.hpp>
@ -2475,6 +2479,31 @@ void ChildSession::loKitCallback(const int type, const std::string& payload)
break; break;
case LOK_CALLBACK_UNO_COMMAND_RESULT: case LOK_CALLBACK_UNO_COMMAND_RESULT:
sendTextFrame("unocommandresult: " + payload); sendTextFrame("unocommandresult: " + payload);
#ifdef IOS
{
// After the document has been saved (into the temporary copy that we set up in
// -[CODocument loadFromContents:ofType:error:]), save it also using the system API so
// that file provider extensions notice.
Parser parser;
Poco::Dynamic::Var var = parser.parse(payload);
Object::Ptr object = var.extract<Object::Ptr>();
auto commandName = object->get("commandName");
auto success = object->get("success");
if (!commandName.isEmpty() && commandName.toString() == ".uno:Save" && !success.isEmpty() && success.toString() == "true")
{
CODocument *document = [[DocumentViewController singleton] document];
[document saveToURL:[document fileURL]
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success) {
LOG_TRC("ChildSession::loKitCallback() save completion handler gets " << (success?"YES":"NO"));
}];
}
}
#endif
break; break;
case LOK_CALLBACK_ERROR: case LOK_CALLBACK_ERROR:
{ {

View file

@ -39,10 +39,6 @@
#include <common/Unit.hpp> #include <common/Unit.hpp>
#include <common/FileUtil.hpp> #include <common/FileUtil.hpp>
#ifdef IOS
#import "DocumentViewController.h"
#endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -1288,17 +1284,6 @@ bool DocumentBroker::sendUnoSave(const std::string& sessionId, bool dontTerminat
const auto command = "uno .uno:Save " + saveArgs; const auto command = "uno .uno:Save " + saveArgs;
forwardToChild(sessionId, command); forwardToChild(sessionId, command);
_lastSaveRequestTime = std::chrono::steady_clock::now(); _lastSaveRequestTime = std::chrono::steady_clock::now();
#ifdef IOS
// We need to do this here, also for auto-save, so that file provider extensions notice.
CODocument *document = [[DocumentViewController singleton] document];
[document saveToURL:[[[DocumentViewController singleton] document] fileURL]
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success) {
LOG_TRC("DocumentBroker::sendUnoSave() save completion handler gets " << (success?"YES":"NO"));
}];
#endif
return true; return true;
} }