How to open RoomPlan data on devices without a LiDAR Scanner - core-data

I've saved my RoomPlan.CapturedRoom in CoreData as a Data object. When I open it again on a device WITH a LiDAR Scanner, it works totally fine. However, when I try to open it on the simulator for example, I get an error saying "RoomPlan.CapturedRoom.Error.deviceNotSupported".
The code I use to convert the Data back to a CapturedRoom is this:
let decoder = JSONDecoder()
do {
self.capturedRoom = try decoder.decode(CapturedRoom.self, from: capturedRoomData)
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
The fatalError is thrown here giving me the error above.

Related

Core data + CloudKit - sharing between iOS and watchOS companion app

In my app I store data with core data.
Recently I discovered the new feature introduced by Apple in WWDC19 which allows core data to work with CloudKit.
I just enabled cloudKit for my app and used an NSPersistentCloudKitContainer instead of NSPersistentContainer and all was set up ! All my data is shared between ios devices.
That works like NSPersistentContainer but it sends a copy of changes on icloud server, so there is always a local cache of data.
Now I'd like to access that data from my apple watch companion app but not all the data, only a specific entity!
So how could I do that?
I tried to set the NSPersistentCloudKitContainer shared between both targets with the attribut inspector but watch don't get any data. I can see in cloudKit dashboard there are requests from watchOS but watch just don't get any data.
But if I save an entity from the watch to core data I can get it only from the watch.
My conclusion is both are no storing the data at the same place. So how could I fix that? There are already using the same NSPersistendCloudKitContainer.
the container shared between both targets :
import Foundation
import CoreData
public class CoreDataContainer {
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentCloudKitContainer(name: "MyProjectName")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
Resolved by adding a cloudKitContainerOptions to my context description like this :
class CoreDataStack {
static let persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "MyProjectName")
let description = container.persistentStoreDescriptions.first
description?.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "myCloudContainerID") // HERE !
container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
}

How to catch core data 'constraint violation' Xcode8/iOS10

I have a small code set that captures data messages from a monitoring device. The messages contain a date/time field (startDts) that is unique. I am storing these with core data to a sqlite database. I have set up a constraint for startDts. All goes well until I receive a message with startDts I have already received before - I get a 'Contraint violation' when attempting to save. Makes sense.
My problem is that I don't seem to be able to catch it in code. In stead, the debugger just stops on the 'try' line.
let we = WaterEvent(context: self.coreDataStack.context)
we.startDts = e.startTime as NSDate?
we.stopDts = e.endTime as NSDate?
do {
try self.coreDataStack.context.save() // << Xcode breaks here on constraint violation
}
catch {
let nserror = error as NSError
print("CoreDataStack Unresolved error \(nserror), \(nserror.userInfo)")
print("Constraint violation for: \(we.startDts)")
}
So the 'catch' code block is never executed i.e., I cannot truly respond to the constraint violation intelligently.
This is a snapshot of the debugger output:
First three lines are print statements from my code, line 4 & 5 is debugger output.
So what's going on? Is the 'Constraint violation' not a thrown exception?

GPUImageWriter intermittent crash

I am using the GPUImage framework to record videos. However, while recording, I like to be able to stop recording, start recording, and repeat. My code is as follow:
-(void) startRecording {
NSLog(#"begin recording ");
dispatch_async(recordingQ, ^{
#autoreleasepool {
_assetURL = [self mediaURLAsVideo:YES];
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:[self mediaURLAsVideo:YES] size:CGSizeMake(640, 480)];
[_overlay addTarget:_movieWriter];
[_movieWriter startRecording];
}
});
}
-(void) stopRecording {
NSLog(#"stop recording");
dispatch_sync(recordingQ, ^{
[_overlay removeTarget:_movieWriter];
[_movieWriter finishRecording];
});
}
Occasionally, I see this crash:
*** Assertion failure in -[GPUImageMovieWriter createDataFBO], /Users/.../Pods/GPUImage/framework/Source/iOS/GPUImageMovieWriter.m:548
I am not sure why this is the case but any help would be appreciated.
There's a second issue to this as well. Occasionally, the console logs
Couldn't write a frame
Couldn't write a frame
Couldn't write a frame
Couldn't write a frame

MagicalRecord never gives success in completion block

Magical Record 2.2:
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
NSArray *cats = [Categorization MR_importFromArray:response.result];
}completion:^(BOOL success, NSError *error) {
//Success is always NO?!
}];
However it does save my records. But they only appear when I restart my app.
I have even tried a loop with MR_importFromObject. Still saves but still no Success is true.

Sending Data to Other Players - Game Center

I am developing a simple game center multiplayer game. i did manage almost everything except sending messeage to players. what i mean, i can invite player to play game, game is starts etc.
regarding apple documentation i am using following method to send data but it' doesn't work at all.
const char *bytes = "123";
NSData *packet = [NSData dataWithBytes:&bytes length:3];
[myMatch sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:nil];
if possible a working sample would be great.
many thanks.
I did pretty much same.
NSError *errorTransmit;
const char *bytes = "asd";
NSData *packet = [NSData dataWithBytes:&bytes length:3];
[myMatch sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&errorTransmit];
if (errorTransmit != nil)
NSLog(#"Error sending data to peers: %#", [errorTransmit localizedDescription]);
}
but when code reach
NSLog(#"Error sending data to peers: %#", [errorTransmit localizedDescription]);
I am getting Program received signal: “EXC_BAD_ACCESS”.
that's why i can't see what is going on.
Must confess I've yet to use the GameCenter bits and pieces, but as a general approach I'd have thought you might want to see if there were any errors being generated. As such, if you use something like...
NSError *transmissionError;
[myMatch sendDataToAllPlayers: packet
withDataMode: GKMatchSendDataUnreliable
error: &transmissionError];
if(transmissionError != nil) {
NSLog(#"Transmission error: %#", transmissionError);
}
...you might get a clue what's going wrong.
Incidentally, I'm currently away from a compiler so apologies for any typos in the above. :-)
I cannot see anything wrong here, I am using this code:
NSData *data = nil;
NSError *error = nil;
int packet = 777;
data = [[NSData alloc] initWithBytes:&packet length:sizeof(int)];
[self.mMatch sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable: &error];
and it works

Resources