My project is using framework and both framework and project are using same enum values. But when I passing param from Main app to module controller I'm getting that they are not same so way to do it is to convert it. I create extension:
extension Result {
init(_ data: Messaging.MessagingResult) {
switch data {
case .authenticationFailed: self = .authenticationFailed
case .connectionError: self = .connectionError
}
}
}
and now I have to create function which will take project enum back to module enums
let adaptedConsume = transform(from: self.consume)
Is this right approach and how transform function should look like
I don't know if I understood your question, but supposing that what you want to do is to map the values of one enum to another, you can just use typealias to do that.
Swift makes it a lot to map types from Objective C to Swift.
Something like typealias Result = Messaging.MessagingResult should work.
You can know more about typealis from Swift Documentation.
Related
I have a function that returns a completion. The completion has as in parameter a custom class with a dictionary that uses an enum as an identifier.
The problem I am facing is that Xcode does not recognises the type of the variable and does not auto complete when I use it inside of completion block.
My code looks like that
Function
func testFunc (completion:(PrxServiceResponseCallback) ->()){
let responseCallback = PrxServiceResponseCallback()
completion(responseCallback)
}
Class
class PrxServiceResponseCallback:NSObject{
var success = false
var resultCode:Int32 = 0
var response:[PrxResponseAttributes:Any] = [PrxResponseAttributes:Any]()
}
enum PrxResponseAttributes{
case sourceProtocolInfoArray
case sinkProtocolInfoArray
case connectionIDsArray
case connectionInfo
}
Calling the function
testFunc { (testResonse) in
testResonse.response[.]//Not Auto completing
}
The whole idea of making a dictionary with an enum as identifier was to make easier which attributes the dictionary returns but, If I can't auto complete, the idea is more pointless.
Any ideas?
Xcode doesn't give you autocomplete doesn't mean that your code doesn't compile. It just means that Xcode is too stupid to figure things out. I have encountered such situations many times before. It seems to always happen inside closures.
You can just ignore the fact that no autocomplete shows up and type the case name yourself:
testResonse.response[.sourceProtocolInfoArray]
It will compile.
You can also consider creating a struct instead of storing the values in a dictionary. Here's a sample struct (I guessed the types):
struct Response {
let sourceProtocolInfo: [String]
let sinkProtocolInfo: [String]
let connectionIDs: [Int]
let connectionInfo: String
}
If you use var response:[UIColor:Any] = [UIColor:Any]()
it is still not giving auto complete so it is not your issue and you can not do much on it .
If you need auto complete then use PrxResponseAttributes with . (dot)
you can do it like
testResonse.response[PrxResponseAttributes.sourceProtocolInfoArray]
EDIT
Note: It is only happening with implemented closure if you add one property in your PrxServiceResponseCallback class like
var anyValue:Any? {
return response[.connectionInfo] // it is showing completion
}
So, I want to make an operator ('or') which will allow me to declare a variable like this:
var someNum: Int or Double
This bring an example. I want to actually use it on some custom made data types. But is it possible to make an operator for variable declarations that will allow for said variable to be one of two types depending on what its being assigned? I know what data types are possible of being entered, but unfortunately I would currently either assign it a type of 'Any' with a bunch of failsafe code implemented or change the original data types created. So I was just wondering if this is possible or might even exist.
I used this article as a reference, but from what I read I'm not sure if I can or how I would implement it for my needs.
Custom Operators in Swift
Thanks for any and all the help in advance.
You can't do this in the way you're asking. It's not possible syntactically to use a operator in a declaration like that.
What you can do is use an enum to distinguish the kinds:
enum NumericInput {
case integral(Int)
case fractional(Double)
}
and take that as the type of your variable:
var value: NumericInput
Then you say
value = .integral(someInteger)
You could do this with generics:
struct MyStruct<T>
{
var someNum: T
}
You can then explicitly state the dataType you wish to use by specifying the type on creation: let a = MyStruct<Int>(someNum: 4).
One thing Swift does that makes this all absolutely beautiful is derive the data type from the constructor, so you can also just do this:
let intStruct = MyStruct(someNum: 4)
let floatStruct = MyStruct(someNum: 5.0)
You can just declare the value with type Any.
For example,
var myVar: Any = shouldAssignDouble ? Double(20) : Float(20)
Later when you want to know if the actual type is a Float or Double, you can check it with
myVar is Double //returns true
I want to store a more specialized type in a Dictionary of type [String:SomeClass]. Here is some sample code illustrating my problem (also available to play with at https://swiftlang.ng.bluemix.net/#/repl/579756cf9966ba6275fc794a):
class Thing<T> {}
protocol Flavor {}
class Vanilla: Flavor {}
var dict = [String:Thing<Flavor>]()
dict["foo"] = Thing<Vanilla>()
It produces the error ERROR at line 9, col 28: cannot assign value of type 'Thing<Vanilla>' to type 'Thing<Any>?'.
I've tried casting Thing<Vanilla>() as Thing<Flavor> but that produces the error cannot convert value of type 'Thing<Vanilla>' to type 'Thing<Flavor>' in coercion.
I've also tried to define the Dictionary as type [String:Thing<Any>] but that doesn't change anything either.
How do I create a collection of different Things without resorting to plain [String:AnyObject]?
I should also mention that the class Thing is not defined by me (in fact it's about BoltsSwift Tasks), so the solution to create a base class of Thing without a type parameter doesn't work.
A Thing<Vanilla> is not a Thing<Flavor>. Thing is not covariant. There is no way in Swift to express that Thing is covariant. There are good reasons for this. If what you were asking for were allowed without careful rules around it, I would be allowed to write the following code:
func addElement(array: inout [Any], object: Any) {
array.append(object)
}
var intArray: [Int] = [1]
addElement(array: &intArray, object: "Stuff")
Int is a subtype of Any, so if [Int] were a subtype of [Any], I could use this function to append strings to an int array. That breaks the type system. Don't do that.
Depending on your exact situation, there are two solutions. If it is a value type, then repackage it:
let thing = Thing<Vanilla>(value: Vanilla())
dict["foo"] = Thing(value: thing.value)
If it is a reference type, box it with a type eraser. For example:
// struct unless you have to make this a class to fit into the system,
// but then it may be a bit more complicated
struct AnyThing {
let _value: () -> Flavor
var value: Flavor { return _value() }
init<T: Flavor>(thing: Thing<T>) {
_value = { return thing.value }
}
}
var dict = [String:AnyThing]()
dict["foo"] = AnyThing(thing: Thing<Vanilla>(value: Vanilla()))
The specifics of the type eraser may be different depending on your underlying type.
BTW: The diagnostics around this have gotten pretty good. If you try to call my addElement above in Xcode 9, you get this:
Cannot pass immutable value as inout argument: implicit conversion from '[Int]' to '[Any]' requires a temporary
What this is telling you is that Swift is willing to pass [Int] where you ask for [Any] as a special-case for Arrays (though this special treatment isn't extended to other generic types). But it will only allow it by making a temporary (immutable) copy of the array. (This is another example where it can be hard to reason about Swift performance. In situations that look like "casting" in other languages, Swift might make a copy. Or it might not. It's hard to be certain.)
One way to solve this is adding an initialiser to Thing and creating a Thing<Flavor> that will hold a Vanilla object.
It will look something like:
class Thing<T> {
init(thing : T) {
}
}
protocol Flavor {}
class Vanilla: Flavor {}
var dict = [String:Thing<Flavor>]()
dict["foo"] = Thing<Flavor>(thing: Vanilla())
In c++, one can introduce an alias reference as follows:
StructType & alias = lengthyExpresionThatEvaluatesToStuctType;
alias.anAttribute = value; // modify "anAttribute" on the original struct
Is there a similar syntactic sugar for manipulating a (value typed) struct in Swift?
Update 1: For example: Let say the struct is contained in a dictionary of kind [String:StructType], and that I like to modify several attributes in the the struct myDict["hello"]. I could make a temporary copy of that entry. Modify the copy, and then copy the temporary struct back to the dictionary, as follows:
var temp = myDict["hello"]!
temp.anAttribute = 1
temp.anotherAttribute = "hej"
myDict["hello"] = temp
However, if my function has several exit points I would have to write myDict["hello"] = temp before each exit point, and it would therefore be more convinient if I could just introduce and alias (reference) for myDict["hello"] , as follows:
var & alias = myDict["hello"]! // how to do this in swift ???
alias.anAttribute = 1
alias.anotherAttribute = "hej"
Update 2: Before down- or close- voting this question: Please look at Building Better Apps with Value Types in swift (from WWWDC15)!! Value type is an important feature of Swift! As you may know, Swift has borrowed several features from C++, and value types are maybe the most important feature of C++ (when C++ is compared to Java and such languages). When it comes to value types, C++ has some syntactic sugar, and my questions is: Does Swift have a similar sugar hidden in its language?. I am sure Swift will have, eventually... Please, do not close-vote this question if you do not understand it!
I have just read Deitel's book on Swift. While I'am not an expert (yet) I am not completely novel. I am trying to use Swift as efficient as possible!
Swift doesn't allow reference semantics to value types generally speaking, except when used as function parameters declared inout. You can pass a reference to the struct to a function that works on an inout version (I believe, citation needed, that this is implemented as a copy-write, not as a memory reference). You can also capture variables in nested functions for similar semantics. In both cases you can return early from the mutating function, while still guaranteeing appropriate assignment. Here is a sample playground that I ran in Xcode 6.3.2 and Xcode 7-beta1:
//: Playground - noun: a place where people can play
import Foundation
var str = "Hello, playground"
struct Foo {
var value: Int
}
var d = ["nine": Foo(value: 9), "ten": Foo(value: 10)]
func doStuff(key: String) {
let myNewValue = Int(arc4random())
func doMutation(inout temp: Foo) {
temp.value = myNewValue
}
if d[key] != nil {
doMutation(&d[key]!)
}
}
doStuff("nine")
d // d["nine"] has changed... unless you're really lucky
// alternate approach without using inout
func doStuff2(key: String) {
if var temp = d[key] {
func updateValues() {
temp.value = Int(arc4random())
}
updateValues()
d[key] = temp
}
}
doStuff2("ten")
d // d["ten"] has changed
You don't have to make the doMutation function nested in your outer function, I just did that to demonstrate the you can capture values like myNewValue from the surrounding function, which might make implementation easier. updateValues, however, must be nested because it captures temp.
Despite the fact that this works, based on your sample code, I think that using a class here (possibly a final class if you are concerned about performance) is really more idiomatic imperative-flavored Swift.
You can, if you really want to, get a raw pointer using the standard library function withUnsafeMutablePointer. You can probably also chuck the value into an inner class that only has a single member. There are also functional-flavored approaches that might mitigate the early-return issue.
I know why I would use a struct as opposed to a class, but how could I best tell which is being used by an API I'm using?
Obviously looking at the header file (or hopefully documentation) should make it immediately obvious. I am wondering if there is a way to know if the object I am using is a struct or class on face value though?
You can’t inherit from other structures or types. Classes have the ability to inherit functions, variables, and constants from parent classes.
In swift structs are value types while classes are reference types. Working with value types can make your code less error prone.
When you make a copy of a reference type variable, both variables are referring to the same object in memory. A change to one of the variables will change the other.
when you make a copy of a value type variable, the complete variable is copied to a new place in memory. A change to one of the copies will not change the other. If the copying of an object is cheap, it is far safer to make a copy than it is to share memory.
Auto completion in Xcode knows the type of type:
I'm not sure what you mean by "face-value". You can test to see if an object is an instance of a class by getting it's MirrorType using reflect and checking for the MirrorType's objectIdentifier property, like this:
struct TestStruct { }
class TestClass { }
let testStruct = TestStruct()
let testClass = TestClass()
if let x = reflect(testStruct).objectIdentifier {
println("I am a class...")
} else {
println("I am not a class...") // prints "I am not a class..."
}
if let x = reflect(testClass).objectIdentifier {
println("I am a class...") // prints "I am a class..."
} else {
println("I am not a class...")
}
This answer may be outdated with the upcoming release of Swift 1.2 (I do not have the new xCode beta so I can't say for sure), which I understand has better object introspection, but this does do the trick.