WKRefreshBackgroundTask cleanupStorage Error attempting to reach file - swift

Whats this error I get when making a URLBGTask in WatchOS4 on the Simulator?
2017-09-28 16:05:26.452999+0900 MiFollowers WatchKit Extension[4628:4012814] [bg_app_refresh] -[WKRefreshBackgroundTask cleanupStorage]_block_invoke:213: Error attempting to reach file:///Users/ryuuzaki/Library/Developer/CoreSimulator/Devices/2E4D6389-93B7-4542-B07F-9A02C720B9AF/data/Containers/Data/PluginKitPlugin/FA4415DF-D984-4394-80B9-EDA199AB587E/Library/com.apple.watchkit/bktaskapp_(null): Error Domain=NSCocoaErrorDomain Code=260 "The file “bktaskapp_(null)” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///Users/ryuuzaki/Library/Developer/CoreSimulator/Devices/2E4D6389-93B7-4542-B07F-9A02C720B9AF/data/Containers/Data/PluginKitPlugin/FA4415DF-D984-4394-80B9-EDA199AB587E/Library/com.apple.watchkit/bktaskapp_(null), NSFilePath=/Users/ryuuzaki/Library/Developer/CoreSimulator/Devices/2E4D6389-93B7-4542-B07F-9A02C720B9AF/data/Containers/Data/PluginKitPlugin/FA4415DF-D984-4394-80B9-EDA199AB587E/Library/com.apple.watchkit/bktaskapp_(null), NSUnderlyingError=0x79b0e340 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Any of you bright minds out there know what all this means?

I was getting this too. Drove me nuts for the last two days.
I'm still not sure if it is a bug or "feature" to require you to use the userInfo property. This is happening if you don't get the userInfo property from the background refresh task in the handle(_ backgroundTasks) method. Any access of the property works. A simple workaround one to get rid of the error is to schedule your next background refresh in the handle method with backgroundTask.userInfo in the userInfo: parameter which just keeps assigning nil to the next task.
WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: refreshDate, userInfo: backgroundTask.userInfo) { (error) in
if let error = error {
print ("Background task error:\(error.localizedDescription)")
}
}
Of course this workaround means you won't be able to use userInfo. Better code might be to stick something in there such as the scheduling date or an identifier for the task, or a dictionary of [String:Any] for both.

Related

Unintelligible Error of CloudKit Failing to delete Asset File

