Reputation: 8905
I am using WatchConnectivity to transfer an image from iOS to Watch OS. When debugging in simulator I am facing a problem
The file is transferred successfully as I can see in (sender side i.e. iOS)
public func session(session: WCSession, didFinishFileTransfer fileTransfer: WCSessionFileTransfer, error: NSError?)
Now from XCode I stop iOS simulator, change target to Watch App, Ctrl+Run Watch App (just run, no build).The below method is called.
public func session(session: WCSession, didReceiveFile file: WCSessionFile)
At last I do
NSFileManager.defaultManager().moveItemAtURL(file.fileURL, toURL: destinationFileURL)
This call throws because there is no file at file.fileURL (which I checked in my MAC also).
The file.fileURL.path! is like this
/Users/<user name>/Library/Developer/CoreSimulator/Devices/DAD8E150-BAA7-43E0-BBDD-58FB0AA74E80/data/Containers/Data/PluginKitPlugin/2CB3D46B-DDB5-480C-ACF4-E529EFBA2657/Documents/Inbox/com.apple.watchconnectivity/979DC929-E1BA-4C24-8140-462EC0B0655C/Files/EC57EBB8-827E-487E-8F5A-A07BE80B3269/image
Any clues?
Upvotes: 2
Views: 2706
Reputation: 1647
As the Apple documentation of WCSessionDelegate Protocol Reference says regarding
- (void)session:(WCSession *)session didReceiveFile:(WCSessionFile *)file
when getting back the (WCSessionFile *)file parameter:
The object containing the URL of the file and any additional information. If you want to keep the file referenced by this parameter, you must move it synchronously to a new location during your implementation of this method. If you do not move the file, the system deletes it after this method returns.
So the best to move it ASAP to a new location. It's safe as the system keeps the reference and doesn't delete it during the move.
- (void)session:(WCSession *)session didReceiveFile:(WCSessionFile *)file {
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *cacheDir = [[NSHomeDirectory() stringByAppendingPathComponent:@"Library"] stringByAppendingPathComponent:@"Caches"];
NSURL *cacheDirURL = [NSURL fileURLWithPath:cacheDir];
if ([fileManager moveItemAtURL: file.fileURL toURL:cacheDirURL error: &error]) {
//Store reference to the new URL or do whatever you'd like to do with the file
NSData *data = [NSData dataWithContentsOfURL:cacheDirURL];
}
else {
//Handle the error
}
}
WARNING! You have to be careful with the thread handling as delegates of WCSession run in the background queue so you have to switch to main queue if you'd like to work with UI.
Upvotes: -2
Reputation: 8905
I found the problem. I was dispatching some code to main thread and the file move code was also inside that. WC framework clean up the file just after this method ends so the file must be moved before this function returns. I moved that code outside performInMainThread block and everything is working like charm.
public func session(session: WCSession, didReceiveFile file: WCSessionFile)
{
// Move file here
performInMainThread { () -> Void in
// Not here
}
}
Upvotes: 8