Here is the report about Trouble to save into Photo Library when running on Silicon Mac with SwiftUI iOS code as iPad-mode.
Is this a disability or am I making a mistake? Please tell me.
Environment of making App and excution
Xcode 14.2
MacOS Monterey 12.6.2, 12.6.3 on SiliconMac, iMac24
About troubled issue
My iOS App that was previously working well, some day returns an error on save to Photo Library, even though nothing has changed in the saving code.
And this problem only occurs on SiliconMac with iPad-mode. No problem with other iOS devices, iPhone, iPad.
’Some day’ mean i don’t know why, may be updating of Xcode or MacOS else.
Sample code for Saving image into PhotoLibrary
Sample code and error return is below. SiliconMac always returns UNKNOWN error.
<br> Fail occurs at 'UImageWriteToSavedPhotosAlbum'
class ImageSaver: NSObject {
func writeToPhotoAlbum(image: UIImage) {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveCheck), nil)
}
#objc func saveCheck(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
print(error)
print("Save NG")
} else {
print("Save OK")
}
}
}
Result of print(error):
Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x600002146490 {Error Domain=PHPhotosErrorDomain Code=3311 "(null)"}}
In the actual Error-string, "Unknown error" is "原因不明のエラー", because of my MacOS is in Japanese.
Confirmation
Anyway, this code works fine on iPhone, iPad, and it used to work on SiliconMac. For some reason, I am getting the error only on SiliconMac, even though there is no change in the code at all.
Already Setted Keys, Yes:
Privacy - Photo Library Usage Description
Privacy - Photo Library Additions Usage Description
Additional trials
I have tried in a different environment:
<br>Downgraded and tried again with 14.0.1, but same result.
<br>Update MacOS Monterey to Ventura 13.2.1, but same result.
Other pattern-1:
Xcode 14.0.1
MacOS Monterey 12.6.2, 12.6.3 on SiliconMac, iMac24
Other pattern-2:
Xcode 14.2
MacOS Ventura 13.2.1 on SiliconMac, iMac24
Related
This is my first WatchKit App.
I am working on an app that gets an API call to an iCal file and displays the time remaining in two events.
I am working on Xcode 13.4.1 and created an iOS app with watchOS app using swift and storyboard. I set the target deployment for the iOS app to 15.5, which is the highest version of iOS that my current version of Xcode will let me set. The target deployment for the watchOS app is set to version 6.2 because I have an Apple Watch series 2, and the latest version of watchOS is 6.3. I want the app to at least work for my watch. The code for the iOS app and watch app are pretty much the same. The app works as expected on the watch and phone simulators and on my physical iPhone 8 plus. The problem is that the app does not work on my physical watch.
I created a custom class called API_Manager that handles the API call. I handle my API call as a giant string because I am getting an iCal file and parse it later on in the class. url is defined above. Here is my API call for both the phone and watch app:
public func getData() throws{
//api call
do{
// real url is defined above
let url:String = ""
savedData = try String(contentsOf: URL(string: url)!)
} catch{
print("there was an error with the api call")
throw API_Error.apiCallError
}
// parsing data
}
getData() is called in the init function of the API_Manager class.
init() throws {
// checking internet connection
if (!NetworkMonitor.shared.isConnected){
throw API_Error.noInternet
}
do{
try getData()
} catch{
throw API_Error.apiCallError
}
}
I believe the root of the problem is an Internet connection. I check for an Internet connection before the API call, and if there is no Internet connection, then I throw a custom error. I used this video to create a Network_Monitor class. This is the startMonitoring() function which is called in the applicationDidFinishLaunching() in extensionDelegate of the watch app and application didFinishLaunchingWithOptions in the appDelegate.
public func startMonitoring(){
monitor.start(queue: queue)
monitor.pathUpdateHandler = { [weak self] path in
self?.isConnected = path.status == .satisfied
// getting connection type
self?.getConnectionType(path)
}
}
I created a custom error that is thrown throughout the API_Manager if things don't work as expected. Here is how I created the custom errors:
enum API_Error: Error{
case noInternet
case apiCallError
}
extension API_Error: CustomStringConvertible{
public var description:String {
switch self{
case .noInternet:
return "Error: No internet connection"
case .apiCallError:
return "There was an error with the api call"
}
}
}
I created another enum that is used to display text on a label in the Interface Controller if a specific error is thrown.
enum API_Manager_Status{
case active
case noInternet
case apiCallError
case null // if the api manager is nill
}
Here is how I used the two enums in InterfaceController:
main() is called in the awake() function.
func main(){
do{
apiManager = try API_Manager()
apiManagerStatus = .active
} catch API_Error.noInternet{
apiManagerStatus = .noInternet
} catch API_Error.apiCallError{
apiManagerStatus = .apiCallError
} catch{
apiManagerStatus = .null
}
if (apiManagerStatus == .noInternet){
periodLabel.setText("Error")
timeRemaining.setText("No Internet")
print(API_Error.noInternet)
} else if (apiManagerStatus == .apiCallError){
periodLabel.setText("Error")
timeRemaining.setText("API Call")
print(API_Error.apiCallError)
} else if (apiManagerStatus == .null){
periodLabel.setText("Error")
timeRemaining.setText("Other Error")
print("Cought all errors")
} else{
// main code to display time remaining
}
So I guess my questions are:
Why is my Apple Watch not getting an Internet connection?
How can I fix my app if it worked on the simulators and iPhone, but not watch?
Can the Apple Watch do an API call?
Do I need to configure my app to connect with the iPhone, given that my watchOS verison is 6.2?
Sorry if this is a long question. This is my first time posting a question on Stack Overflow. I would appreciate any help. Let me know if I need to add any more information to help clear things up.
I have tried many potential solutions to fix the problem, but none have worked:
I distributed the app on Test Flight and had my dad download it. He has an Apple Watch Series 4 running on watchOS 9.2, and the app still does not work on his watch.
I have restarted my phone and watch multiple times and even tried to run the app with my phone off, so the watch could connect to wifi.
I tried to install a watchOS 9 beta profile on my watch, knowing it would not work, but I still wanted to see what would happen.
I tried setting the build target to watchOS 8.5, which is the highest my version of Xcode would allow, to see if the problem was watchOS 6.2, and if it would work on my dad's watch.
Lastly, I tried adding privacy messages in the Info.plist for both the phone and the watch app. The messages did not display when I re-downloaded the app, but it still did not fix the issue.
(the messages I used were: "Privacy - Nearby Interaction Usage Description" which does not work on watchOS 6.2, but I still kept in the info.plist, and "Privacy - Bluetooth Always Usage Description")
I know Apple Watches are supposed to use the connected phone for Internet and then wifi if a phone is not connected. My watch shows that my phone is connected, and I have tried it with just wifi. I believe my watch can still get an Internet connection because I can still use Siri and even go to the App Store on my watch, which needs an Internet connection. I would appreciate any help. Let me know if I need to add any more information to help clear things up.
FaceID allows storage of credentials but not retrival. I'm seeing this error when inspecting via the xcode console. If I run the same code from xcode locally everything works fine.
returned Error Domain=com.apple.LocalAuthentication Code=-1004 "Caller is not running foreground."
To make it even more strange if I install a different version from testflight and then reinstall the original broken version it starts working again.
We've encountered this error as well in our app, but as it turned out, it was caused by having multiple apps with the same Product Name on one device.
In our case this means that we will not have this on our live app, but this came up on devices of our tester.
This error always comes up for me as -1004 so I added a check to my error handling block like this:
...
if let error = authError as? LAError {
if (error.code.rawValue == -1004) { //bizarre facial recognition error
completion(true, //do some code..)
}
completion(false, error)
}...
works on my production application
I downloaded a sample project from here(haptic sampler) and I cannot run because of several issues.
I solved signing identifier.
The error messages say:
~/PlayingACustomHapticPatternFromAFile/HapticSampler/ViewController.swift:66:19: Type 'CHHapticEngine.StoppedReason' has no member 'gameControllerDisconnect'
~/PlayingACustomHapticPatternFromAFile/HapticSampler/ViewController.swift:68:19: Type 'CHHapticEngine.StoppedReason' has no member 'engineDestroyed'
if I delete these parts, another error says:
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Here are my questions.
Do same issues happen to you?
How can I fix this problem?
Here's my environment specification.
macOS Catalina 10.15.6
Xcode 11.6
iPhone 7 iOS 13.6
Haptic feedback needs an actual device since it uses a vibration motor. It can not be run on a simulator. That is why you are getting the error message "Failed to create engine!". To fix it connect to an actual device and select a team in "Signing & Capabilities" and run.
The problem is that the enum cases
.gameControllerDisconnect
And
.engineDestroyed
Were introduced in iOS 14, Xcode 12 beta. But you are running an earlier version so, as the error message says, they don’t exist.
Replace the following lines of ViewController.swift Line 48 in the createEngine() function.
if engine == nil {
print("Failed to create engine!")
}
With:
guard let engine = engine else {
print("Failed to create engine!")
return
}
That should resolve the compile + runtime errors you're currently getting
I have a very strange problem with UIDocumentBrowserViewController when testing on iOS 13. The importHandler(newDocumentURL, .move) seems to crash without any reason :
[DocumentManager] Cannot create urlWrapper for url file:///.../tmp/23720D22-BC1D-4E7B-A7AE-A1C8B0293F9E.txt.
error Error Domain=NSPOSIXErrorDomain Code=22 "couldn't issue sandbox extension com.apple.app-sandbox.read-write for '/.../tmp/23720D22-BC1D-4E7B-A7AE-A1C8B0293F9E.txt':
Invalid argument" UserInfo={NSDescription=couldn't issue sandbox extension com.apple.app-sandbox.read-write for '/.../tmp/23720D22-BC1D-4E7B-A7AE-A1C8B0293F9E.txt': Invalid argument}.
Here is a two step process to reproduce :
Create a new Xcode project "Document Based App"
Type in this code in the documentBrowser(_: , didRequestDocumentCreationWithHandler:)
let newDocumentURL: URL? =
URL(fileURLWithPath: NSTemporaryDirectory())
.appendingPathComponent(UUID().uuidString)
.appendingPathExtension("txt")
// Set the URL for the new document here. Optionally, you can present a template chooser before calling the importHandler.
// Make sure the importHandler is always called, even if the user cancels the creation request.
if newDocumentURL != nil {
print(newDocumentURL!)
try! "My file content".write(to: newDocumentURL!, atomically: true, encoding: .utf8)
importHandler(newDocumentURL, .move)
} else {
importHandler(nil, .none)
}
Launch it on an iOS 13 simulator, create a new document, and the error is printed out and nothing else happens.
If you execute the same code on iOS 12, it perfectly works, the file is moved and is opened by the app.
The problem occurs on iOS 13 beta 7, wether it's compiled by Xcode 11 beta 7 or Xcode 10.3
Any idea?
EDIT: The problem still occurs when you create the file in the document directory instead of the temporary directory :
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
EDIT 2: The problem still exists with Xcode 11 GM (11A419c)
EDIT 3: The problem persists only the simulator. On device with iOS 13 GM, UIDocumentBrowserViewController works as expected.
EDIT 4: Problem still present on simulators with official Xcode 11 release 11A420a (aka GM Seed 2.)
EDIT 5: Problem only occurs on Mojave and seems to be absent on Catalina
I've verified that the bug exists with Xcode 11.1 GM running on Mac OS Mojave.
The issue does not occur when running on Catalina Beta 9. (FWIW I ran Catalina Beta 9 in a Parallels virtual machine because I don't know if it is stable enough to upgrade to for production work.)
Looking for workarounds, will post if I find any (but note this is not my area of expertise, just proceeded on a hunch that turned out to be correct.)
You may want to update the Radar you filed to indicate that this is probably specific to Mojave.
This is as straightforward as is sounds; when I try to use session.transferCurrentComplicationUserInfo(_:), I get the error message written in the title, word for word.
Looking at the documentation (transferCurrentComplicationUserInfo, WCSession) there's no indication that it's been deprecated... plus, if something is deprecated it says so in the error message and will still show up in Xcode's intellisense (albeight with strikethrough). For me, neither is happening.
So why Xcode saying it's unavailable?
This is my barebones code that causes the error message:
let userInfo: [String:Any] = [:]
let _ = session?.transferCurrentComplicationUserInfo(userInfo)
For some background, I'm using Xcode 10.1 and Swift 4.2. My app's deployment target is iOS 9.3 and my watch extension's is watchOS 4.0.
Probably, you are trying to call it from the Watch Extension, where it appears as unavailable.
The function transferCurrentComplicationUserInfo can only be called from the iOS app.