So, I'm building a simple diary app in which the diary pages are saved in Core Data and synced with CloudKit. I have a lot of database operations, which I do asynchronously in the background. For example, when the user writes an entry, I save the diary page every 5 seconds or when the user adds an image to it.
I do not touch anything with CloudKit rather than using an NSPersistentCloudKitContainerand these lines:
cloudKitContainer.automaticallyMergesChangesFromParent = true
guard let containerId = cloudKitContainer.containerIdentifier,
let description = container.persistentStoreDescriptions.first else {
print(#function, "Could not initalizeCloudKitScheme.")
return
}
let options = NSPersistentCloudKitContainerOptions(containerIdentifier: containerId)
description.cloudKitContainerOptions = options
When saving and deleting diary pages I get the following error. The error occurs especially when adding and deleting images, I guess due to their size:
PFCloudKitExporter exportOperationFinished:withSavedRecords:deletedRecordIDs:operationError:]_block_invoke(492): Failed to delete asset file: file:///var/mobile/Containers/Data/Application/D62B434E-A968-423B-8408-9461A97DA8D1/Library/Application%20Support/ckAssetFiles/3F783A57-2038-45E8-8D93-1DD0A7EBD89F.fxd
Error Domain=NSCocoaErrorDomain Code=4 "“3F783A57-2038-45E8-8D93-1DD0A7EBD89F.fxd” couldn’t be removed." UserInfo={NSUserStringVariant=(
Remove
), NSFilePath=/var/mobile/Containers/Data/Application/D62B434E-A968-423B-8408-9461A97DA8D1/Library/Application Support/ckAssetFiles/3F783A57-2038-45E8-8D93-1DD0A7EBD89F.fxd, NSUnderlyingError=0x281995e90 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Can anyone explain how this error can occur, if I am only doing basic operations on my dataset?

Getting the stack trace of the error origin in swift

Consider this code:
func doSomething() throws {
try callThrowingFunction1()
try callThrowingFunction2()
}
func userAction() {
do {
try doSomething()
} catch {
// display and log error
}
}
Say those inner functions can throw the same kind of errors and I would like to know if an error occurred in callThrowingFunction1() or in callThrowingFunction2().
As long as I'm in the debugger I can set a breakpoint for Swift errors on swift_willThrow, but if I would like to log the call stack on a user device, is there a way to do that?
Swift errors have no such thing as stack-trace yet (if will ever), and even Xcode can show stack-trace only if the error is un-handled by our code (and gets caught by Xcode directly instead).
Alternativly, your custom Error's constructor can store the stack-trace for later use, but in most cases errors are not custom, where you can't alter error's constructor (like errors of 3rd-party library).
But we can at least print stack-trace of where error(s) get catched, like:
do {
try ... // something that throws goes here
} catch let error as NSError {
print("Error: \(error)")
println(NSThread.callStackSymbols())
}
Exception breakpoint
If you just want to debug, without need to upload stack-trace to server, then Xcode's "Exception breakpoint" feature can help, like:
First place a normal-breakpoint near the failing logic.
Wait until Xcode pauses App on that line, enable Xcode's feature:
Finally, resume App, and wait untill exception is thrown.
Images are old, nowadays you see "Add Swift Error Breakpoint" or something like that as well (beside "Add Exception Breakpoint" option).

Find what errors a function can throw in Xcode with Swift [duplicate]

With Swift now some functions are marked with throws, and this force the developers to call the function inside a do - try catch block.
But how the developer can know the list of different exceptions thrown by that function?
As reference, here is a line of Java code:
static void employeeAge(int age) throws MyExceptionA,MyExceptionB
Here is clear that the exceptions are 2 MyExceptionA and MyExceptionB and the developer can decide to act differently depends of the error.
Can we achieve the same on Swift?
When the Swift docs says a function throws, they mean that it throws an ErrorType (in Cocoa APIs usually an NSError), not an exception.
Consider the following do-try-catch flow for NSFileManager's createDirectoryAtPath:
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
do {
try NSFileManager.defaultManager().createDirectoryAtPath(documentsPath, withIntermediateDirectories: false, attributes: nil)
} catch {
// 'error' variable automatically populated
print(error)
print(error.dynamicType)
}
createDirectoryAtPath will fail because the documents directory already exists. Logging the dynamicType of the error shows that it is in fact an NSError object:
Error Domain=NSCocoaErrorDomain Code=516 "The file “Documents” couldn’t be saved in the folder “35B0B3BF-D502-4BA0-A991-D07568AB87C6” because a file with the same name already exists." UserInfo={NSFilePath=/Users/jal/Library/Developer/CoreSimulator/Devices/E8A35774-C9B7-42F0-93F1-8103FBBC7118/data/Containers/Data/Application/35B0B3BF-D502-4BA0-A991-D07568AB87C6/Documents, NSUnderlyingError=0x7fa88bd14410 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}}
NSError
In order to see the different types of errors a function can throw, you would have to examine the error for information to determine the type of error thrown, and how to handle each error. In the case of NSError this would be its domain, code, and description.
In this particular case, a directory already exists at that path, so the file manager cannot create a new directory. An example of another reason why this operation could fail would be if the file manager did not have write access. That would be error code 256.
I had the exact same question as the OP. Since no one really answered the question as he asked (and I as well), here goes my contribution.
In Swift 3 and Xcode 8.3.3 you would do as follows to treat the individual exceptions. Below I will give you an example with FileManager.
First you will have only one catch block to catch whatever error the method throws at you. Then you will cast that error as an NSError. Contrary to the Error protocol in Swift, NSError is a REAL error class. Then you can extract that error's code in a switch statement. You will have to know what domain that method throws error from and then find the error codes in the appropriate header file.
In my example below, the file related errors are thrown in the NSCocoaErrorDomain and these errors codes are defined/listed in Foundation/FoundationErrors.h. In my computer, they are located at
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/FoundationErrors.h
for macOS apps and at
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/
for iPhone apps.
So here is an example:
let home = FileManager.default.homeDirectoryForCurrentUser
let file = home.appendingPathComponent("file")
do {
let loadedString = try String(contentsOf: file)
}
catch {
let realError = error as NSError // As weird as it looks, Xcode actually wants this forced conversion
print(realError.localizedDescription)
switch realError.code {
case 257: // No permission
handleNoPermission()
case 260: // File not found
handleFileNotFound()
default:
handleUndefinedError()
}
}
The .localizedDescription contains a user friendly message in your user's language about that error. If file is not found above it prints: The file “file” couldn’t be opened because there is no such file. in English. It is meant to be used directly in the error dialogs you present to your user.
You may also find more information about what error is thrown by each domain here: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html
You write a pattern after catch to indicate what errors that clause can handle.
do {
try expression
statements
} catch pattern 1 {
statements
} catch pattern 2 where condition {
statements
}
See section Handling Errors Using Do-Catch of Swift Programming Language

