Marshalling objective c to nativescript js - nativescript

Hello I'm trying to use the following cocoa pod for tcp functionality in ios:
https://cocoapods.org/pods/CocoaAsyncSocket
Im facing problems writing the marshalled js using this library
Here is an example (Objective C):
// The most common way to initialize an instance is simply like this:
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *err = nil;
if (![socket connectToHost:#"deusty.com" onPort:80 error:&err]) // Asynchronous!
{
// If there was an error, it's likely something like "already connected" or "no delegate set"
NSLog(#"I goofed: %#", err);
}
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(#"Cool, I'm connected! That was easy.");
}
JSCODE:
// mainQueue var is to get dispatch_get_main_queue
var mainQueue = (function() {
var runloop = CFRunLoopGetMain();
return function(func) {
CFRunLoopPerformBlock(runloop, kCFRunLoopDefaultMode, func);
CFRunLoopWakeUp(runloop);
}
}());
var tcpClient = GCDAsyncSocket.alloc().initWithDelegateDelegateQueue(testerClass,mainQueue);
var e = new interop.Reference();
if (!tcpClient.connectToHostOnPortError('192.168.88.110',3333,e)) {
console.log('Could not connect to mipbook');
console.log(e.value);
}
function socketDidConnectToHost(sock,host,port) {
console.log('connected to host');
}
The connect to port part is working fine, but the delegate instance method is not being called when the connection is successful.

Tried with this:
let delegate = ...
let dispatchQueue = dispatch_queue_create("test_queue", null);
let udp = GCDAsyncSocket.alloc().initWithDelegateDelegateQueue(delegate, dispatchQueue);
And it works fine. Should also work for GCDAsyncSocket.
For some reason dispatch_get_main_queue() is undefined.

Ok, I got it to work
The problem was with marshalling dispatch_get_main_queue(). I got my script to work by editing GDCAsyncSocket.m in the source of the pod used.
GDCAsyncSocket.m:
delegateQueue = dq;
change to
delegateQueue = dispatch_get_main_queue();
this way dispatch_get_main_queue() is no longer needed to be passed from the js side, its value is evaluated in the objective c library.
Here is the working JS code:
var tcpClientDelegate = NSObject.extend({
socketDidConnectToHostPort(sock,host,port) {
console.log('connected to host: '+host);
console.log('connected to port: '+port);
}
}, {
protocols: [GCDAsyncSocketDelegate]
});
var clientInstance = new tcpClientDelegate();
var tcpClient = GCDAsyncSocket.alloc().initWithDelegateDelegateQueue(clientInstance,null);
var e = new interop.Reference();
if (!tcpClient.connectToHostOnPortError('192.168.88.110',3333,e)) {
console.log('Could not connect to mipbook');
console.log(e.value);
}

Related

Core Data Error: "Can't find model for source store"

I just deleted an attribute of my entity inside CoreData and after that this error appears:
2016-02-02 21:37:54.499 toRep_Management[32110:4679391] CoreData: error: -addPersistentStoreWithType:XML configuration:(null) URL:file:///Users/Tom/Library/Application%20Support/de.toEducate.toRep_Management/CocoaAppCD.storedata options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "Persistent store migration failed, missing source managed object model." UserInfo={URL=file:///Users/Tom/Library/Application%20Support/de.toEducate.toRep_Management/CocoaAppCD.storedata, metadata={type = immutable dict, count = 6,
entries =>
0 : {contents = "NSStoreUUID"} = {contents = "A3FD787E-495C-493D-A3B9-2E7F7925EF7C"}
3 : {contents = "NSStoreModelVersionIdentifiers"} = (
""
)
4 : {contents = "NSStoreType"} = {contents = "XML"}
10 : {contents = "NSPersistenceFrameworkVersion"} = {value = +641, type = kCFNumberSInt64Type}
11 : {contents = "NSStoreModelVersionHashes"} = {type = mutable dict, count = 1,
entries =>
0 : Notice = {length = 32, capacity = 32, bytes = 0xd22eaaf9bb53e406e8914544584e0e72 ... 0899bacb36b735bd}
}
12 : {contents = "NSStoreModelVersionHashesVersion"} = {value = +3, type = kCFNumberSInt64Type}
}
, reason=Can't find model for source store} with userInfo dictionary {
URL = "file:///Users/Tom/Library/Application%20Support/de.toEducate.toRep_Management/CocoaAppCD.storedata";
metadata = {
NSPersistenceFrameworkVersion = 641;
NSStoreModelVersionHashes = {
Notice = ;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = XML;
NSStoreUUID = "A3FD787E-495C-493D-A3B9-2E7F7925EF7C";
};
reason = "Can't find model for source store";
}
2016-02-02 21:37:54.499 toRep_Management[32110:4679391] CoreData: annotation: NSPersistentStoreCoordinator's current model hashes are {
Notice = <2465d170 cdc5f276 8e769b4d 25c03a0d 8efb193b 6707ab4d 46419c42 17733df1>;
}
I thought I implemented a lightweight migration correctly but now I´m not sure anymore.
My AppDelegate:
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "de.toEducate.toRep_Management" in the user's Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask)
let appSupportURL = urls[urls.count - 1]
return appSupportURL.URLByAppendingPathComponent("de.toEducate.toRep_Management")
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("toRep_Management", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.) This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
let fileManager = NSFileManager.defaultManager()
var failError: NSError? = nil
var shouldFail = false
var failureReason = "There was an error creating or loading the application's saved data."
// Make sure the application files directory is there
do {
let properties = try self.applicationDocumentsDirectory.resourceValuesForKeys([NSURLIsDirectoryKey])
if !properties[NSURLIsDirectoryKey]!.boolValue {
failureReason = "Expected a folder to store application data, found a file \(self.applicationDocumentsDirectory.path)."
shouldFail = true
}
} catch {
let nserror = error as NSError
if nserror.code == NSFileReadNoSuchFileError {
do {
try fileManager.createDirectoryAtPath(self.applicationDocumentsDirectory.path!, withIntermediateDirectories: true, attributes: nil)
} catch {
failError = nserror
}
} else {
failError = nserror
}
}
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = nil
let migrateOptions = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
if failError == nil {
coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CocoaAppCD.storedata")
do {
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: migrateOptions)
} catch {
failError = error as NSError
}
}
if shouldFail || (failError != nil) {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
if failError != nil {
dict[NSUnderlyingErrorKey] = failError
}
let error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSApplication.sharedApplication().presentError(error)
abort()
} else {
return coordinator!
}
}()
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving and Undo support
#IBAction func saveAction(sender: AnyObject!) {
// Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user.
if !managedObjectContext.commitEditing() {
NSLog("\(NSStringFromClass(self.dynamicType)) unable to commit editing before saving")
}
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
NSApplication.sharedApplication().presentError(nserror)
}
}
}
func windowWillReturnUndoManager(window: NSWindow) -> NSUndoManager? {
// Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.
return managedObjectContext.undoManager
}
func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply {
// Save changes in the application's managed object context before the application terminates.
if !managedObjectContext.commitEditing() {
NSLog("\(NSStringFromClass(self.dynamicType)) unable to commit editing to terminate")
return .TerminateCancel
}
if !managedObjectContext.hasChanges {
return .TerminateNow
}
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
// Customize this code block to include application-specific recovery steps.
let result = sender.presentError(nserror)
if (result) {
return .TerminateCancel
}
let question = NSLocalizedString("Could not save changes while quitting. Quit anyway?", comment: "Quit without saves error question message")
let info = NSLocalizedString("Quitting now will lose any changes you have made since the last successful save", comment: "Quit without saves error question info");
let quitButton = NSLocalizedString("Quit anyway", comment: "Quit anyway button title")
let cancelButton = NSLocalizedString("Cancel", comment: "Cancel button title")
let alert = NSAlert()
alert.messageText = question
alert.informativeText = info
alert.addButtonWithTitle(quitButton)
alert.addButtonWithTitle(cancelButton)
let answer = alert.runModal()
if answer == NSAlertFirstButtonReturn {
return .TerminateCancel
}
}
// If we got here, it is time to quit.
return .TerminateNow
}
Could anybody help with the error and how can I handle this in future with a better migration?
"Can't find model for source store" means that you're trying to do a model migration but that Core Data can't find the old version of the data model. For migration to work, you need to have both the old version and the new version. The error suggests that you only have the new version.
When you're going to change a data model and migrate data, you need to create a new version of the model in your project. You'd do this by selecting the model file in Xcode and using "Editor" menu --> "Add Model Version". Then you'd make your changes to the new version while leaving the old one in place.
You need to restore the old model. The best way to do that is to just look back through your SCM (git, probably) commits and get it.

