iCloud Drive list directories and files through NSMetadataQuery - icloud

I have built an iCloud-enabled app named "rmc".My app now can upload files to iCloud Drive and get metadata by NSMetadataQuery.But NSMetadataQuery's results only include the files in my APP's Container.Please see this link:https://developer.apple.com/videos/wwdc/2015/?id=234,
this is a document and it is said that NSMetadataQuery can get files in other APP's container.What I want is that I can get all files in iCloud Drive,just like the app "Document 5" and "Cloud Lite",they can get all files.
please see this picture.It is the UI of APP "Document 5".This APP can get the root directory information of iCloud Drive.But my app only can get files in the folder of "rmc".I also want to get the all directories and files in iCloud Drive.Like "Document 5" did.I hope if someone can help me and understand my question,because my English is pour.Thanks!!!
This is my code:
- (BOOL)getFiles
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
self.query = [[NSMetadataQuery alloc]init];
self.query.predicate = [NSPredicate predicateWithFormat:#"%K like '*'",NSMetadataItemFSNameKey]; // all
self.query.searchScopes = [NSArray arrayWithObjects:NSMetadataQueryUbiquitousDocumentsScope,NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope,nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(getFilesFinished:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(getFilesFinished:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
[self.query startQuery];
return YES;
}
this method used NSMetadataQuery to get metadata from iCloudDrive.And I set the searchScopes = [NSArray arrayWithObjects:NSMetadataQueryUbiquitousDocumentsScope,NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope,nil];
This is Apple's Documentation about this value:
NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope
Search for documents outside the app’s container. This search can locate iCloud documents that the user previously opened using a document picker view controller. This lets your app access the documents again without requiring direct user interaction. The result’s NSMetadataItemURLKey attributes return security-scoped NSURLs. For more information on working with security-scoped URLs, see Security-Scoped URLs in NSURL Class Reference.

Related

Whats best way of getting content from SharePoint to AWS/Azure programmatically?

How do we move from sharepoint to AWS estate?
I have found various sources on how to do it in the UI, but nothing programmatically?
Any suggestions would be greatly appreciated
Here are UI steps I've found but nothing programmatically - https://www.youtube.com/watch?v=VW6gqVsvOeQ
You should be able to do this in code using the Graph APIs. In particular, you'll be looking for the Working with files in Microsoft Graph section of the API documentation.
Follow these steps to install the Graph SDK.
Follow these steps to Create an app registration.
Follow these steps to Add a certificate to the app registration.
Get an auth token in your code.
Get the site ID by appending /_api/site/id to the site url e.g. https://contoso.sharepoint.com/sites/TheSite/_api/site/id
Get the list of drives associated with the document libraries on your site.
For each drive, get a list of children.
Iterate each child recursively to expand through folders and sub folders.
Download items.
Upload items to AWS.
Getting an auth token
using Azure.Identity;
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_APP/CLIENT_ID";
var clientCertificate = new X509Certificate2("MyCertificate.pfx");
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientcertificatecredential
var clientCertCredential = new ClientCertificateCredential(
tenantId, clientId, clientCertificate, options);
var graphClient = new GraphServiceClient(clientCertCredential, scopes);
Get list of drives
var drives = await graphClient.Sites["{site-id}"].Drives
.Request()
.GetAsync();
Get root items of a drive
var children = await graphClient.Drives["{drive-id}"].Root.Children
.Request()
.GetAsync();
Get children of items
var children = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Children
.Request()
.GetAsync();
Download files
var stream = await graphClient.Me.Drive.Items["{driveItem-id}"].Content
.Request()
.GetAsync();

Django download links only working in new tab

This is driving me crazy, I'm developing a django app and need to provide a download link to a file located in the media folder. If I type the url in a blank tab it works fine, the file is downloaded, but if I click on the link from the website nothing happens. I realize this might be because the url to the file doesn't have the same origin that the website and from what I understood the browser won't allow the download, is this correct? Is there any way around?
url of the website (in development): http://localhost:8000/django_app/view_name
url of the file: http://localhost:8000/django_app/media/file.ext
I've tried the following html href:
href="../media/file.ext" download target="_blank"
And the following view:
def download_file(request):
fl_path = settings.MEDIA_ROOT + "\\filename.ext"
filename = "file_name"
mime_type, _ = mimetypes.guess_type(fl_path)
response = HttpResponse(fl, content_type=mime_type)
response['Content-Disposition'] = "attachment; filename=%s" % filename
return response
Nothing happens when I click on the link, no error generated. If I open the link in a new tab it downloads the file normally... Note that I need to be able to change the href link dynamically.
Thanks!

Uploaded media files 404 on production but show up hours later

We've built a custom front end for users to post threads and upload images on top of Sitecore 9. Recently, we moved the user generated content to it's own database, so the media files are no longer in the proper sitecore 'media gallery'. Also, file storage is on a networked share. Uploading images works just fine. It's immediately after where the problem lies.
Upon image upload, our rest api returns the media url from the MediaManager.GetMediaUrl(itemId). This also works. It returns a valid url, it is formatted correctly and should resolve. Unfortunately, for some time after, the url does the sitecore dance an 302s to our 404 page.
I can see the image through the content editor and our custom content handler injects the image folder node into both master and web databases.
Why would the link manager be able to find the url, but the image is not available? I uploaded something yesterday afternoon, an when I checked this morning, the image is now available on the site. Any information or suggestions are appreciated.
I have tried saving the image multiple times hoping that this might trigger whatever mystical Sitecore event that causes images to show. Since there isn't a publish due to the separate database, I can't try that. I've removed all versions thinking it couldn't default to a particular language. Nothing. Only time seems to make the images visible. The code below works just fine. I'm just putting it here to to show some work.
public MediaItem UploadSimpleMedia(MediaGallerySimpleUploadRequest request)
{
try
{
var destinationFolder = request.ParentItemId != null
? _content.GetItem<Item>(request.ParentItemId.Value)
: _content.GetItem<Item>(_publicLibraryPath + "/embeded");
var name = !string.IsNullOrEmpty(request.Name)
? ItemUtil.ProposeValidItemName(request.Name)
: ItemUtil.ProposeValidItemName(request.Files[0].FileName);
var creator = new MediaCreator();
var tags = request.Tags != null ? request.Tags.Split(',') : new string[0];
var tagIds = _tagService.GetTagIds(tags);
var tagIdString = string.Join(",", tagIds);
var options = new MediaCreatorOptions()
{
AlternateText = request.Name,
FileBased = true,
IncludeExtensionInItemName = false,
Versioned = false,
Destination = $"{destinationFolder.Paths.Path}/{name}",
Database = Factory.GetDatabase("content")
};
using (new SecurityDisabler())
using (new DatabaseCacheDisabler())
{
MediaItem item = creator.CreateFromStream(request.Files[0].InputStream, request.Files[0].FileName, options);
item.BeginEdit();
item.InnerItem["Title"] = request.Name;
item.InnerItem["Description"] = request.Description;
item.InnerItem["__Semantics"] = tagIdString;
// Sitecore won't calculate MIME Type or File Size automatically unless you upload directly
// to the Sitecore Media Library. We're uploading in-place for private groups for permission inheritance
// and now because of indexing, they are getting uploaded to /Community/Gallery/Files if not private.
item.InnerItem["Size"] = request.Files[0].ContentLength.ToString();
item.InnerItem["Mime Type"] = request.Files[0].ContentType;
item.EndEdit();
// Just pausing here to reflect on why Sitecore is so sexily complicated
// that it takes time to display an image on the CD, but has no problem giving
// up the media url
CacheManager.GetHtmlCache(Sitecore.Context.Site);
_searchService.RefreshIndex(item.ID.Guid);
var fromDatabase = _content.GetItem<Item>(item.ID.Guid);
return fromDatabase;
}
}
catch (Exception ex)
{
_logger.Error(this.GetType().AssemblyQualifiedName, ex);
_logger.Trace(ex.StackTrace);
}
return null;
}
I don't get any error messages either in our custom logs or the default sitecore logs. Images just aren't resolving. Is it caching? I've even nuked all caches by calling CacheManager.ClearAllCaches().

sitecore analytics pdf download tracking

how do I track a pdf download with sitecore page events?
I have code which tracks the event from back end but how do you determine whether the link is external, internal or a media link?
And how can you determine if media link is pdf?
public void RegisterDownload(string downloadedResourceText, ID itemId)
{
if (downloadedResourceText != null)
{
if (TrackerEnabled())
{
var page = CurrentPage();
page.Register(new PageEventData("Download", _downloadPageEventGuid) { ItemId = itemId.ToGuid(), Data = downloadedResourceText, DataKey = downloadedResourceText, Text = "Resource Downloaded" });
}
}
}
If you want to do it with Sitecore, just set the event in the Tracking field for the PDF in the media library.
Then it shows up in the experience profile or you can trigger a engagement plan, etc...
If you are looking to do it programmatically, you have to create the details of the event. You just pass in a string of "User did X" to the page event code you have posted. The itemID is the page they were on when they did it. If it was a brochure, you would have "downloaded the brochure for product XYZ".
Some good details of the properties of the page event call can be found here:
https://doc.sitecore.net/sitecore_experience_platform/82/digital_marketing/marketing_operations/events/register_a_page_event_programmatically

How to serve static content with embedded Jetty?

I have tried to serve simple html documents using embedded Jetty, but I keep getting 404 error. Here's my relevant setup
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
resource_handler.setResourceBase(".");
server.setHandler(resource_handler);
As I run this from Eclipse and print out the BaseResource, I'll get my project's workspace directory where I have a simple index.html. However if I try the url http://127.0.0.1:8888/index.html, I'll get a 404 error - what am I missing?