use of # in Swift 2 - xcode

Hi so my friend gave me his client's existing project and it got too much bugs. I have been debugging the app, and just cam across this line of code
class func saveFile(#data: NSData, filename: String, directory: NSSearchPathDirectory = .DocumentDirectory) -> Bool {
var file = filePath(filename, directory: directory)
return data.writeToFile(file, atomically: true)
}
Noticed #? So what exactly is #?
Here's a screenshot of function with # too.
Additional Info: I think they used this library Service Stack and I think it's for xamarin only.

In Swift 1, # was used to give the same external and internal name to a function parameter. For example, the function definition:
func save(#data: Float) {
print(data)
}
Was equivalent to:
func save(data data: Float) {
print(data)
}
This was removed in Swift 2, and external names must be declared explicitly.
External parameter names are used to make function calls more idiomatic. For example:
func send(sender: String, receiver: String) {
print("Sending from \(sender) to \(receiver)")
}
Is called like this:
send("Cupertino", "New York")
By adding external parameters, you can make that function call more idiomatic without changing the body:
func send(from sender: String, to receiver: String) {
print("Sending from \(sender) to \(receiver)")
}
Making the code more readable:
send(from: "Cupertino", to: "New York")
More information in the Apple docs.

Related

GoDoc Example function for type/struct functions

Problem
I have written some example functions located in a *_test.go file to help clarify context for standalone public functions without issue. The problem on displaying comes when writing example functions for functions tied to a type.
Example
Here's a basic example of what I'm encountering.
Say we have a function in main.go like below:
type Client struct {
user string
ip string
}
func (c *Client) SendNotification(message string) error {
return nil
}
I want to create an example function for such in main_test.go, like below
func ExampleSendNotification() {
//Showoff code here
}
VSCode throws an error for that specific example, saying "ExampleSendNotification refers to unknown identifier: SendNotification". Also, it just does not appear as an example when running the godoc.
I've also tried this format:
func (c *Client) ExampleSendNotification() {
//Showoff code here
}
But then it just removes it as a test in VSCode, and doesn't appear
I found the answer just as I was finishing writing this. Thought I would still post for anybody else.
The trick is writing Example[Type]_[Method], so practically in my example, that would look like:
func ExampleClient_SendNotification() {
//Showoff code here
}

How to Mock inner methods in GoLang

e.g
type test struct { // few fields}
func (t *test) createresource(res1 string,res2 string)error {
//doing some task
t.createsubresource(res1)
}
func (t *test)createsubresource(res1 string)error{
//perform some task
}
I want to write test function for createresource , how can I mock t.createsubresource(res1) call. This is legacy code and I don't have permission to modify any above function.
Your mock can be done using interfaces, as for example:
main.go
package main
type TestInterface interface {
CreateResource(res1 string, res2 string) error
CreateSubresource (res1 string) error
}
func main() {
DoSomething(new(Test))
}
func DoSomething(t TestInterface) {
t.CreateResource()
}
main_test.go
package main
import "testing"
type TestMock struct {}
func (tm *TestMock) CreateResource(res1 string, res2 string) error {
return nil
}
func (tm *TestMock) CreateSubresource(res1 string) error {
return nil
}
func TestDoSomething(t *testing.T) {
err := DoSomething(new(TestMock))
//... do your assertions
}
Why does it works like that?
Calling a function that depends on a specific structure does not allow you to inject alternatives to it, that's why a solution using interface needs to be created. By having an interface, just implement a new structure that matches that interface and pass it as a dependency injection to the procedure that will be tested.
Also, check this out:
There is no easy way, by default, to just point your original structure and tell Go to make a mock from it. Maybe some 3rd party lib can do it (but I didn't saw that yet).
In go, public and private declarations are defined by the first letter as uppercase. By the lower cases declarations in your sample I've noticed that everything is private.
Usually it is not a good practice to test private methods. There are a lot of discussions about this topic, you can take a look in this one here
There are also some support libs to make assertions and mocks like for example stretchr/testify, please make a research first.
I hope that it helps you.

protocol upon addition, asking again and again, cleared derived data folder also

I am integrating autocomplete from heremap, NMAResultListener.
Upon adding protocol stubs, it's asking the same again and again
I cleared derived data folder also. Still no help
class AddWorkVC: UIViewController, UITextFieldDelegate, NMAResultListener {
func request(_ request: NMARequest, didCompleteWithData data: Any?, error: Error?) {
}
var mainWorkTextField : SearchTextField! = nil
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
It should not ask for "add protocol stubs" again and again
The protocol method is defined differently for objective-c and swift. It's possible that something is annotated wrongly, or that the protocol stubs are being added wrongly.
According to the documentation, the Swift method signature is
func requestDidComplete(_ request: NMARequest, data: Any?, error: Error?)

Call to swift method from JavaScript hangs xcode and application

I am writing an iOS App (using xcode 7.3 and swift 2.2) using JavascriptCode framework. Calling javascript methods from swift works perfect, but when I call the swift method from javascript, xcode simply shows a "loading" type of symbol and nothing happens. I need to "force quit" xcode to get out of this state.
I have followed https://www.raywenderlich.com/124075/javascriptcore-tutorial and http://nshipster.com/javascriptcore/ and I am trying pretty simple calls.
Has anyone faced this kind of issue?
My swift code is as follows:
#objc protocol WindowJSExports : JSExport {
var name: String { get set }
func getName() -> String
static func createWindowWithName(name: String) -> WindowJS
}
#objc class WindowJS : NSObject, WindowJSExports {
dynamic var name: String
init(name: String) {
self.name = name
}
class func createWindowWithName(name: String) -> WindowJS {
return WindowJS(name: name)
}
func getName() -> String {
NSLog("getName called from JS context")
return "\(name)"
}
}
I am initializing the context as follows:
runContext = JSContext()
runContext.name = "test_Context"
windowToJs = WindowJS(name: "test")
runContext.setObject(windowToJs.self, forKeyedSubscript: "WindowJS")
If I replace the last two lines in above code with below code without instantiating it, the code simply fails to load.
runContext.setObject(WindowJS.self, forKeyedSubscript: "WindowJS")
And the javascript code is as simple as
function check() {
return WindowJS.getName()
}
I do see the breakpoint being hit in the JS function check and when the WindowJS.getName gets called, xcode simply becomes unresponsive.
The setTimeout could be solved by adding following piece of code to my swift function.
let setTimeout: #convention(block) (JSValue, Int) -> () =
{ callback, timeout in
let timeVal = Int64(timeout)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeVal), dispatch_get_main_queue(), { callback.callWithArguments(nil)})
}
To expose this native code to the JS context, I also added following.
runContext.setObject(unsafeBitCast(setTimeout, AnyObject.self), forKeyedSubscript: "setTimeout")
Things then worked fine.
You're creating a deadlock since you are calling from Swift to JavaScript back to Swift. I'm not sure exactly why it is a deadlock but I had a similar issue with WKWebView on Mac recently.
You need to decouple this and make the communication asynchronous. This obviously means you cannot simply return a value from your JS function in this case.
To decouple, you can break the deadlock by deferring the work the JavaScript function needs to do out of the current runloop iteration using setTimeout:
function myFunction() {
setTimeout(function() {
// The actual work is done here.
// Call the Swift part here.
}, 0);
}
The whole native ↔︎ JavaScript communication is very, very tricky. Avoid it if you can. There's a project called XWebView that may be able to help you as it tries to ease bridging between the two worlds.