Delegate functions are not called - NSURLConnection

I'm new to swift coding, so most of my code is "this is how I found it on the internet" status.
I'm trying to send a HTTP GET request and then work with it. I'm using NSURLConnection for this. I have 2 swift files in my Xcode project (it is a swift console project, not playground), one is main one and 2nd contains my class I would like to use for delegation:
import Foundation
class Remote: NSObject, NSURLConnectionDelegate {
var data = NSMutableData()
func connect() {
var url = NSURL(string: "https://www.google.com")
var request = NSURLRequest(URL: url!)
NSLog("Is%# main thread", NSThread.isMainThread() ? "" : " NOT");
var conn = NSURLConnection(request: request, delegate: self, startImmediately: false)
conn?.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
conn?.start()
sleep(2)
}
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
println("didReceiveResponse")
}
func connection(connection: NSURLConnection!, didReceiveData conData: NSData!) {
println("didReceiveData")
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
println("DidFinishLoading")
}
deinit {
println("deiniting")
}
}
Here is my main swift code:
import Foundation
var xxx = Remote()
xxx.connect()
sleep(10)
sleep(2)
When I set breakpoints on each println in delegate functions, they are never hit. Execution is done from main thread according to NSLog output.
In debugger I can see that data are sent and received over the network, but I never get any output. I've seen many similar questions here but nothing helped me.
What am I doing wrong?
As Martin R suggested I added correct NSRunLoop into my code right after starting NSURLConnection:
self.shouldKeepRunning = true
let theRL = NSRunLoop.currentRunLoop()
while self.shouldKeepRunning && theRL.runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeInterval: 1.0, sinceDate: NSDate())) { }
shouldKeepRunning is bool variable defined in my class and it set to false in delegate function connectionDidFinishLoading, so

