WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.74' for table 'wp_options']INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1714399455.1246991157531738281250', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)
As you can read on MSDN<\/a>, there is in fact a lot of contracts available for a Windows 8 app. <\/p>\n Today, I want to describe one which is very useful for the Dropbox client I work on (8 Files In A Box)<\/a> : The Cached File Updater contract. <\/strong><\/p>\n As you will see, it can be really useful with the FileSavePicker contract.<\/p>\n <\/p>\n First of all : The Cached File Updater contracts simply declare that your app is responsible for the management of one or many of its files.<\/strong> This is really useful for ‘file management apps’.<\/p>\n You can usethe “CachedFileUpdater” to do some really interesting things :<\/p>\n I refer to “a file” but this can be done on any file of your app.<\/p>\n Using this contract is done in 4 steps, one being optional.<\/strong><\/p>\n The first thing, as for any contracts is to declare the contract in the app manifest. Simply add it : When you create a file in your app, you can define some triggers on it using the CachedFileUpdater.SetUpdateInformation<\/em> method.<\/strong> This is a simple call and it takes 5 arguments :<\/p>\n Here is an example which ask your app to be activated after an another app writes on your file :<\/strong> Once this is done, you can override the OnCachedFileUpdaterActivated method of your application. The provided arg will give you a propertie “CachedFileUpdaterUI” with some interesting information :<\/p>\n When you don’t have to show any UI to the user, you’ll simply have to grab the file when the FileUpdateRequested event is raised and do something with the file. If the local file have to be updated, you can call the UpdateLocalFile method and provide an up to date file. <\/p>\n Also, you have to set the “args.Request.Status” depending of the success of the operation (in our case to FileUpdateStatus.Complete). \/\/do not forget this void OnCachedFileUpdaterUIFileUpdateRequested(CachedFileUpdaterUI sender, var theContentId = args.Request.ContentId; \/\/Do something to the file<\/p>\n \/\/If the local file have to be updated, call do this : \t args.Request.Status=FileUpdateStatus.Complete <\/p>\n If the update process needs it, you can ask the user for some input. <\/p>\n To do so, you have to tell it in the FileUpdateRequested event handler using the args.Request.Status and set it to FileUpdateStatus.UserInputNeeded<\/strong>. \/\/Can set a custom title return; The UIRequested event is then raised and you have to set the content of the Window to your specific UI in the handler<\/strong>. Don’t forget to do it in the right thread.Don’t forget to do it in the right thread : create the page in the first activation event and use the page Dispatcher to set the content.<\/p>\n [csharp] The FileUpdateRequested event will then be raised once more to inform you that the UI is visible.<\/strong> In the handler, you have to grab the event args and pass it to your UI. The UI will then be responsible to set the Request Status to the correct value. In my case, I save the args as a static field of my application. FileUpdateRequestedEventArgs = args;<\/p>\n var deferral = args.Request.GetDeferral(); \/\/Can set a custom title for the UI if (sender.UIStatus == UIStatus.Unavailable) if (sender.UIStatus == UIStatus.Visible) [\/csharp]<\/p>\n In my UI, I simply set the status and complete the deferral when the user click on a button: <\/a><\/p>\n In 8 Files In A Box, the Dropbox client for Windows 8,<\/a> we wanted to be able to save a file and to upload it directly to the user Dropbox. <\/strong><\/p>\n I first thought it was not possible :<\/strong> as soon as the file save picker provide a file to the requesting app, my app is shut down by Windows 8 and I have :<\/p>\n Leonard<\/a> one of my Infinite Square<\/a> colleague demonstrated me that I was wrong (and that impossible is really not a French word:)).<\/p>\n It can in fact be done using the Cached File Updater contract :<\/strong><\/p>\n Really simple in fact \ud83d\ude42 For those who best understand code (as me :)) here a code snippet : args.FileSavePickerUI.TargetFileRequested async void FileSavePickerUI_TargetFileRequested( CachedFileUpdater.SetUpdateInformation(fileCreated, args.Request.TargetFile = fileCreated;<\/p>\n }<\/p>\n [\/csharp]<\/p>\n <\/p>\n At first, I did not manage to make it works : the OnCachedFileUpdaterActivated method was called but the OnCachedFileUpdaterUIFileUpdateRequested event was never raised. <\/p>\n
\nThe code of this blog post is available here<\/a>.<\/p>\nWhat is it ?<\/h2>\n
\n
How to use it ?<\/h2>\n
1)Declare the contract in the manifest.<\/h5>\n
\n<\/a><\/p>\n2)Define some triggers on your file.<\/h5>\n
\n
\n[csharp]CachedFileUpdater.SetUpdateInformation(fileCreated,
\n "A content id to identify the file.",
\n ReadActivationMode.NotNeeded,
\n WriteActivationMode.AfterWrite,
\n CachedFileOptions.None);
\n[\/csharp]<\/p>\n3)Override the OnCachedFileUpdaterActivated method of the Application.<\/h5>\n
\n
\nHere is an example :
\n[csharp]
\n protected override void
\n OnCachedFileUpdaterActivated(CachedFileUpdaterActivatedEventArgs args)
\n {
\n args.CachedFileUpdaterUI.FileUpdateRequested
\n += OnCachedFileUpdaterUIFileUpdateRequested;
\n base.OnCachedFileUpdaterActivated(args);<\/p>\n
\n Window.Current.Activate();
\n }<\/p>\n
\n FileUpdateRequestedEventArgs args)
\n {
\n var deferral = args.Request.GetDeferral();<\/p>\n
\n var theTargetFile = args.Request.File;<\/p>\n
\n \/\/StorageFile upToDateFile=null;
\n \/\/fill upToDateFile with the correct data
\n \/\/args.Request.UpdateLocalFile(upToDateFile);<\/p>\n
\n deferral.Complete();
\n}
\n[\/csharp]<\/p>\n4) Ask the user for some input (optional).<\/h5>\n
\n[csharp]
\nif (sender.UIStatus == UIStatus.Hidden)
\n{
\n args.Request.Status = FileUpdateStatus.UserInputNeeded;<\/p>\n
\n sender.Title = "Requiring input for : " + args.Request.ContentId;<\/p>\n
\n}
\n[\/csharp]<\/p>\n
\nvoid CachedFileUpdaterUI_UIRequested(CachedFileUpdaterUI sender, object args)
\n{
\n _specificUIPage.Dispatcher.RunAsync(
\n CoreDispatcherPriority.Normal,
\n () => { Window.Current.Content = _specificUIPage; });
\n}
\n[\/csharp]<\/p>\n
\n[csharp]
\npublic static FileUpdateRequestedEventArgs FileUpdateRequestedEventAr
\nvoid OnCachedFileUpdaterUIFileUpdateRequested(
\n CachedFileUpdaterUI sender, FileUpdateRequestedEventArgs args)
\n{
\n bool showSpecificUI = false;<\/p>\n
\n if (sender.UIStatus == UIStatus.Hidden)
\n {
\n args.Request.Status = FileUpdateStatus.UserInputNeeded;<\/p>\n
\n sender.Title = "Requiring input for : "
\n + args.Request.ContentId;
\n deferral.Complete();
\n return;
\n }<\/p>\n
\n {
\n\t\/\/failure
\n args.Request.Status = FileUpdateStatus.Failed;
\n deferral.Complete();
\n return;
\n }<\/p>\n
\n {
\n\t\t\/\/Do nothing, the UI will do it for us.
\n return;
\n }
\n}<\/p>\n
\n[csharp]
\nprivate void ButtonBase_OnClick(object sender, RoutedEventArgs e)
\n{
\n App.FileUpdateRequestedEventArgs
\n\t .Request.Status = FileUpdateStatus.Complete;
\n App.FileUpdateRequestedEventArgs
\n\t .Request.GetDeferral().Complete();
\n}
\n[\/csharp]<\/p>\nWhy is it useful with the FileSavePicker ?<\/h2>\n
\n
\n
\n[csharp]
\nprotected override void
\n OnFileSavePickerActivated(FileSavePickerActivatedEventArgs args)
\n{
\n base.OnFileSavePickerActivated(args);<\/p>\n
\n += FileSavePickerUI_TargetFileRequested;
\n}<\/p>\n
\n FileSavePickerUI sender,
\n TargetFileRequestedEventArgs args)
\n{
\n var fileCreated = await ApplicationData.Current
\n .TemporaryFolder.CreateFileAsync("ThisIsACoolFileName");<\/p>\n
\n "A content id to identify the file.",
\n ReadActivationMode.BeforeAccess,
\n WriteActivationMode.AfterWrite,
\n CachedFileOptions.None);<\/p>\nOthers importants things to know<\/h3>\n
1) don’t forget to activate your app.<\/h5>\n