I'm trying to build an app written in Swift that uses Parse, but I've realized that my Xcode no longer provides autocomplete for any of the Parse functions. The app still compiles and builds with no problem on the iOS simulator so I know the framework is being read/compiled correctly but it's very frustrating to develop without being able to use the autocomplete features, especially since the API Reference doesn't yet have Swift code.
For my current project, I added pod Parse to my Podfile and thus added the sdk that way. I've also followed the instructions here: http://blog.parse.com/2014/06/06/building-apps-with-parse-and-swift/ to create a Appname-Bridging-Header.h file, adding #import <Parse/Parse.h> there to import the header file. So I'm not sure what the problem is.
There is definitely some support for autocompleting bridged Obj-C libraries into swift but it's not perfect yet.
For example, if you subclass PFQueryTableViewController and type 'tableview' on a new line, all the standard UITableViewController protocol methods appear as autocomplete, in addition to the PFQueryTableViewController-specific method:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!, object: PFObject!) -> PFTableViewCell!
However, this isn't really a Parse-specific issue and will probably improve with new releases of swift/Xcode.
If I understood question correctly, try this:
var gameScore : PFObject = PFObject(className: "GameScore")
or
var gameScore = PFObject(className: "GameScore") as PFObject
I had issue with swift's methods' autocompletion after the object was created, because XCode couldn't recognize class of new object if you don't write it manually.
Related
basically I have some Objective-c class already existing and I want to use them in my NativeScript projet. Currently I have added those files to the Xcode project target and I want to be able to call my objective-c code from nativeScript js. I've read the doc but I don't understand it. It seems so complicated. basically currently all I want to do is be able to present my custom view controller by calling probably something along
const vc = MyCustomViewController.alloc.initWithNibName("xib file")
page.frame.ios.controller.present(vc,true, nil)
Am I obligated to create a plugin for that? Am I obligated to use my objective-c class to build a framework in Xcode and then import the framework?
So I found out.
Actually what you need to do is first to compile your native iOS code into a framework. As per the documentation all your classes must inherit NSObject and all your function must be marked with #objc to be exposed to the objective-c Nativescript side if you write in swift. You will notice as well that in a framework your bundle is not the main bundle. In this example you can see how you can retrieve the bundle from the framework and load a xib from it.
Then you need to add your framework file to a Nativescript plugin. For that, you want to add the framework to the plugin's iOS folder yourPlugin/platform/iOS/yourFramework.framework.
then, you need to add your plugin to your app. You can add your local plugin by using the next command line. Notice the path end with the /src folder.
tns plugin add /path/to/yourplugin/src
Now, you can then call your native functions and classes without even importing them. Of course this works only on iOS. If you run your app on android, calling those methods will crash.
To show this viewController on your Nativescript side you will need to call the following code. By the way You can find documentation elsewhere to get a reference to the current page or frame object.
const controller = page.frame.ios.controller
const vc = IOMediaViewController.create()
vc.modalPresentationStyle = UIModalPresentationFullScreen
controller.presentViewControllerAnimatedCompletion(vc,true,null)
I am trying to understand the best ways in which to bring native library code into a NativeScript plugin for iOS. I've had success in past bringing in a CocoaPod and accessing the symbols from that. So I want to create my own.
I follow the process for pod lib create TestPod to generate my library project. (https://guides.cocoapods.org/making/using-pod-lib-create.html)
The 'library' is a trivial test: it simply creates a class with a function that returns
a recognizable greeting string.
The associated "Example app" demo produces a text label that displays this string.
This all works as expected, all running in pure iOS world (written in Swift).
At the Nativescript side, I'm using the Nativescript Plugin Seed and I'm declaring my Podfile in the src/platforms/iOS folder as directed. My "plugin" (trivial as it is as a test), has the iOS-specific parts in the pluginName.ios.js file. I have a separate test method in here that verifies I can reach and use native iOS platform symbols (e.g. NSMutableString) and that works as expected. I want to do the same thing with native code imported from my library.
But when I bring the Podfile into Nativescript, it builds okay, but I'm not able to see any of the symbols as I would expect to see.
I generate typings and I don't find them either, but I do find a "TestPod.d.ts" typings file that declares some version info and a mysterious class named "UITest" that I did not define and bears no resemblance to my "SimpleTest" class, which I can't find anywhere.
I'm sure I'm missing something here that is probably obvious to the knowledgeable. But I'm unable to guess what it is. Any ideas?
import Foundation
#objc public class SimpleTest : NSObject {
public func announce() -> String {
return "Greetings from Swift code in a library"
}
}
I'm calling it in the plugin using the following:
public testNativeLib() : string {
let str:string;
try {
const testClass = new SimpleTest()
str = testClass.announce()
} catch(e) {
str = e.message;
}
return str;
}
and what I get returned for str is the catch case error message: "Can't find variable: SimpleTest"
Without seeing the source to the pod file; the only guess would be that you didn't use the #objc on anything that you wanted exposed. Without you exposing anything with #objc (or descending from a native objc class, so it is tagged by swift automagically) NativeScript cannot see it.
Please note their are some types in Swift that currently cannot be consumed by NativeScript (Or ObjC) and you have to write some wrapper code in swift around it using types that are compatible with ObjC so that NativeScript can use it.
Please see: https://docs.nativescript.org/guides/ios-source-code for more info on requirements...
The code needs to be:
import Foundation
public class SimpleTest : NSObject {
#objc public func announce() -> String {
return "Greetings from Swift code in a library"
}
}
Move the #objc to the actual property/function you want exposed. The NSObject will already cause the class to be exposed if it has exposed members.
The metadata generated:
A complete demo using a swift source file in a plugin is now located at
https://github.com/NathanaelA/demo-swift-plugin
If I have full control over the source, then I won't normally add another moving piece (i.e. cocoapod) to the mix; just let xcode compile the swift code and expose it, no need to add any additional places something can break.
However, if you want to see how to do an actual swift CocoaPod plugin; checkout any of these plugin repos that use swift code and cocoapod:
https://github.com/tomvardasca/nativescript-crypto
https://github.com/arpit2438735/nativescript-tglib
https://github.com/Daltron/NotificationBanner
In the case of an actual cocoapod; you need to have a valid Podfile, and a valid podspec file! Once you have those; when you build the application, you can open up xcode and verify that the cocoapod is linked in. If it isn't linked in then your podfile/podspec is messed up and has to do with a issue with Cocoapod and it is not a NativeScript issue. So in that case; you need to follow some Cocoapod tutorials to get it to work.
Please note; nuking your platform folder frequently while you are testing with cocoapods is highly recommended. Occasionally Nativescript does not detect the changes to Native code properly and so it then doesn't rebuild the xcode project/workspace files. So nuking your platforms folder will of course force it to rebuild them. If you don't you WILL waste a lot of time while messing around with cocoapods.
When running the sample project you will see this:
In addition, in the demo, the metadata generated from the code I saved in the demo/metadata folder so you can look at it.
I have a custom Swift framework in a Cocoapod, wrapped in a NativeScript plugin. My NativeScript TypeScript code can do everything it needs to access classes and methods in the classes in the framework. That in itself was a lot of work to figure out all the nuances. Now I'm at the last part, which is to downcast a custom viewController in the framework from UIViewController. The following code is working, in that NativeScript actually loads my storyboard and controller:
var podBundle = NSBundle.bundleForClass(CustomViewController)
var bundleUrl = podBundle.URLForResourceWithExtension("MyFramework", "bundle")
var bundle = NSBundle.bundleWithURL(bundleUrl)
var storyboard = UIStoryboard.storyboardWithNameBundle("Main", bundle)
var viewController = storyboard.instantiateViewControllerWithIdentifier("CustomViewControllerID")
console.log(viewController)
console.log(viewController instanceof CustomViewController)
application.ios.rootController.presentViewControllerAnimatedCompletion(viewController, true, null)
The first console.log actually logs the full class, as in MyFramework.CustomViewController: hexcodehere
The second console.log logs true as well, meaning it knows the type of the viewController variable is indeed CustomViewController.
The problem is, I need to call a function in CustomViewController, so I need to downcast:
storyboard.instantiateViewControllerWithIdentifier("CustomViewControllerID") as CustomViewController
But the compiler says "Cannot find name" to CustomViewController. If I try MyFramework.CustomViewController, it says "Cannot find name" to MyFramework. Notice NSBundle.bundleForClass(CustomViewController) works. So that means CustomViewController is known to the compiler.
If I import the plugin at the top of the file:
import { CustomViewController } from "myplugin", it says "cannot find module" to myplugin. Mind you I can actually access all the classes in this plugin. So the plugin is definitely properly installed. It is installed from a local file path, not git.
It seems I'm missing something devilishly simple. But I can't figure it out for the life of me.
I'm happy to help others who want to use native iOS storyboard and Swift classes, etc.
Attesting to the brain's ability to work on a problem in the background, it suddenly came to me. Since the runtime is aware of the type, all I have to do is to cast to "any" to get around the compiler issue:
var viewController = storyboard.instantiateViewControllerWithIdentifier("CustomViewControllerID") as any
Then the compiler allows me to call whatever function on my CustomViewController viewcontroller instance without a complaint, and runtime is fine too. To be extra safe, wrap the calls to subclass methods in a if instanceof block.
Autocomplete isn't working for me when accessing members from a class extension in Xcode (6.3.2).
I made a UIColor extension, and I am accessing them via UIColor().sampleExtendedColorName(), and it does not show up while I'm typing. Autocomplete works for everything other than this. Is there a setting I can change?
extension UIColor{
func sampleExtendedColorName() -> UIColor {
return UIColor(red:200/255, green:100/255, blue:120/255, alpha:1.0)
}
}
Update (new info):
So autocomplete is working if I access the UIColors from a ViewController that directly subclasses UIViewController, but if I subclass a custom CustomViewController that is a subclass of UIViewController, autocomplete doesn't show up for some reason.
Checking all the Target Memberships is working fine. If you don't know where the Target Membership is,
Go to your swift file (Eg: ViewController.swift)
On the right side in the Utilities panel, Click file inspector
You can see Target Membership there.
Check all the fields.
Figured it out, issue was on my ColorExtension.Swift file in my Xcode project. I needed to check all the Target Memberships.
I am making a Cocoa app, and previously, all my code was in AppDelegate.swift. I wanted to write an extension but it wouldn't let me do it there, so I created another class, and pasted my code in it. After reconnecting all my objects to their respective Xibs (sorry if my technical jargon is a bit off) the code is the exact same except for the initialization. I used
func applicationDidFinishLaunching(aNotification: NSNotification)
which worked previously in AppDelegate.Swift but now no longer gets executed. Is there a reason for this?
Well it turns out I just needed to add a delegate from my new class to AppDelegate.swift. Now at least the launching works, but now unfortunately everything I write there is crashing. Oh well.
I did not understand well what your problem is, anyway you could follow these steps:
Create your class (suppose to be a UIViewController)
Connect your class with a ViewController in your main storyboard (make sure your app uses that storyboard in Project Settings)
To get started with your code use methods like viewDidLoad, viewDidAppear and so on, which are triggered automatically, like didFinishLaunchingWithOptions you used before.