Why doesn't this function get called?

Im following the Ray Wenderlich tutorial and converted most of the code to Swift. Im on part two but this function never gets called. I followed the tutoral but im not sure where to call it. I dont think its a delegate function also so I know that im supposed to call it somewhere but not sure where. Has anyone ever tried this tutorial and got it to work on Swift? Thanks!
Heres the link: http://www.raywenderlich.com/60998/game-center-tutorial-how-to-make-a-simple-multiplayer-game-with-sprite-kit-part-2
func match(theMatch: GKMatch, didReceiveData data: NSData, fromPlayer playerID: String) {
let message = UnsafePointer<Message>(data.bytes).memory
if(message.messageType == MessageType.kMessageTypeRandomNumber) {
let messageRandomNumber = UnsafePointer<MessageRandomNumber>(data.bytes).memory
println("Received random number: \(messageRandomNumber.randomNumber)")
var tie = false
if(messageRandomNumber.randomNumber == _ourRandomNumber) {
println("Tie")
tie = true
_ourRandomNumber = arc4random()
self.sendRandomNumber()
}
else {
var dictionary = ["\(playerIDKey)":"\(playerID)", "\(randomNumberKey)":"\(messageRandomNumber.randomNumber)"]
self.processReceivedRandomNumber(dictionary)
}
if(_receivedAllRandomNumbers) {
_isPlayer1 = self.isLocalPlayerPlayer1()
}
if(!tie && _receivedAllRandomNumbers) {
if(_gameState == GameState.kGameStateWaitingForRandomNumber) {
_gameState = GameState.kGameStateWaitingForStart
}
self.tryStartGame()
}
}
else if(message.messageType == MessageType.kMessageTypeGameBegin) {
println("Begin game message received")
_gameState = GameState.kGameStateActive
self.delegate?.setCurrentPlayerIndex(self.indexForLocalPlayer())
}
else if(message.messageType == MessageType.kMessageTypeMove) {
println("Move message received")
let messageMove = UnsafePointer<MessageMove>(data.bytes).memory
self.delegate?.movePlayerAtIndex(self.indexForPlayerWithId(playerIDKey))
}
else if(message.messageType == MessageType.kMessageTypeGameOver) {
println("Game over message received")
let messageGameOver = UnsafePointer<MessageGameOver>(data.bytes).memory
self.delegate?.gameOver(messageGameOver.player1Won)
}
}
The delegate method match:didReceiveData:fromPlayer: has been deprecated. Use match:didReceiveData:fromRemotePlayer: instead.
Make sure you set the delegate, doing something like:
func matchmakerViewController(viewController: GKMatchmakerViewController, didFindMatch match: GKMatch) {
theMatch = match
match.delegate = self
...
}
That is the viewController:didFindMatch delegate for GKMatchmakerViewControllerDelegate.
You need to delegate from both GKMatchmakerViewControllerDelegate and GKMatchDelegate.
Yeah, I know this is an old thread, but the OP hasn't had any success yet.
match:didReceiveData:fromPlayer: is a GKMatchDelegate optional method which will trigger when the match received data sent from the player.
So please don't try to call it directly. It will be called by GameKit when data is received from a player.
#protocol GKMatchDelegate <NSObject>
#optional
// The match received data sent from the player.
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromRemotePlayer:(GKPlayer *)player NS_AVAILABLE(10_10, 8_0);
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID NS_DEPRECATED(10_8, 10_10, 4_1, 8_0, "use match:didReceiveData:fromRemotePlayer:");
#end;
This also is declared in GameKitHelper.h class as a GameKitHelperDelegate
#protocol GameKitHelperDelegate
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data
fromPlayer:(NSString *)playerID;
#end
This delegate method is calling from the below method when the match received data sent from the player
#pragma mark GKMatchDelegate
// The match received data sent from the player.
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
if (_match != match) return;
[_delegate match:match didReceiveData:data fromPlayer:playerID];
}