(os/kern) invalid capability (20) invalid name(15) - I cant seem to get rid of these errors

First let me say I have researched this topic and looked through the following link and it did not help
Link 1
I tired un-checking elements in the Attributes Inspector (as described in link1) .
I also tried adding the code to the .plist file as described in LINK 2 and it did not help.
Where I seem to be getting the error is when i execute the following sequence of events using a button to start it:
user presses a button
alert pops up to ask the user if they wish to proceed
if yes a button now becomes un-hidden to allow the user to send data to my domain
once the new button is pressed I use a fetch to get a bunch of core data and then send it to my domain using an NSString(data: data!, encoding: NSUTF8StringEncoding)! call
right after all the data is sent to my domain I get the following error every time:
_BSMachError: (os/kern) invalid capability (20)
_BSMachError: (os/kern) invalid name (15)
It does successfully send the data but the error stays... PLEASE HELP
I was getting this error executing not long run operations but some operations that take long on handler blocks of UIAlertActions. I solved by putting operations in a background thread with:
NSOperationQueue().addOperationWithBlock {
// Operations Here.
}
Accessing the core data can take longer then you think and accessing it from button handler can make that error appear because some handlers have limited amount of time to respond.
For me this error occurred when I tried to set the button title to an optional string:
self.titleButton.setTitle(self.playlistItem?.title, for: UIControlState())
The error messages do not occur when changed to this:
self.titleButton.setTitle(self.playlistItem!.title, for: UIControlState())
Feel free to post relevant code in your question.
Hope this helps...

AVAudioPlayer initialization: error code -50

I recently ran into a problem that I couldn't find discussed anywhere on the internet - I was initializing an AVAudioPlayer to play an audio file, and getting the following error:
Error Domain=NSOSStatusErrorDomain Code=-50 "Operation could not be completed. (OSStatus error -50.)
As it turns out, I had made a mistake creating my NSURL to send to the audio player init method, resulting in the NSURL object being null. Stupid mistake, pretty easy to find when debugging, but I thought I'd list it here just in case someone else does the same thing.
“ OSStatus error -50” means paramErr, an old-style Mac error code indicating a bad parameter.
Regarding the comment from Brynjar:
The Apple NSURL Class Reference describing URLWithString states
To create NSURL objects for file system paths, use
fileURLWithPath:isDirectory: instead.
I have found that using URLWithString for file system paths generates the error reported by pix0r and therefore could be another explanation for error code = -50
Make sure your NSURL is valid, or you will get error code -50 "Operation could not be completed".
I'm adding my version of the issue and solution because I encountered the error with a print statement. I think it was related to string interpolation and or trying to forcibly print nsattributedstrings. I attempted to do the following.
print("THE ARRAY COUNT IS : \(unwrappedResults.count)\n\n\n
THE FULL ARRAY IS THE FIRST WHOLE RESULT IS: \(unwrappedResults)\n\n\n \ (unwrappedResults[0])\n
THE ATTRIBUTED FULL TEXT IS: \(unwrappedResults[0].attributedFullText)\n\n\n
THE ATTRIBUTED PRIMARY TEXT IS: \(unwrappedResults[0].attributedPrimaryText)\n\n\n
THE ATTRIBUTED SECONDARY TEXT IS: \(unwrappedResults[0].attributedSecondaryText)\n\n\n")
something about this was incorrect and no print would occur. I would receive the error following errors in my console.
boringssl_metrics_log_metric_block_invoke(131) Failed to log metrics
&
boringssl_metrics_log_metric_block_invoke(133) Error Domain=NSOSStatusErrorDomain Code=-50 "Unsupported xpc type"
UserInfo={NSDescription=Unsupported xpc type}
I fixed this issue by changing the way I unwrapped/the variables values. Fundamentally I think I was trying to print something using string interpolation that could not be printed and that is what caused this error.