Swift 2: Can't call createDirectoryAtUrl with definition

I am currently developing an application on xCode7 beta 2 using Swift 2 (it is a requirement at the moment).
Here is what I am trying to call:
let fileManager = NSFileManager.defaultManager()
let tempDirectoryURL = NSURL(string: NSTemporaryDirectory())!
let directoryURL = tempDirectoryURL.URLByAppendingPathComponent("com.test.manager/multipart.form.data")
var error: NSError?
if fileManager.createDirectoryAtURL(directoryURL, createIntermediates: true, attributes: nil) {
...
}
Here is the error I am getting:
Cannot invoke 'createDirectoryAtURL' with an argument list of type
'(NSURL, createIntermediates: Bool, attributes: nil)'
Which is confusing because the definition for createDirectoryAtURL I am getting when I right click and "view definition" is:
func createDirectoryAtURL(
url: NSURL,
withIntermediateDirectories createIntermediates: Bool,
attributes: [String : AnyObject]?
) throws
The only only paramater that doesn't match verbatim is the last parameter "attributes", which the documentation (and all example usage) explicitly states can accept the value nil.
Apple's Documentation:
If you specify nil for this parameter, the directory is created
according to the umask(2) Mac OS X Developer Tools Manual Page of the
process.
Two problems here:
You've switched an parameter label for its internal name. The second parameter's label — part of the function name, required for calling it — is withIntermediateDirectories. The implementor of that function refers to that parameter's value as createIntermediates. So your call should look like this:
fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
Note the signature you quoted:
func createDirectoryAtURL( ... ) throws
You're using this call as the condition of an if statement — that means you need a function that returns Bool. The compiler is trying to satisfy the requirement of the if statement by looking for a function called createDirectoryAtURL whose type signature is (NSURL, Bool, [String : AnyObject]?) -> Bool, and complaining because it only sees one whose signature is (NSURL, Bool, [String : AnyObject]?) throws -> Void.
The error handling system in Swift 2 takes ObjC methods that return BOOL and have an NSError out parameter and turns them into throwing methods with no return type (that is, they return Void). So, if you're looking at Swift 1.x code that uses such methods, or porting ObjC code, you need to change patterns like the following:
var error: NSError?
if fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil, error: &error) {
// all good
} else {
// handle error
}
And use patterns like this instead:
do {
try fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
// if here, all is good
} catch {
// handle error
}

Resources