Whats the easiest way to empty and save a Core Data Table in Swift?

So I have a entity, which I am treating as a simple Database Table in iOS8 XCODE and SWIFT. I want to delete every entry in the table. Permanently. So when I start up the app again they do not reload.This is my code.
func deleteAllItems(){
println("All Items are being DELETED")
var count:Int = 0
while (HBCContactList.count > 0){
let AppDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let MOContext: NSManagedObjectContext = AppDel.managedObjectContext!
MOContext.deleteObject(HBCContactList[0] as NSManagedObject)
HBCContactList.removeAtIndex(0)
var error:NSError? = nil
if !MOContext.save(&error){
abort()
}
tableView.reloadData()
}
It looks like it loads. When its finished on the screen there is nothing in UITableView and all is good. However If I write code to return me the entity via a fetch statement and do a count on the number of records. It still says there is over 150 results.
Thoughts? Am I even in the right ball park?
One solution is to fetch the objects and delete them.
Here is an example (make sure you specify your own entity) :
// If you'll be using the Managed Object Contexte often,
// you might want to make it a lazy property :
lazy var managedObjectContext : NSManagedObjectContext? = {
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
if let managedObjectContext = appDelegate.managedObjectContext {
return managedObjectContext
}
else {
return nil
}
}()
func deleteData() {
let context = self.managedObjectContext!
let fetchRequest = NSFetchRequest(entityName: "yourEntity")
fetchRequest.includesPropertyValues = false // Only fetch the managedObjectID (not the full object structure)
if let fetchResults = context.executeFetchRequest(fetchRequest, error: nil) as? [yourEntity] {
for result in fetchResults {
context.deleteObject(result)
}
}
var err: NSError?
if !context.save(&err) {
println("deleteData - Error : \(err!.localizedDescription)")
abort()
} else {
println("deleteData - Success")
}
}

Code that has run smoothly for days suddenly not working. Not sure how to fix the exception that is being thrown

I have a piece of code that has been running smoothly since I created it, that has suddenly begun to crash every time I run my app. I keep getting EXC_BREAKPOINT that highlights a line in my Thread 1 that states: Swift._getImplicitlyUnwrappedOptionalValue. I've tried adding breakpoints to catch the suspect code within my method, but nothing turns up and I just keep getting this error. I've been at this for a while now, and I'm pretty stumped as to what is going on and how I'm supposed to fix it. Any help is appreciated! Below I've included a screenshot of the error as well as the method I'm trying to call that produces the error. Thanks!
#IBAction func nextPhoto(sender: UISwipeGestureRecognizer)
{
self.deleteResponseMessage(self)
if photoObjects.count == 0
{
var image:UIImage = UIImage(contentsOfFile: "launchImageTall")
feedView.image = image
}
else
{
userInfo.hidden = false
var content:PFObject = photoObjects[0] as PFObject
var recipients = content["recipients"] as NSMutableArray
var userImageFile = content["imageFile"] as PFFile
userImageFile.getDataInBackgroundWithBlock { (imageData:NSData!, error:NSError!) -> Void in
if error == nil
{
var contentImage = UIImage(data: imageData)
self.feedView.image = contentImage
}
}
var profilePicImageFile = content["senderProfilePic"] as PFFile
profilePicImageFile.getDataInBackgroundWithBlock({ (imageData:NSData!, error:NSError!) -> Void in
if error == nil
{
var picture = UIImage(data: imageData)
self.senderProfilePic.image = picture
}
})
var username = content["senderUsername"] as NSString
senderUsername.text = username
var photoCaption = content["photoCaption"] as NSString
senderMessage.text = photoCaption
senderObjectId = content["senderObjectId"] as NSString
for var i=0;i<photoObjects.count-1;i++
{
photoObjects[i] = photoObjects[i+1]
}
if recipients.count == 1
{
content.deleteInBackground()
}
else
{
recipients.removeObject(currentUserObjectId!)
content.setObject(recipients, forKey: "recipients")
content.saveInBackground()
}
}
}
Did you update Xcode recently. Apple is busy updating their cocoa libraries. Every return value was explicitly being unwrapped (like return String!). Now they are going through every function and evaluating whether it should return an instance (return String) or an optional (String?).
So check your code for optionals and remove those ! or ?.
At least that was the case for me with every Xcode update.

Resources