1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Merge pull request #4116 from kambala-decapitator/ios-launcher-copy-data

[launcher][iOS] fix copying existing OH3 data
This commit is contained in:
Ivan Savenko 2024-06-10 18:22:02 +03:00 committed by GitHub
commit 5512ebee64
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 124 additions and 4 deletions

View File

@ -25,5 +25,7 @@ const char *bundlePath();
const char *frameworksPath();
const char *bundleIdentifier();
bool isOsVersionAtLeast(unsigned int osMajorVersion);
}
#pragma GCC visibility pop

View File

@ -46,4 +46,9 @@ const char *bundlePath() { return NSBundle.mainBundle.bundlePath.fileSystemRepre
const char *frameworksPath() { return NSBundle.mainBundle.privateFrameworksPath.fileSystemRepresentation; }
const char *bundleIdentifier() { return NSBundle.mainBundle.bundleIdentifier.UTF8String; }
bool isOsVersionAtLeast(unsigned int osMajorVersion)
{
return NSProcessInfo.processInfo.operatingSystemVersion.majorVersion >= osMajorVersion;
}
}

View File

@ -26,6 +26,8 @@ set(launcher_SRCS
if(APPLE_IOS)
list(APPEND launcher_SRCS
ios/launchGame.m
ios/selectdirectory.h
ios/selectdirectory.mm
)
endif()
@ -212,6 +214,11 @@ if(ENABLE_INNOEXTRACT)
endif()
if(APPLE_IOS)
target_link_libraries(vcmilauncher
iOS_utils
"-framework UniformTypeIdentifiers"
)
# TODO: remove after switching prebuilt deps to a newer Conan's Qt recipe
if(XCODE_VERSION VERSION_GREATER_EQUAL 14.0)
target_link_libraries(vcmilauncher "-framework IOKit")

View File

@ -26,7 +26,11 @@
#include "cli/extract.hpp"
#endif
#ifdef VCMI_ANDROID
#ifdef VCMI_IOS
#include "ios/selectdirectory.h"
#include "iOS_utils.h"
#elif defined(VCMI_ANDROID)
#include <QAndroidJniObject>
#include <QtAndroid>
@ -226,9 +230,12 @@ void FirstLaunchView::heroesDataMissing()
#ifdef VCMI_ANDROID
// selecting directory with ACTION_OPEN_DOCUMENT_TREE is available only since API level 21
bool canUseDataCopy = QtAndroid::androidSdkVersion() >= 21;
const bool canUseDataCopy = QtAndroid::androidSdkVersion() >= 21;
#elif defined(VCMI_IOS)
// selecting directory through UIDocumentPickerViewController is available only since iOS 13
const bool canUseDataCopy = iOS_utils::isOsVersionAtLeast(13);
#else
bool canUseDataCopy = true;
const bool canUseDataCopy = true;
#endif
ui->labelDataCopyTitle->setVisible(canUseDataCopy);
@ -385,8 +392,15 @@ void FirstLaunchView::copyHeroesData(const QString & path, bool move)
{
QDir sourceRoot{path};
#ifdef VCMI_IOS
// TODO: Qt 6.5 can select directories https://codereview.qt-project.org/c/qt/qtbase/+/446449
SelectDirectory iosDirectorySelector;
if(path.isEmpty())
sourceRoot.setPath(iosDirectorySelector.getExistingDirectory());
#else
if(path.isEmpty())
sourceRoot.setPath(QFileDialog::getExistingDirectory(this, {}, {}, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
#endif
if(!sourceRoot.exists())
return;

View File

@ -0,0 +1,20 @@
/*
* selectdirectory.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include <QString>
class SelectDirectory final
{
public:
~SelectDirectory();
QString getExistingDirectory();
};

View File

@ -0,0 +1,72 @@
/*
* selectdirectory.mm, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "selectdirectory.h"
#include <QEventLoop>
#import <UIKit/UIKit.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#import <MobileCoreServices/MobileCoreServices.h>
@interface ObjcDocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
@property (nonatomic, assign, readonly) QEventLoop & eventLoop;
@property (nonatomic, copy, nullable) NSURL * selectedDirectoryURL;
@end
@implementation ObjcDocumentPickerDelegate
{
QEventLoop _eventLoop;
}
- (QEventLoop &)eventLoop { return _eventLoop; }
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
{
self.selectedDirectoryURL = urls.firstObject;
_eventLoop.exit();
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
{
_eventLoop.exit();
}
@end
static ObjcDocumentPickerDelegate * documentPickerDelegate;
SelectDirectory::~SelectDirectory()
{
[documentPickerDelegate.selectedDirectoryURL stopAccessingSecurityScopedResource];
documentPickerDelegate = nil;
}
QString SelectDirectory::getExistingDirectory()
{
documentPickerDelegate = [ObjcDocumentPickerDelegate new];
UIDocumentPickerViewController * documentPickerVc;
if(@available(iOS 14.0, *))
documentPickerVc = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:@[UTTypeFolder]];
else
documentPickerVc = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(__bridge NSString *)kUTTypeFolder] inMode:UIDocumentPickerModeOpen];
documentPickerVc.allowsMultipleSelection = NO;
documentPickerVc.delegate = documentPickerDelegate;
[UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPickerVc animated:YES completion:nil];
documentPickerDelegate.eventLoop.exec(QEventLoop::DialogExec);
if(!documentPickerDelegate.selectedDirectoryURL)
return {};
[documentPickerDelegate.selectedDirectoryURL startAccessingSecurityScopedResource];
return QString::fromNSString(documentPickerDelegate.selectedDirectoryURL.path);
}