Commit 67824c11 authored by Marc Etcheverry's avatar Marc Etcheverry Committed by Felix Paul Kühne

Add file sharing support (#11302)

Signed-off-by: Felix Paul Kühne's avatarFelix Paul Kühne <fkuehne@videolan.org>
parent a7e1567a
B"CHOOSE_AUDIO_TRACK"="Choose Audio Track";
......
//
// VLCOpenInActivity.h
// VLC for iOS
//
// Created by Marc Etcheverry on 6/26/14.
// Copyright (c) 2014 VideoLAN. All rights reserved.
//
/// A UIActivity that handles multiple files and presents them in a UIDocumentInteractionController
/// This class is inspired by https://github.com/honkmaster/TTOpenInAppActivity
@interface VLCOpenInActivity : UIActivity
@property (nonatomic, weak) UIViewController *presentingViewController;
@property (nonatomic, weak) UIBarButtonItem *presentingBarButtonItem;
@end
//
// VLCOpenInActivity.m
// VLC for iOS
//
// Created by Marc Etcheverry on 6/26/14.
// Copyright (c) 2014 VideoLAN. All rights reserved.
//
#import "VLCOpenInActivity.h"
#import <MobileCoreServices/MobileCoreServices.h>
@interface VLCOpenInActivity () <UIActionSheetDelegate, UIDocumentInteractionControllerDelegate>
@end
@implementation VLCOpenInActivity
{
NSMutableArray /* NSURL */ *_fileURLs;
UIDocumentInteractionController *_documentInteractionController;
}
#pragma mark - UIActivity
- (void)dealloc
{
_documentInteractionController.delegate = nil;
}
+ (UIActivityCategory)activityCategory
{
return UIActivityCategoryAction;
}
- (NSString *)activityType
{
return NSStringFromClass([self class]);
}
- (NSString *)activityTitle
{
return NSLocalizedString(@"SHARING_ACTIVITY_OPEN_IN_TITLE", nil);
}
- (UIImage *)activityImage
{
return [UIImage imageNamed:@"OpenInActivityIcon"];
}
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
for (id activityItem in activityItems) {
if ([activityItem isKindOfClass:[NSURL class]] &&
[(NSURL *)activityItem isFileURL]) {
return YES;
}
}
return NO;
}
- (void)prepareWithActivityItems:(NSArray *)activityItems
{
_fileURLs = [[NSMutableArray alloc] initWithCapacity:[activityItems count]];
for (id activityItem in activityItems) {
if ([activityItem isKindOfClass:[NSURL class]]
&& [(NSURL *)activityItem isFileURL]) {
[_fileURLs addObject:activityItem];
}
}
}
- (void)performActivity
{
if (!self.presentingViewController || !self.presentingBarButtonItem) {
[self activityDidFinish:NO];
return;
}
NSUInteger count = [_fileURLs count];
if (count > 1) {
[self presentFileSelectionActionSheet];
} else if (count == 1) {
[self presentDocumentInteractionControllerWithFileURL:[_fileURLs firstObject]];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_FILES", nil)
message:nil
delegate:nil
cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
otherButtonTitles:nil];
[alertView show];
[self activityDidFinish:NO];
}
}
#pragma mark - UIDocumentInteractionController
- (NSString *)UTTypeForFileURL:(NSURL *)url
{
CFStringRef UTTypeStringRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)url.pathExtension, NULL);
return (NSString *)CFBridgingRelease(UTTypeStringRef);
}
- (void)presentDocumentInteractionControllerWithFileURL:(NSURL *)fileURL
{
NSParameterAssert(fileURL);
if (!fileURL) {
[self activityDidFinish:NO];
return;
}
if (!self.presentingBarButtonItem) {
[self activityDidFinish:NO];
return;
}
_documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
_documentInteractionController.delegate = self;
_documentInteractionController.UTI = [self UTTypeForFileURL:fileURL];
__block BOOL controllerWasPresentedSuccessfully = NO;
dispatch_block_t controllerPresentationBlock = ^{
controllerWasPresentedSuccessfully = [_documentInteractionController presentOpenInMenuFromBarButtonItem:self.presentingBarButtonItem animated:YES];
if (!controllerWasPresentedSuccessfully) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_APPLICATIONS", nil)
message:nil
delegate:nil
cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
otherButtonTitles:nil];
[alertView show];
[self activityDidFinish:NO];
}
};
if (![self.presentingViewController presentedViewController]) {
controllerPresentationBlock();
} else {
[self.presentingViewController dismissViewControllerAnimated:YES completion:controllerPresentationBlock];
}
}
#pragma mark - UIDocumentInteractionControllerDelegate
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller
{
[self activityDidFinish:YES];
_documentInteractionController.delegate = nil;
_documentInteractionController = nil;
}
#pragma mark - UIActionSheet
- (void)presentFileSelectionActionSheet
{
[self.presentingViewController dismissViewControllerAnimated:YES completion:^{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"SHARING_ACTION_SHEET_TITLE_CHOOSE_FILE", nil)
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (NSURL *fileURL in _fileURLs) {
[actionSheet addButtonWithTitle:[fileURL lastPathComponent]];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)];
[actionSheet showFromBarButtonItem:self.presentingBarButtonItem animated:YES];
}];
}
#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (actionSheet.cancelButtonIndex != buttonIndex) {
[self presentDocumentInteractionControllerWithFileURL:_fileURLs[buttonIndex]];
} else {
[self activityDidFinish:NO];
}
}
@end
......@@ -26,6 +26,9 @@
#import "VLCFolderCollectionViewFlowLayout.h"
#import "LXReorderableCollectionViewFlowLayout.h"
#import "VLCAlertView.h"
#import "VLCOpenInActivity.h"
#import <AssetsLibrary/AssetsLibrary.h>
/* prefs keys */
static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutorial?";
......@@ -63,6 +66,9 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
UISearchDisplayController *_searchDisplayController;
BOOL _usingTableViewToShowData;
UIBarButtonItem *_actionBarButtonItem;
VLCOpenInActivity *_openInActivity;
}
@property (nonatomic, strong) UITableView *tableView;
......@@ -142,7 +148,26 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
[_emptyLibraryView.emptyLibraryLongDescriptionLabel sizeToFit];
[_emptyLibraryView.learnMoreButton setTitle:NSLocalizedString(@"BUTTON_LEARN_MORE", @"") forState:UIControlStateNormal];
UIBarButtonItem *createFolderItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize target:self action:@selector(createFolder)];
[self setToolbarItems:@[createFolderItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], [UIBarButtonItem themedDarkToolbarButtonWithTitle:NSLocalizedString(@"BUTTON_RENAME", @"") target:self andSelector:@selector(renameSelection)], [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteSelection)]]];
// Better visual alignment with the action button
UIEdgeInsets insets = UIEdgeInsetsMake(4, 0, 0, 0);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
insets.top += 1;
}
createFolderItem.imageInsets = insets;
_actionBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(actOnSelection:)];
_actionBarButtonItem.enabled = NO;
// If you find strange issues with multiple Edit/Cancel actions causing UIToolbar spacing corruption, use a flexible space instead of a fixed space.
UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedSpace.width = 20;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
fixedSpace.width *= 2;
}
[self setToolbarItems:@[_actionBarButtonItem, fixedSpace, createFolderItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], [UIBarButtonItem themedDarkToolbarButtonWithTitle:NSLocalizedString(@"BUTTON_RENAME", @"") target:self andSelector:@selector(renameSelection)], [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteSelection)]]];
self.navigationController.toolbar.barStyle = UIBarStyleBlack;
if (SYSTEM_RUNS_IOS7_OR_LATER) {
......@@ -269,7 +294,7 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
UIBarButtonItem *removeFromFolder = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:@selector(removeFromFolder)];
NSMutableArray *toolbarItems = [self.toolbarItems mutableCopy];
toolbarItems[0] = removeFromFolder;
toolbarItems[2] = removeFromFolder;
self.toolbarItems = toolbarItems;
[self reloadViews];
......@@ -467,10 +492,14 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
- (void)reloadViews
{
if (_usingTableViewToShowData)
// Since this gets can get called at any point and wipe away the selections, we update the actionBarButtonItem here because this can happen if you tap "Save Video" in the UIActivityController and a media access alert view takes away focus (the corresponding 'became active' notification of UIApplication will call this). Or simply try bringing down the notification center to trigger this. Any existing UIActivityViewController session should be safe as it would have copies of the selected file references.
if (_usingTableViewToShowData) {
[self.tableView reloadData];
else
[self updateActionBarButtonItemStateWithSelectedIndexPaths:[self.tableView indexPathsForSelectedRows]];
} else {
[self.collectionView reloadData];
[self updateActionBarButtonItemStateWithSelectedIndexPaths:[self.collectionView indexPathsForSelectedItems]];
}
[self _displayEmptyLibraryViewIfNeeded];
}
......@@ -545,6 +574,13 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
[self removeMediaObject: _foundMedia[indexPath.row] updateDatabase:YES];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.isEditing) {
[self updateActionBarButtonItemStateWithSelectedIndexPaths:[tableView indexPathsForSelectedRows]];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.isEditing) {
......@@ -553,6 +589,8 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
_libraryMode = _previousLibraryMode;
[self updateViewContents];
[self createFolderWithName:nil];
} else {
[self updateActionBarButtonItemStateWithSelectedIndexPaths:[tableView indexPathsForSelectedRows]];
}
return;
}
......@@ -687,6 +725,8 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
_folderObject = _foundMedia[indexPath.item];
[self createFolderWithName:nil];
_libraryMode = _previousLibraryMode;
} else {
[self updateActionBarButtonItemStateWithSelectedIndexPaths:[collectionView indexPathsForSelectedItems]];
}
[(VLCPlaylistCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath] selectionUpdate];
return;
......@@ -724,6 +764,10 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (self.editing) {
[self updateActionBarButtonItemStateWithSelectedIndexPaths:[collectionView indexPathsForSelectedItems]];
}
[(VLCPlaylistCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath] selectionUpdate];
}
......@@ -1049,7 +1093,7 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
inFolder = NO;
UIBarButtonItem *createFolderItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize target:self action:@selector(createFolder)];
NSMutableArray *toolbarItems = [self.toolbarItems mutableCopy];
toolbarItems[0] = createFolderItem;
toolbarItems[2] = createFolderItem;
self.toolbarItems = toolbarItems;
[self setLibraryMode:_libraryMode];
[self updateViewContents];
......@@ -1149,6 +1193,126 @@ static NSString *kDisplayedFirstSteps = @"Did we display the first steps tutoria
[self _endEditingWithHardReset:NO];
}
#pragma mark - Sharing
// We take the array of index paths (instead of a count) to actually examine if the content is shareable. Selecting a single folder should not enable the share button.
- (void)updateActionBarButtonItemStateWithSelectedIndexPaths:(NSArray *)indexPaths
{
NSUInteger count = [indexPaths count];
if (!indexPaths || count == 0) {
_actionBarButtonItem.enabled = NO;
} else {
// Look for at least one MLFile
for (NSUInteger x = 0; x < count; x++) {
MLFile *file = _foundMedia[[indexPaths[x] row]];
if ([file isKindOfClass:[MLFile class]]) {
_actionBarButtonItem.enabled = YES;
return;
}
}
}
}
- (void)actOnSelection:(UIBarButtonItem *)barButtonItem
{
NSParameterAssert(barButtonItem);
if (!barButtonItem) {
APLog(@"Missing a UIBarButtonItem to present from");
return;
}
NSArray *indexPaths;
if (!_usingTableViewToShowData)
indexPaths = [self.collectionView indexPathsForSelectedItems];
else
indexPaths = [self.tableView indexPathsForSelectedRows];
NSUInteger count = indexPaths.count;
if (count) {
NSMutableArray /* NSURL */ *fileURLobjects = [[NSMutableArray alloc] initWithCapacity:count];
for (NSUInteger x = 0; x < count; x++) {
MLFile *file = _foundMedia[[indexPaths[x] row]];
if ([file isKindOfClass:[MLFile class]]) {
NSURL *fileURL = [NSURL URLWithString:[file url]];
if ([fileURL isFileURL]) {
[fileURLobjects addObject:fileURL];
}
}
}
if ([fileURLobjects count]) {
// Provide some basic user feedback as UIActivityController lags in presentation sometimes (blocking the main thread).
// iOS 6 has trouble re-enabling all the icons, so only disable the sharing one. Usage of the toolbar will be disabled by UIApplication in this case anyhow.
if (SYSTEM_RUNS_IOS7_OR_LATER) {
[self.navigationController.toolbar.items makeObjectsPerformSelector:@selector(setEnabled:) withObject:@(NO)];
} else {
_actionBarButtonItem.enabled = YES;
}
// Just in case, since we are facing a possible delay from code we do not control (UIActivityViewController), disable any possible changes to selection (or exit from this screen)
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
// The reason we do a dispatch_async to the main queue here even though we are already on the main queue is because UIActivityViewController blocks the main thread at some point (either during creation or presentation), which won't let UIKit draw our call to disable the toolbar items in time. On an actual device (where the lag can be seen when UIActivityViewController is presented for the first time during an applications lifetime) this makes for a much better user experience. If you have more items to share the lag may be greater.
dispatch_async(dispatch_get_main_queue(), ^{
_openInActivity = [[VLCOpenInActivity alloc] init];
_openInActivity.presentingViewController = self;
_openInActivity.presentingBarButtonItem = barButtonItem;
dispatch_block_t enableInteractionBlock = ^{
if (SYSTEM_RUNS_IOS7_OR_LATER) {
// Strangely makeObjectsPerformSelector:withObject has trouble here (when called from presentViewController:animated:completion:)
// [self.navigationController.toolbar.items makeObjectsPerformSelector:@selector(setEnabled:) withObject:@(YES)];
for (UIBarButtonItem *item in self.navigationController.toolbar.items) {
item.enabled = YES;
}
} else {
_actionBarButtonItem.enabled = YES;
}
if ([[UIApplication sharedApplication] isIgnoringInteractionEvents]) {
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
};
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:fileURLobjects applicationActivities:@[_openInActivity]];
controller.completionHandler = ^(NSString *activityType, BOOL completed) {
APLog(@"UIActivityViewController finished with activity type: %@, completed: %i", activityType, completed);
// Provide some feedback if saving media to the Camera Roll. Note that this could caus a false positive if the user chooses "Don't Allow" in the permissions dialog, and UIActivityViewController does not inform us of that, so check the authorization status.
// By the time this is called, the user has not had time to choose whether to allow access to the Photos library, so only display the message if we are truly sure we got authorization. The first time the user saves to the camera roll he won't see the confirmation because of this timing issue. This is better than showing a success message when the user had denied access. A timing workaround could be developed if needed through UIApplicationDidBecomeActiveNotification (to know when the security alert view was dismissed) or through other ALAssets APIs.
if (completed && [activityType isEqualToString:UIActivityTypeSaveToCameraRoll] && [ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusAuthorized) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHARING_SUCCESS_CAMERA_ROLL", nil)
message:nil
delegate:nil
cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
otherButtonTitles:nil];
[alertView show];
}
_openInActivity = nil;
// Just in case, we could call enableInteractionBlock here. Since we are disabling touch interaction for the entire UI, to be safe that we return to the proper state: re-enable everything (if presentViewController:animated:completion: failed for some reason). But UIApplication gives us a warning even if we check isIgnoringInteractionEvents, so do not call it for now.
// enableInteractionBlock();
};
[self.navigationController presentViewController:controller animated:YES completion:enableInteractionBlock];
});
return;
}
}
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_FILES", nil)
message:nil
delegate:nil
cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
otherButtonTitles:nil];
[alertView show];
}
#pragma mark - coin coin
- (void)setLibraryMode:(VLCLibraryMode)mode
......
......@@ -369,6 +369,10 @@
7DF7CA0717650C2A00C61739 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7DF7CA0617650C2A00C61739 /* AVFoundation.framework */; };
7DF7E791175F47DC0018858D /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7DF7E790175F47DC0018858D /* MediaPlayer.framework */; };
7DF9352F1958AB0600E60FD4 /* UIColor+Presets.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF9352E1958AB0600E60FD4 /* UIColor+Presets.m */; };
8F91EC79195CEC7900F5BCBA /* VLCOpenInActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F91EC78195CEC7900F5BCBA /* VLCOpenInActivity.m */; };
8F91EC7C195DF9D200F5BCBA /* OpenInActivityIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8F91EC7A195DF9D200F5BCBA /* OpenInActivityIcon.png */; };
8F91EC7D195DF9D200F5BCBA /* OpenInActivityIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8F91EC7B195DF9D200F5BCBA /* OpenInActivityIcon@2x.png */; };
8F91EC7F195E1DAB00F5BCBA /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F91EC7E195E1DAB00F5BCBA /* AssetsLibrary.framework */; };
9B088308183D7BEC004B5C2A /* VLCCloudStorageTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B088307183D7BEC004B5C2A /* VLCCloudStorageTableViewController.m */; };
9B1A164E185E0821001A99D9 /* backIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B1A164C185E0821001A99D9 /* backIcon.png */; };
9B1A164F185E0821001A99D9 /* backIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9B1A164D185E0821001A99D9 /* backIcon@2x.png */; };
......@@ -1040,6 +1044,11 @@
7DF7E790175F47DC0018858D /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
7DF9352D1958AB0600E60FD4 /* UIColor+Presets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+Presets.h"; path = "Sources/UIColor+Presets.h"; sourceTree = SOURCE_ROOT; };
7DF9352E1958AB0600E60FD4 /* UIColor+Presets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIColor+Presets.m"; path = "Sources/UIColor+Presets.m"; sourceTree = SOURCE_ROOT; };
8F91EC77195CEC7900F5BCBA /* VLCOpenInActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCOpenInActivity.h; path = Sources/VLCOpenInActivity.h; sourceTree = SOURCE_ROOT; };
8F91EC78195CEC7900F5BCBA /* VLCOpenInActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCOpenInActivity.m; path = Sources/VLCOpenInActivity.m; sourceTree = SOURCE_ROOT; };
8F91EC7A195DF9D200F5BCBA /* OpenInActivityIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = OpenInActivityIcon.png; sourceTree = "<group>"; };
8F91EC7B195DF9D200F5BCBA /* OpenInActivityIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "OpenInActivityIcon@2x.png"; sourceTree = "<group>"; };
8F91EC7E195E1DAB00F5BCBA /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
9B088306183D7BEC004B5C2A /* VLCCloudStorageTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCCloudStorageTableViewController.h; path = Sources/VLCCloudStorageTableViewController.h; sourceTree = SOURCE_ROOT; };
9B088307183D7BEC004B5C2A /* VLCCloudStorageTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCCloudStorageTableViewController.m; path = Sources/VLCCloudStorageTableViewController.m; sourceTree = SOURCE_ROOT; };
9B1A164C185E0821001A99D9 /* backIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backIcon.png; sourceTree = "<group>"; };
......@@ -1192,6 +1201,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8F91EC7F195E1DAB00F5BCBA /* AssetsLibrary.framework in Frameworks */,
7D15168B194773630086FB8C /* MobileCoreServices.framework in Frameworks */,
7D168F7118D4A21B003FAF59 /* Accelerate.framework in Frameworks */,
CCE2A22E17A5859E00D9EAAD /* CoreText.framework in Frameworks */,
......@@ -1644,6 +1654,8 @@
7D378496183A98D1009EE944 /* VLCPlaylistTableViewCell.m */,
7D378497183A98D1009EE944 /* VLCPlaylistViewController.h */,
7D378498183A98D1009EE944 /* VLCPlaylistViewController.m */,
8F91EC77195CEC7900F5BCBA /* VLCOpenInActivity.h */,
8F91EC78195CEC7900F5BCBA /* VLCOpenInActivity.m */,
7D37849C183A98DD009EE944 /* VLCThumbnailsCache.h */,
7D37849D183A98DD009EE944 /* VLCThumbnailsCache.m */,
);
......@@ -1810,6 +1822,7 @@
7D94FCDD16DE7D1000F2623B /* Frameworks */ = {
isa = PBXGroup;
children = (
8F91EC7E195E1DAB00F5BCBA /* AssetsLibrary.framework */,
7D15168A194773630086FB8C /* MobileCoreServices.framework */,
7D168F7018D4A21B003FAF59 /* Accelerate.framework */,
7D897889185E1344009BAB5D /* libCrashReporter.a */,
......@@ -1925,6 +1938,8 @@
7DBC3B3C1711DD1E00DCF688 /* Icons */ = {
isa = PBXGroup;
children = (
8F91EC7A195DF9D200F5BCBA /* OpenInActivityIcon.png */,
8F91EC7B195DF9D200F5BCBA /* OpenInActivityIcon@2x.png */,
7D6B08C0174A831900A05173 /* vlc-xmas.png */,
7D6B08C1174A831900A05173 /* vlc-xmas@2x.png */,
7D3E6CE418589EE000D584E7 /* AppIcon512x512.png */,
......@@ -2480,6 +2495,7 @@
7D897885185E00C3009BAB5D /* checkboxEmpty@2x.png in Resources */,
9BADAF48185FC66700108BD8 /* playbackControllerBg.png in Resources */,
7DBBF19D183AB4300009A339 /* VLCCloudStorageTableViewController.xib in Resources */,
8F91EC7C195DF9D200F5BCBA /* OpenInActivityIcon.png in Resources */,
7D278D6B18E9D5EF0063E109 /* tvShow.png in Resources */,
7D47D7271760D77C00E86BAD /* pauseIcon.png in Resources */,
7D47D7281760D77C00E86BAD /* pauseIcon@2x.png in Resources */,
......@@ -2618,6 +2634,7 @@
7D6622601871F29000CA9496 /* checkbox-legacy-empty.png in Resources */,
7D53D517187729EC00A1BA97 /* wifi@2x.png in Resources */,
7D3784E3183A99D2009EE944 /* papasscode_marker.png in Resources */,
8F91EC7D195DF9D200F5BCBA /* OpenInActivityIcon@2x.png in Resources */,
7D3784E4183A99D2009EE944 /* papasscode_marker@2x.png in Resources */,
7D89786F185DED88009BAB5D /* VLCFutureDownloadViewController.xib in Resources */,
);
......@@ -2683,6 +2700,7 @@
7D31001D17B64AE100E6516D /* GHRevealViewController.m in Sources */,
7DC72D6317B7ED24008A26D0 /* WhiteRaccoon.m in Sources */,
7D63C19018774B1700BD5256 /* VLCFirstStepsSecondPageViewController.m in Sources */,
8F91EC79195CEC7900F5BCBA /* VLCOpenInActivity.m in Sources */,
7D37848F183A98B6009EE944 /* VLCMovieViewController.m in Sources */,
7D378492183A98BF009EE944 /* VLCExternalDisplayController.m in Sources */,
7D378499183A98D1009EE944 /* VLCPlaylistCollectionViewCell.m in Sources */,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment