How to pass variable from flutter to native objective c - ios

I have found plenty of information on passing data from flutter to android using method channel but none for objective c. I understand calling functions, but not passing data. Below is an example of what I have.
Future<void> _uploadImage(String filePath) async {
try {
await platform.invokeMethod('uploadImage', {"filePath": filePath});
} on PlatformException catch (e) {
print("Failed to get token: '${e.message}'.");
}
}
else if([#"uploadImage" isEqualToString:call.method]){
DBUserClient *client = [DBClientsManager authorizedClient];
NSString *filePath = call.arguments(#"filePath");
NSLog(filePath, result);
NSData *fileData = [filePath dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
[[[client.filesRoutes uploadData:filePath inputData:fileData]
setResponseBlock:^(DBFILESFileMetadata *result, DBFILESUploadError *routeError, DBRequestError *networkError) {
if (result)
{
NSLog(#"%#\n", result);
} else
{
NSLog(#"%#\n%#\n", routeError, networkError);
}
}] setProgressBlock:^(int64_t bytesUploaded, int64_t totalBytesUploaded, int64_t totalBytesExpectedToUploaded) {
NSLog(#"\n%lld\n%lld\n%lld\n", bytesUploaded, totalBytesUploaded, totalBytesExpectedToUploaded);
}];
}
else{
result(FlutterMethodNotImplemented);
}
}];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
To clarify, the bottom set of code written in objective-c is definitely not correct, but I've been trying to piece it out. I have the images path and I am trying to upload it to Dropbox. Main issue is that the filePath is not reaching the method channel. NSString *filePath = call.arguments(#"filePath") isn't an actual function call.

Change:
NSString *filePath = call.arguments(#"filePath");
to
NSString *filePath = call.arguments[#"filePath"];

Related

Error 403 on Youtube Video Upload IOS

In my project wanna have a flow like this:
Users record short videos -> they upload the videos on my channel -> end
To achive this result i'm trying to work with the new Google APIs Client Library for Objective-C for REST. It has a poor documentation and the examples are for mac only. Anyway after many errors this is my code:
- (void)doAuthWithoutCodeExchange:(OIDServiceConfiguration *)configuration
clientID:(NSString *)clientID
clientSecret:(NSString *)clientSecret {
NSURL *redirectURI = [NSURL URLWithString:kRedirectURI];
// builds authentication request
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
clientId:clientID
clientSecret:clientSecret
scopes:#[ OIDScopeOpenID, OIDScopeProfile ]
redirectURL:redirectURI
responseType:OIDResponseTypeCode
additionalParameters:nil];
// performs authentication request
AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
[self logMessage:#"Initiating authorization request %#", request];
appDelegate.currentAuthorizationFlow =
[OIDAuthorizationService presentAuthorizationRequest:request
presentingViewController:self
callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse,
NSError *_Nullable error) {
if (authorizationResponse) {
OIDAuthState *authState =
[[OIDAuthState alloc] initWithAuthorizationResponse:authorizationResponse];
[self setAuthState:authState];
[self logMessage:#"Authorization response with code: %#",
authorizationResponse.authorizationCode];
// could just call [self tokenExchange:nil] directly, but will let the user initiate it.
OIDTokenRequest *tokenExchangeRequest =
[_authState.lastAuthorizationResponse tokenExchangeRequest];
[self logMessage:#"Performing authorization code exchange with request [%#]",
tokenExchangeRequest];
[OIDAuthorizationService performTokenRequest:tokenExchangeRequest
callback:^(OIDTokenResponse *_Nullable tokenResponse,
NSError *_Nullable error) {
if (!tokenResponse) {
[self logMessage:#"Token exchange error: %#", [error localizedDescription]];
} else {
[self logMessage:#"Received token response with accessToken: %#", tokenResponse.accessToken];
}
[_authState updateWithTokenResponse:tokenResponse error:error];
GTMAppAuthFetcherAuthorization *gtmAuthorization =
[[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:authState];
// Sets the authorizer on the GTLRYouTubeService object so API calls will be authenticated.
self.youTubeService.authorizer = gtmAuthorization;
// Serializes authorization to keychain in GTMAppAuth format.
[GTMAppAuthFetcherAuthorization saveAuthorization:gtmAuthorization
toKeychainForName:kGTMAppAuthKeychainItemName];
[self uploadVideoFile];
}];
} else {
[self logMessage:#"Authorization error: %#", [error localizedDescription]];
}
}];
}
This method cause this flow:
app send user to google login page in safari -> user log with his credentials -> after login, user is redirect back to my app -> the block success call the method UploadVideo.
This part of the flow seems to work correctly, i obtain a valid token as the log says. The second part is the video upload that consist in two main methods:
- (void)uploadVideoFile {
// Collect the metadata for the upload from the user interface.
// Status.
GTLRYouTube_VideoStatus *status = [GTLRYouTube_VideoStatus object];
status.privacyStatus = #"public";
// Snippet.
GTLRYouTube_VideoSnippet *snippet = [GTLRYouTube_VideoSnippet object];
snippet.title = #"title";
NSString *desc = #"description";
if (desc.length > 0) {
snippet.descriptionProperty = desc;
}
NSString *tagsStr = #"tags";
if (tagsStr.length > 0) {
snippet.tags = [tagsStr componentsSeparatedByString:#","];
}
GTLRYouTube_Video *video = [GTLRYouTube_Video object];
video.status = status;
video.snippet = snippet;
[self uploadVideoWithVideoObject:video
resumeUploadLocationURL:nil];
}
- (void)uploadVideoWithVideoObject:(GTLRYouTube_Video *)video
resumeUploadLocationURL:(NSURL *)locationURL {
NSURL *fileToUploadURL = [NSURL fileURLWithPath:self.VideoUrlCri.path];
NSError *fileError;
NSLog(#"step");
if (![fileToUploadURL checkPromisedItemIsReachableAndReturnError:&fileError]) {
NSLog(#"exit");
return;
}
// Get a file handle for the upload data.
NSString *filename = [fileToUploadURL lastPathComponent];
NSString *mimeType = [self MIMETypeForFilename:filename
defaultMIMEType:#"video/mp4"];
GTLRUploadParameters *uploadParameters =
[GTLRUploadParameters uploadParametersWithFileURL:fileToUploadURL
MIMEType:mimeType];
uploadParameters.uploadLocationURL = locationURL;
GTLRYouTubeQuery_VideosInsert *query =
[GTLRYouTubeQuery_VideosInsert queryWithObject:video
part:#"snippet,status"
uploadParameters:uploadParameters];
query.executionParameters.uploadProgressBlock = ^(GTLRServiceTicket *ticket,
unsigned long long numberOfBytesRead,
unsigned long long dataLength) {
NSLog(#"upload progress");
};
GTLRYouTubeService *service = self.youTubeService;
_uploadFileTicket = [service executeQuery:query
completionHandler:^(GTLRServiceTicket *callbackTicket,
GTLRYouTube_Video *uploadedVideo,
NSError *callbackError) {
if (callbackError == nil) {
NSLog(#"uploaded");
} else {
NSLog(#"error %#",callbackError);
}
}];
}
- (NSString *)MIMETypeForFilename:(NSString *)filename
defaultMIMEType:(NSString *)defaultType {
NSString *result = defaultType;
NSString *extension = [filename pathExtension];
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
(__bridge CFStringRef)extension, NULL);
if (uti) {
CFStringRef cfMIMEType = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType);
if (cfMIMEType) {
result = CFBridgingRelease(cfMIMEType);
}
CFRelease(uti);
}
return result;
}
I obtain a 403 error in NSLog(#"error %#",callbackError); and i can't see error details because the are something like :
data=<7b226572 726f7222 3a7b2265 72726f72 73223a5b 7b22646f 6d61696e 223a2267 6c6f6261 6c222c22 72656173 6f6e223a 22696e73 75666669 ... 61676522 3a22496e 73756666 69636965 6e742050 65726d69 7373696f 6e227d7d>}
In google api console i have created a Client Oauth for my application bundle and an API key, i use those values for my connection, it seems they works correctly because i obtain a valid token. Anyway, there someone who can help me or point me in the right direction about this error? Or there someone who knows a working example about a video upload for IOS and not for MAC ? There something weird in my code? I can't find any help in documentation or google

How download file google drive api ios

I tried to download file from google drive API since 3 day without success. I used this https://developers.google.com/drive/ios/devguide/files#reading_files.
But I can't understand what I need to put in *drive and *file?
I tried :
GTLDriveFile *file = #"fileText.txt"; (or I tried the url of my file on google drive...) The guide don't explain... And I didn't find real example.
GTLServiceDrive *drive = ...;
GTLDriveFile *file = ...;
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/drive/v3/files/%#?alt=media",
file.identifier]
GTMSessionFetcher *fetcher = [drive.fetcherService fetcherWithURLString:url];
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
if (error == nil) {
NSLog(#"Retrieved file content");
// Do something with data
} else {
NSLog(#"An error occurred: %#", error);
}
}];
So I had search other code like but no one explain what I need to put in drive and file:
how to download file from google drive using objective c? (just this say it's url)
Google drive api download file for iOS
IOS: How to Download Google Docs files using ios google drive sdk API?
SOLUTION :
I had a problem of authorization with my scope, solved by total access to drive. I changed the scope (in quickstart code, look : "- (GTMOAuth2ViewControllerTouch *)createAuthController...")
-->NSArray *scopes = [NSArray arrayWithObjects:kGTLAuthScopeDrive, nil];
For download (inspired by quickstart example) :
// self.service is my GTLServiceDrive
// When the view appears, ensure that the Drive API service is authorized, and perform API calls.
- (void)viewDidAppear:(BOOL)animated {
if (!self.service.authorizer.canAuthorize) {
// Not yet authorized, request authorization by pushing the login UI onto the UI stack.
[self presentViewController:[self createAuthController] animated:YES completion:nil];
} else {
NSString *urltest = [NSString stringWithFormat:#"https://www.googleapis.com/drive/v3/files/%#?alt=media", identifier_file]; //the ID of my file in a string identifier_file
GTMSessionFetcher *fetcher = [self.service.fetcherService fetcherWithURLString:urltest]; // the request
// receive response and play it in web view:
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *errorrr) {
if (errorrr == nil) {
NSLog(#"Retrieved file content");
[webView_screen loadData:data MIMEType:#"application/pdf" textEncodingName:#"UTF-8" baseURL:nil]; //my file is a pdf
[webView_screen reload];
} else {
NSLog(#"An error occurred: %#", errorrr);
}
}];
}
}
If you want to save on the phone, you can look the Bala's code.
First fetch the file from Drive
driveFiles = [[NSMutableArray alloc] init];
for (GTLDriveFile *file in files.items) {
if ([file.mimeType isEqualToString:#"application/vnd.google-apps.folder"]) {
} else {
NSString *fileExtension = file.fileExtension;
if (fileExtension) {
if ([fileExtension isEqualToString:#"pdf"]) {
[driveFiles addObject:file];
}
}
}
}
And GTLDriveFile pass the object that you have in the array
GTLDriveFile *file=[driveFiles objectAtIndex:indexPath.row];
This is the code for download the file
NSString *link;
if (file.webContentLink) {
link = file.webContentLink;
} else if (file.embedLink) {
link = file.embedLink;
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"File has no downloadable link" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
if (link) {
NSString *downloadUrl = file.downloadUrl;
GTMHTTPFetcher *fetcher = [self.driveService.fetcherService fetcherWithURLString:downloadUrl];
//async call to download the file data
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
if (error == nil) {
if (data) {
NSString *dirPath = [self directoryPathForSavingFile];
NSString *filePath = [dirPath stringByAppendingPathComponent:file.title];
[self saveFileJSONData:data forFileName:filePath withCompletionHandler:^(BOOL successStatus) {
// Adding skip attribute to avoid data sinking in iCloud
BOOL path = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (path) {
NSLog(#"filePath %#", filePath);
}
}];
}
} else {
NSLog(#"An error occurred: %#", error);
}
}];
}
Code for Directory path for save the file
- (NSString *)directoryPathForSavingFile:(NSString *)directoryName {
NSString *applicationDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
applicationDirectory = [applicationDirectory stringByAppendingPathComponent:directoryName];
return applicationDirectory;
}

Return parent method from within block

Hi I'm new to using blocks in Objective-C
What I think I want is the following:
- (void) iNeedAToken {
NSString *token = [self theMethodThatShouldReturnTheToken];
}
- (NSString) theMethodThatShouldReturnTheToken {
[myAwesomeAsyncMethod success:^(id JSON) {
NSString *token = [JSON objectForKey:#"FOO"];
return token;
}]
}
Is this possible? Or is this the wrong logic all together?
Thanks!
You're mixing async with synchronous code. You're theMethodThatShouldReturnTheToken already returned (you're missing a return value) before the block passed to success finishes.
Best bet would be to continue your process from the success block.
- (void) tokenRequestContext1
{
[self requestToken:^(NSString *token) {
// do something with token
}];
}
- (void) requestToken:(void(^)(NSString *))tokenBlock
{
[myAwesomeAsyncMethod success:^(id JSON) {
NSString *token = [JSON objectForKey:#"FOO"];
if (tokenBlock) {
tokenBlock(token);
}
}];
}
You start by calling requestToken. This will start the async request for your token. Some time might pass, but eventually doSomethingWithToken will be called where you can use the received token.
There is a description of way to wait until complition block will be finished: http://omegadelta.net/2011/05/10/how-to-wait-for-ios-methods-with-completion-blocks-to-finish/
Regular version of this code is:
- (void) iNeedAToken {
[self theMethodThatShouldReturnTheToken:^(id res){ token = res;}];
NSString *token = [self theMethodThatShouldReturnTheToken];
}
- (void) theMethodThatShouldReturnTheToken:(void (^)(id res)result) {
[myAwesomeAsyncMethod success:^(id JSON) {
NSString *token = [JSON objectForKey:#"FOO"];
result(token);
}]
}

iOS GData YouTube comment on a Video

There are a lot of GData YouTube tutorials on how to upload a Video in an iOS App, but I didn't find one showing how to comment on a Video. So I read on the reference-page, just tried and so on but didn't find anything!
Does anyone know how to comment on a Video in an iOS App using the GData API?
Thanks
Use this methods in comment button
GDataEntryYouTubeVideo *video = (GDataEntryYouTubeVideo *)arrayData;
[self addCommentTitle:#"comment" text:commentField.text toVideo:video];
- (void)addCommentTitle:(NSString *)commentTitle
text:(NSString *)commentContent
toVideo:(GDataEntryYouTubeVideo *)entry {
GDataComment *commentObj = [entry comment];
GDataFeedLink *feedLink = [commentObj feedLink];
NSURL *feedURL = [feedLink URL];
if (feedURL) {
// fetch the comment feed for the video
GDataServiceGoogleYouTube *service = [self youTubeService];
[service setYouTubeDeveloperKey:devKey];
[service setAuthToken:[self getRequestToken]];
[service fetchFeedWithURL:feedURL completionHandler:^(GDataServiceTicket *ticket, GDataFeedBase *commentFeed,NSError *error) {
if (error == nil) {
GDataEntryYouTubeComment *newCommentEntry = [GDataEntryYouTubeComment commentEntry];
[newCommentEntry addContentValueDeclaration];
[newCommentEntry setTitleWithString:commentTitle];
[newCommentEntry setContentWithString:commentContent];
NSString *subString = [videoString substringWithRange: NSMakeRange(0, [videoString rangeOfString: #"?"].location)];
NSString *last=[subString lastPathComponent];
NSString *ss=#"http://gdata.youtube.com/feeds/api/videos/";
NSString *idd=#"/comments";
NSString *com=[NSString stringWithFormat:#"%#%#%#",ss,last,idd];
NSURL *postURL = [NSURL URLWithString:com ];
[service fetchEntryByInsertingEntry:newCommentEntry
forFeedURL:postURL
completionHandler:^(GDataServiceTicket *ticket, GDataEntryBase *entry, NSError *error) {
// callback
if (error == nil) {
NSLog(#"url.: succeeded ");
}
}];
}
}];
}
}
get Authentication token using login details
- (NSString*) getRequestToken {
// return your auth token as string
}

Clean (remove) a database in MagicalRecord

I have an app that is using MagicalRecord for its Core Data handling and this works nice. However I have different users that can login in the app and when another user logs in, the core data database must be emptied so that the different user can have his own data. The database can be emptied completely as the data is also stored on a webservice and therefore can always be synced again after logging in again the first user.
So far I cannot seem to find a helper method (that works) for this purpose. I have tried
[MagicalRecord cleanUp];
whenever the user is logging out, but this does not do the trick.
This is how I did it. It is essential to have this line: [MagicalRecord cleanup]. Without it, [self setupDB] won't work.
UPDATE: Deletes the -wal and -shm files. #thattyson pointed out an issue in iOS 9. Also, see the answer of #onmyway133.
- (void)setupDB
{
[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:[self dbStore]];
}
- (NSString *)dbStore
{
NSString *bundleID = (NSString *)[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleIdentifierKey];
return [NSString stringWithFormat:#"%#.sqlite", bundleID];
}
- (void)cleanAndResetupDB
{
NSString *dbStore = [self dbStore];
NSError *error1 = nil;
NSError *error2 = nil;
NSError *error3 = nil;
NSURL *storeURL = [NSPersistentStore MR_urlForStoreName:dbStore];
NSURL *walURL = [[storeURL URLByDeletingPathExtension] URLByAppendingPathExtension:#"sqlite-wal"];
NSURL *shmURL = [[storeURL URLByDeletingPathExtension] URLByAppendingPathExtension:#"sqlite-shm"];
[MagicalRecord cleanUp];
if([[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error1] && [[NSFileManager defaultManager] removeItemAtURL:walURL error:&error2] && [[NSFileManager defaultManager] removeItemAtURL:shmURL error:&error3]){
[self setupDB];
}
else{
NSLog(#"An error has occurred while deleting %#", dbStore);
NSLog(#"Error1 description: %#", error1.description);
NSLog(#"Error2 description: %#", error2.description);
NSLog(#"Error3 description: %#", error3.description);
}
}
Here's the Swift version:
func setupDB() {
MagicalRecord.setupCoreDataStackWithAutoMigratingSqliteStoreNamed(self.dbStore())
}
func dbStore() -> String {
return "\(self.bundleID()).sqlite"
}
func bundleID() -> String {
return NSBundle.mainBundle().bundleIdentifier!
}
func cleanAndResetupDB() {
let dbStore = self.dbStore()
let url = NSPersistentStore.MR_urlForStoreName(dbStore)
let walURL = url.URLByDeletingPathExtension?.URLByAppendingPathExtension("sqlite-wal")
let shmURL = url.URLByDeletingPathExtension?.URLByAppendingPathExtension("sqlite-shm")
var removeError: NSError?
MagicalRecord.cleanUp()
//Swift 1
//let deleteSuccess = NSFileManager.defaultManager().removeItemAtURL(url, error: &removeError)
//Swift 2
let deleteSuccess: Bool
do {
try NSFileManager.defaultManager().removeItemAtURL(url)
try NSFileManager.defaultManager().removeItemAtURL(walURL!)
try NSFileManager.defaultManager().removeItemAtURL(shmURL!)
deleteSuccess = true
} catch let error as NSError {
removeError = error
deleteSuccess = false
}
if deleteSuccess {
self.setupDB()
} else {
println("An error has occured while deleting \(dbStore)")
println("Error description: \(removeError?.description)")
}
}
To expand on #yoninja 's answer, this will make reset CoreData stack explicitly, plus dealing with wal and shm files
- (void)setupDB
{
[MagicalRecord setDefaultModelNamed:#"Model.momd"];
[MagicalRecord setupCoreDataStack];
}
- (void)cleanAndResetupDB
{
[MagicalRecord cleanUp];
NSString *dbStore = [MagicalRecord defaultStoreName];
NSURL *storeURL = [NSPersistentStore MR_urlForStoreName:dbStore];
NSURL *walURL = [[storeURL URLByDeletingPathExtension] URLByAppendingPathExtension:#"sqlite-wal"];
NSURL *shmURL = [[storeURL URLByDeletingPathExtension] URLByAppendingPathExtension:#"sqlite-shm"];
NSError *error = nil;
BOOL result = YES;
for (NSURL *url in #[storeURL, walURL, shmURL]) {
if ([[NSFileManager defaultManager] fileExistsAtPath:url.path]) {
result = [[NSFileManager defaultManager] removeItemAtURL:url error:&error];
}
}
if (result) {
[self setupDB];
} else {
NSLog(#"An error has occurred while deleting %# error %#", dbStore, error);
}
}
MagicalRecord does not provide this functionality for you. The cleanUp method is provided for you to reinitialize your CoreData stack in memory and cleaning up any contexts, queues and other related objects. However, it is not that difficult to do yourself given that MagicalRecord does provide a handy method to get the path for your library.
Check out the -[NSPersistentStore MR_urlForStoreName:] method. This will give you the file url for your store. You can then delete it with an NSFileManager instance. Be careful to do this before you set up the Core Data stack or you'll crash when you save because you'd have yanked out the store from under a properly initialized stack.
The following will completely delete the MagicalRecord CoreData sqlite files, as well as the -wal and -shm files. MagicalRecord puts them all in the Library folder; this will simply remove all files from the folder. This will not work if you have other data you need to persist in the Library folder, I did not:
- (void)resetCoreDataDB
{
[MagicalRecord cleanUp];
[self deleteFilesInLibrary];
[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:#"YourDBName.sqlite"];
}
- (void)deleteFilesInLibraryDirectory
{
NSString* folderPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSError *error = nil;
for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:&error])
{
[[NSFileManager defaultManager] removeItemAtPath:[folderPath stringByAppendingPathComponent:file] error:&error];
if(error)
{
NSLog(#"Delete error: %#", error.description);
}
}
}
If you are using the iOS Simulator and deleted the database file, you may probably notice that the data is still there. However, if tested on an actual device (which should be), the file is deleted and the context is reset as should be.
[MagicalRecord cleanUp];
// delete database file
NSError *error;
NSURL *fileURL = [NSPersistentStore MR_urlForStoreName:#"db.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error];
if(error) {
// Hanldle error
}
// reset setup.
[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:#"db.sqlite"];
A bit rewritten answer of #yoninja for Swift 4:
private var dbStore : String? {
get {
if let bundleId = Bundle.main.bundleIdentifier {
return bundleId + ".sqlite"
}
return MagicalRecord.defaultStoreName()
}
}
func setupCoreDataStack() {
MagicalRecord.setupCoreDataStack(withAutoMigratingSqliteStoreNamed: self.dbStore)
}
func cleanUp() {
MagicalRecord.cleanUp()
var removeError: NSError?
let deleteSuccess: Bool
do {
guard let url = NSPersistentStore.mr_url(forStoreName: self.dbStore) else {
return
}
let walUrl = url.deletingPathExtension().appendingPathExtension("sqlite-wal")
let shmUrl = url.deletingPathExtension().appendingPathExtension("sqlite-shm")
try FileManager.default.removeItem(at: url)
try FileManager.default.removeItem(at: walUrl)
try FileManager.default.removeItem(at: shmUrl)
deleteSuccess = true
} catch let error as NSError {
removeError = error
deleteSuccess = false
}
if deleteSuccess {
self.setupCoreDataStack()
} else {
print("An error has occured while deleting \(self.dbStore)")
print("Error description: \(removeError.debugDescription)")
}
}

Resources