I am trying to integrate Firebase into an iMessage extension.
As a test, I am setting up Firebase and trying to save a local file to Firebase Storage in the viewDidAppear method. The Firebase Real-time Database works fine in the code below, only the storage part does not.
The exact same code works when done in a normal app (i.e. not a iMessage extension).
I get the following error message:
Error Domain=FIRStorageErrorDomain Code=-13000
"An unknown error occurred, please check the server response."
UserInfo={ResponseErrorDomain=NSURLErrorDomain, object=test.jpg,
bucket=myapp.appspot.com, ResponseErrorCode=-995,
`NSLocalizedDescription=An unknown error occurred, please check the server response.
I am doing the following:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
FIRApp.configure()
FIRAuth.auth()?.signInAnonymously { (user, error) in
guard let fileURL = Bundle.main.url(forResource: "test", withExtension:"jpg") else { return }
let storageRef = FIRStorage.storage().reference().child("test.jpg")
storageRef.putFile(fileURL, metadata: nil) { (metaData, error) in //produces error
if error != nil {
print(error.debugDescription)
}
}
FIRDatabase.database().reference().updateChildValues(["someKey" : "someValue"]) // works fine
}
}
I have a suspicion that iMessage extensions may get limited access to the file system (since they live in a different sandbox than the normal app), and thus getting the file wouldn't work. In this case putData works, but putFile doesn't. Solution: always upload and download in memory (putData and dataWithMaxSize:) vs the file system (putFile and writeFile).
Related
I have a simple UIDocument subclass with overriding load and contents functions.
Before updating on iOS 13 json document was saved in url "/private/var/mobile/Library/Mobile Documents/iCloud~appbundle/Documents/EFB7FCBA96684AC0B101E3CD829E6996.json"
In current iOS version 13.2.2 (after updating) this document does not open:
let cloudDocument: ICloudDocument = ICloudDocument(fileURL: url)
cloudDocument.open { (openSuccess) in
if openSuccess {
success()
} else {
// in my case openSuccess is false
failure()
}
}
Debug information.
After overriding handleError in ICloudDocument
override func handleError(_ error: Error, userInteractionPermitted: Bool) {
print("userInteractionPermitted - \(userInteractionPermitted)")
print(error)
}
in console:
userInteractionPermitted - true
Error Domain=NSCocoaErrorDomain Code=256 "The file “EFB7FCBA96684AC0B101E3CD829E6996” couldn’t be opened." UserInfo={NSURL=file:///private/var/mobile/Library/Mobile%20Documents/iCloud~appbundle/Documents/EFB7FCBA96684AC0B101E3CD829E6996.json}
If I use cloudDocument.read method in ICloudDocument it works well with receiving data from file, but open throws the error.
DocumentState cloudDocument.documentState of document is closed.
File options:
> print(FileManager.default.isWritableFile(atPath: url.path))
true
> print(FileManager.default.isReadableFile(atPath: url.path))
true
URLResourceKeys:
URLResourceKey.ubiquitousItemIsUploadingKey - true
URLResourceKey.ubiquitousItemIsUploadedKey - false
URLResourceKey.ubiquitousItemUploadingErrorKey - nil
URLResourceKey.ubiquitousItemHasUnresolvedConflictsKey - false
URLResourceKey.isUbiquitousItemKey - true
URLResourceKey.ubiquitousItemDownloadingStatusKey - "NSURLUbiquitousItemDownloadingStatusCurrent"
I found one link about this problem without answer
https://forums.developer.apple.com/thread/126889
Any ideas?
Restaring iOS solved this problem. I think that after updating into iOS 13 and migration, system needs additional reload.
I am trying to implement Admob for my iOS app. The form loads on the Xcode simulator devices. I am located in the US, but I have used the following code to test that the Consent SDK is working for European users. When I use this with a simulator, the form and ads load.
PACConsentInformation.sharedInstance.debugIdentifiers = ["SPECIFIC_TO_MY_DEVICE"]
PACConsentInformation.sharedInstance.debugGeography = PACDebugGeography.EEA
The form does not load on my physical device with this configuration. The form also did not load when I used testflight to distribute a test version to a test user in the EU. Subsequently, the ads did not load on "European" devices.
When the form should load, I get an error from the below block of code. Also. I get the error WebKitDomain Error 101. My ATS settings are set up in the plist per the Admob documentation.
thisForm.load {(_ error: Error?) -> Void in
if let error = error {
print("Error loading form: \(error.localizedDescription)")
//I am getting the error here.
} else {
thisForm.present(from: self) { (error, userPrefersAdFree) in
print("in present handler")
if let error = error {
// Handle error.
print("error presenting: \(error.localizedDescription)")
} else if userPrefersAdFree {
//TODO: find a way to disable ads
} else {
// Check the user's consent choice.
//let status = PACConsentInformation.sharedInstance.consentStatus
}
}
}
Does anyone know what may be causing these errors with physical devices? I have tried with a real ad id and a test ad id.
Present consent form only if the following equals true
If requestLocationInEEAOrUnknown == true {
//present consent form
}
else {
//do whatever is needed
}
I have a small app in which users can upload local files to the server.
I am trying to handle unexpected situation like losing Internet connection. I want to use persistence feature which I have declared in AppDelegate.
Database.database().isPersistenceEnabled = true
At first, I export file to the server and if it succeeds then database reference is created.
let uploadTask = ref.putData(contents as Data, metadata: myMetadata, completion: { (metadata, error) in
if error != nil {
...
} else {
DataService.instance.usersRef.observeSingleEvent(of: .value) { (snapshot: DataSnapshot) in
...
}
}
)}
However, testing the solution (with turning airplane mode on and off) while exporting the file, the transfer is not restored. I am not sure if it's implementation issue or I'm missing key point of persistence feature.
Thanks in advance!
I have a synchronized realm running on Realm Object Server. It is a global realm created by the admin user. I created another user on the server (not an admin) and used the admin user to grant read-only permissions to that user for that particular realm.
I can see the permission when I query the admin's management realm and the normal user's permission realm. However, when I connect to the global realm from my iOS app (Swift 3) with the normal user, the server returns error code 206: permission denied and closes the realm file.
The strange thing is that the app manages to download a few objects from the realm, and it also loads a few more objects (about 3) every time I relaunch it.
An even stranger thing is that when I launch the app with the admin user the same thing happens except it loads about 100 extra objects in every relaunch and it doesn't show the permission denied error.
Note: I'm getting these results on the iOS simulator and still haven't tried the app on an actual device.
UPDATE: I have tried the app on a physical device and the problem persists.
I'm using Realm Swift v2.10.1 on Xcode 8.3.3 and Realm Object Server v1.8.3 on a Linux Ubuntu 16.04.3 x64 machine.
EDIT:
Here is how I apply the permission:
let per = SyncPermissionValue(realmPath: "/realmname", userID: "userId", accessLevel: .read)
realmUser!.applyPermission(per, callback: { (error) in
print("PERMISSION ERROR: \(String(describing: error))")
if error == nil {
print("no error")
}
})
Here is how connect from my app. These methods are in a custom class which is used by the view controller requesting the objects from the realm.
private func logInToServer() {
SyncUser.logIn(with: .usernamePassword(username: "username", password: "pass", register: false), server: URL(string: "http://server IP:9080")!, onCompletion: { (user, error) in
var realmUser = user
if realmUser == nil {
realmUser = SyncUser.current
}
self.connectToDatabase(realmUser: realmUser!)
})
} // end logInToServer()
private func connectToDatabase(realmUser: SyncUser) {
DispatchQueue.main.async(execute: {
let configuration = Realm.Configuration(syncConfiguration: SyncConfiguration(user: realmUser, realmURL: URL(string: "realm://server IP/realmname")!))
self.realm = try! Realm(configuration: configuration)
// I initially found out that implementing a small delay gave the app enough time to download all objects even though the permission denied error was still there. But, this no longer works.
Timer.scheduledTimer(timeInterval: self.delay, target: self, selector: #selector(self.populateResults), userInfo: nil, repeats: false)
})
} // end connectToDatabase()
#objc private func populateResults() {
self.categories = self.realm.objects(BookCategory.self)
self.books = self.realm.objects(Book.self)
delegate?.didPopulteResults(categories, books) // The delegate is the view controller requesting the objects.
}
I want an option in my app to reset all of my data. I created a class named CoreDataStack and put all of my core data code in it with this function:
func dropAllData() throws {
try persistentStoreCoordinator.destroyPersistentStoreAtURL(applicationDocumentsDirectory, withType:NSSQLiteStoreType , options: nil)
try addStoreCoordinator(NSSQLiteStoreType, configuration: nil, storeURL: applicationDocumentsDirectory, options: self.options)
}
I then have this function in my AppDelegate:
func dropTables() {
do {
try stack.dropAllData()
} catch {
print(error)
}
}
I've used this function before to delete my data with success, but suddenly I can't delete anything and I keep receiving this error when I call dropTables().
Error Domain=NSCocoaErrorDomain Code=134000 "(null)" UserInfo={NSURL=file:///Users/myname/Library/Developer/CoreSimulator/Devices/59E4B2FB-E0E4-4527-8793-253864A2DE83/data/Containers/Data/Application/33D1C5CF-94B8-4897-A77F-A10DDFEF92D6/Documents/}
I've tried searching for this error and couldn't find anything (or I'm just looking in the wrong places). I also tried deleting the app from the device, reinstalling, and trying again but get the same result. Does anyone know what this error is and why can't delete my database?