Hugo, a razão pela qual quero sair do FB é por ficar demasiado lento e consumir 
recursos passados 20min e se abrir um segundo projecto.

Att,

António Pinto

No dia 04/09/2014, às 17:28, Hugo Ferreira <[email protected]> escreveu:

> APintex,
> 
> Ainda não tinha pensado nisso mas é bem verdade.
> 
> Eu mudei para o OS X à 2 anos e digo-te é sem V de volta. Todos os portáteis 
> baratos ou caros que passam pelas minhas mãos não chegam ao fim da garantia e 
> este é impecável. Nada a apontar. De tal forma que após acabar a garantia, 
> investi para duplicar a RAM e troquei o disco por um SSD e com garantia da 
> Apple. Digo-te que valeu cada cêntimo principalmente para o FB que abusa da 
> máquina.
> 
> Por um lado gostaria de saír do FB. É um IDE preso no tempo :( mas por outro 
> lado serve o seu propósito e pelo que sondei, os outros não estão à altura.
> 
> Eu uso o MySQL em paralelo com o SQL Server à uns anos. Ao fim de algum tempo 
> de conheceres bem os motores, consegues fazer SQL quase 100% compatível sem 
> um ORM (principalmente se usares SQL Server 2012+).
> 
> Todos os projectos que faço, faço logo compatíveis com esses 2 motores.
> 
> Para reports (que nenhum dev gosta) para AIR recomendo o único que conheço: 
> Stimulsoft mas é client-side. Podes usar uma app AIR via linha de comandos no 
> servidor para gerar reports como workaround se precisares de reports no lado 
> do servidor com PHP.
> Têm um solução ASP.NET para quem usar este backend sem workarounds.
> 
> Já disse no forum que se fizeram um solução HTML5 (puro) estou disposto a 
> pagar em avanço. Dizem que é algo que andam a pensar :)
> 
> 
> 2014-09-04 17:17 GMT+01:00 APintex Gmail <[email protected]>:
>> 2014 foi e está a ser um ano de mudanças…
>> Passei do Windows para o OS X, quero passar do Flash Builder para o IntelliJ 
>> IDEA (ainda não tive coragem)
>> Estou a refazer um projecto de .Net para AIR, de MSSQL para MySQL e 
>> webservices feitos em .Net para PHP. 
>> No meio disto tudo o que mais me custa são os reports (uma seca para mim 
>> desde sempre)
>> 
>> António Pinto
>> [email protected]
>> 
>> 
>> 
>> No dia 04/09/2014, às 16:58, Hugo Ferreira <[email protected]> escreveu:
>> 
>>> É como eu. Na realidade acredito que a maioria esteja no mesmo barco. Para 
>>> coisas a sério ainda não.
>>> Quem já trabalha à anos com Objective-C, irá continuar mesmo após o Swift 
>>> se tornar uma realidade viável.
>>> 
>>> Terminei o meu primeiro projecto HTML5 e correu muito bem. No final demorei 
>>> muito menos tempo do que previa e já tenho agora uma base para fazer o 
>>> próximo mais rapidamente.
>>> 
>>> Quando houver tempo irei recriar um projecto em Flex com HTML5 e mais tarde 
>>> outro (se isto algum dia vier a acontecer) e depois disso acho que não 
>>> voltarei a usar o Flash !
>>> 
>>> O AIR vou continuar a usar e abusar e também muito código nativo com 
>>> Android.
>>> 
>>> Também acho que o Swift será uma realidade para mim só para o ano que vem !
>>> 
>>> 
>>> 2014-09-04 16:48 GMT+01:00 Apintex <[email protected]>:
>>>> Hugo, para já é pura curiosidade no Swift. Instalei o Xcode 6 beta e nem o 
>>>> abri. :(
>>>> Vou vendo alguns exemplos para ir aprendendo alguma coisa e partilho com 
>>>> vocês os que acho importantes.
>>>> Estou a terminar um projecto (MoneyEX Pro) e só no início do próximo ano 
>>>> começarei a trabalhar com o Swift. 
>>>> 
>>>> Att,
>>>> 
>>>> António Pinto
>>>> 
>>>> No dia 04/09/2014, às 16:10, Hugo Ferreira <[email protected]> 
>>>> escreveu:
>>>> 
>>>>> APintex,
>>>>> 
>>>>> Acabei à pouco tempo de ler 2 bons livros de desenvolvimento Android.
>>>>> Já desenvolvi diversas ANE's para Android e já me sinto suficientemente 
>>>>> confortável para desenvolver qualquer app para Android ou mesmo ANE.
>>>>> 
>>>>> Em breve gostaria de entrar no desenvolvimento nativo para iOS (tanto 
>>>>> apps como ANE's) e aqui ficam algumas dúvidas:
>>>>> 1. Não faz sentido nesta altura do campeonato investigar em Objective-C 
>>>>> (thank you god);
>>>>> 2. Será que não vale a pena esperar por um bom livro que seja uma 
>>>>> compilação do desenvolvimento Swift (de preferência em PT). Ainda não vi 
>>>>> nenhum na Fnac;
>>>>> 3. Será que irá ser possível desenvolver ANE's com swift. Penso que aqui 
>>>>> a única coisa que falta é a lib que actualmente é para Objective-C (para 
>>>>> alguém transcrever tem de saber bem Objective-C) ou será possível usar a 
>>>>> actual ?
>>>>> 
>>>>> As minhas expectativas são:
>>>>> - Dentro de 1 ano o iOS8 tenha mais de 80% de market share para valer a 
>>>>> pena;
>>>>> - Existam bons livros e exemplos;
>>>>> - Exista um lib para Swift (a Adobe tem de fazer) ou ser possível usar a 
>>>>> actual (não sei);
>>>>> - Exista uma framework para Bluetooth LE (para mim é importante) tal como 
>>>>> já existe com Objective-C ou se possa usar as actuais.
>>>>> 
>>>>> 
>>>>> 
>>>>> 2014-09-04 15:58 GMT+01:00 APintex Gmail <[email protected]>:
>>>>>> 
>>>>>> António Pinto
>>>>>> [email protected]
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> http://realm.io/news/swift-enums-pattern-matching-generics/
>>>>>> 
>>>>>> Sign up to be notified of future videos
>>>>>> 
>>>>>> We won’t email you for any other reason, ever.
>>>>>> 
>>>>>> Enums (0:40)
>>>>>> 
>>>>>> Enums are a kind of abstraction that allow you to give a variable one 
>>>>>> value among several related values. For example, when building a state 
>>>>>> machine you could have an enum that describes the state of an object 
>>>>>> from a set number of states. There are three types of enums in Swift.
>>>>>> 
>>>>>> Basic Enum (1:12)
>>>>>> 
>>>>>> The most basic Swift enum simply has a bunch of cases and is declared 
>>>>>> using the enum key word. In this example, the enum is called Direction 
>>>>>> and can only be one of the four provided cases. To declare an enum, you 
>>>>>> use the enum name, followed by a dot and then one of the possible 
>>>>>> values. Unlike in Objective-C or C, enums are not typedefs of aliases 
>>>>>> for integers.
>>>>>> 
>>>>>> enum Direction { 
>>>>>>   case North 
>>>>>>   case South 
>>>>>>   case East 
>>>>>>   case West 
>>>>>> }
>>>>>> 
>>>>>> let myDirection = Direction.North
>>>>>> Raw Value Enum (2:00)
>>>>>> 
>>>>>> The second type of Swift enum is a “raw value” enum, which is the same 
>>>>>> as the basic enum but has additional raw values associated with each 
>>>>>> case. In this enum Title, each case has an associated string that is the 
>>>>>> name for the title. Important to note is that the raw value and the enum 
>>>>>> itself are not interchangeable. The toRaw and fromRaw methods help to go 
>>>>>> between the value and the enum.
>>>>>> 
>>>>>> enum Title : String { 
>>>>>>   case CEO = "Chief Executive Officer"
>>>>>>   case CTO = "Chief Technical Officer"
>>>>>>   case CFO = "Chief Financial Officer"
>>>>>> }
>>>>>> 
>>>>>> let myTitle = Title.CEO 
>>>>>> let myString : String = Title.CEO.toRaw() 
>>>>>> let anotherTitle : Title = 
>>>>>>   Title.fromRaw("Chief Executive Officer")!
>>>>>> For integer type raw enums, integer numbering remains implicit if you do 
>>>>>> not specify values. Swift automatically counts up from the last provided 
>>>>>> explicit value. This can be seen in the following example:
>>>>>> 
>>>>>> enum Planet : Int { 
>>>>>>   case Mercury = 1
>>>>>>   case Venus, Earth, Mars // 2, 3, 4 
>>>>>>   case Jupiter = 100
>>>>>>   case Saturn, Uranus, Neptune // 101, 102, 103 
>>>>>> }
>>>>>> Associated Value Enum (3:52)
>>>>>> 
>>>>>> The third type of enum is one with associated values. Each case in the 
>>>>>> enum can carry associated data. In this example from the Swift book, the 
>>>>>> bar code enum allows you to associate different QR codes with different 
>>>>>> strings.
>>>>>> 
>>>>>> enum Barcode { 
>>>>>>   case UPCA(sys: Int, data: Int, check: Int) 
>>>>>>   case QRCode(String) 
>>>>>> }
>>>>>> 
>>>>>> let myUPC = 
>>>>>>   Barcode.UPCA(sys: 0, data: 27917_01919, check: 2) 
>>>>>> let myQRCode = 
>>>>>>   Barcode.QRCode("http://example.com";)
>>>>>> Associated values are especially useful in handling JSON, because arrays 
>>>>>> and dictionaries are actually types. Thus, you can create an enum to 
>>>>>> represent a JSON structure as a tree, with JSON nodes wrapping different 
>>>>>> types.
>>>>>> 
>>>>>> enum JSONNode { 
>>>>>>   case NullNode 
>>>>>>   case StringNode(String) 
>>>>>>   case NumberNode(Float) 
>>>>>>   case BoolNode(Bool) 
>>>>>>   case ArrayNode([JSONNode]) 
>>>>>>   case ObjectNode([String:JSONNode]) 
>>>>>> }
>>>>>> 
>>>>>> let x : JSONNode = .ArrayNode( 
>>>>>>   [.NumberNode(10.0), 
>>>>>>   .StringNode("hello"), 
>>>>>>   .BoolNode(false)])
>>>>>> Switch Statements (Pattern Matching) (6:17)
>>>>>> 
>>>>>> Switch statements is where most of the pattern matching functionality in 
>>>>>> Swift comes from. A basic switch statement looks very similar to an 
>>>>>> Objective-C switch statement, where there is a clause followed by cases. 
>>>>>> Two things to note: Swift switches don’t have breaks, so for old style 
>>>>>> fallthrough behaviour, your code must have an explicit use of the 
>>>>>> keyword fallthrough. Switch statements must also be comprehensive, so 
>>>>>> default cases are required, which may help prevent errors.
>>>>>> 
>>>>>> let value = 10
>>>>>> switch value { 
>>>>>> case 10: println("ten") 
>>>>>> case 20: println("twenty") 
>>>>>> case 30: println("thirty") 
>>>>>> default: println("another number") 
>>>>>> }
>>>>>> Ranges (8:35)
>>>>>> 
>>>>>> In Swift, you can also pattern match on anything that’s comparable. You 
>>>>>> can even match strings now to a case (and printout emojis for a fun 
>>>>>> parlor trick!). Anything that can be compared with the double equals 
>>>>>> operator can be matched. Swift also allows matching on ranges, where 
>>>>>> ranges can be the pattern inside a switch state.
>>>>>> 
>>>>>> let v: UInt = 10
>>>>>> switch v { 
>>>>>> case 0...9: println("Single digit") 
>>>>>> case 10...99: println("Double digits") 
>>>>>> case 100...999: println("Triple digits") 
>>>>>> default: println("4 or more digits") 
>>>>>> }
>>>>>> Tuples (9:00)
>>>>>> 
>>>>>> Tuples are composite data types - they contain multiple elements that 
>>>>>> can all be of different types. A tuple is then represented by the types 
>>>>>> of its elements. In this tuple-based switch statement, a tuple is the 
>>>>>> input. Each element in the pattern tuple is actually a sub-pattern, so 
>>>>>> you can match against patterns in each element. The underscore 
>>>>>> represents a “I don’t care” value. In this example, the last case 
>>>>>> functions as a default because the (_, _) says the same thing as a 
>>>>>> default - none of the other cases match, and we don’t care about other 
>>>>>> possible values.
>>>>>> 
>>>>>> let person = ("Helen", 25) 
>>>>>> switch person { 
>>>>>> case ("Helen", let age): 
>>>>>>   println("Your name is Helen, and you are \(age)" + " years old") 
>>>>>> case (_, 13...19): 
>>>>>>   println("You are a teenager") 
>>>>>> case ("Bob", _): 
>>>>>>   println("You are not a teenager, but your name" + " is Bob.") 
>>>>>> case (_, _): 
>>>>>>   println("no comment") 
>>>>>> }
>>>>>> Binding in Cases (10:56)
>>>>>> 
>>>>>> If you have case statements, there may be associated data that needs to 
>>>>>> be used in the case statement body. The let binding is how you can do 
>>>>>> that. The first two cases in this example take the tuple elements and 
>>>>>> create the bindings X and Y to represent those elements.
>>>>>> 
>>>>>> let myTuple = ("abcd", 1234) 
>>>>>> switch myTuple { 
>>>>>> case let (x, y): 
>>>>>>   "The string in 'x' is \(x); " + "the integer in 'y' is \(y)"
>>>>>> case (let x, let y): 
>>>>>>   "Another way to do the exact same thing"
>>>>>> case (_, let y): 
>>>>>>   "We don't care about the string in 'x', " + "but the integer in 'y' is 
>>>>>> \(y)"
>>>>>> }
>>>>>> Enums (12:22)
>>>>>> 
>>>>>> You can also switch on enums, but for enums with values wrapped inside, 
>>>>>> switch statements are the only way you can access those values. The 
>>>>>> following switch statement uses let to bind each case and use the value.
>>>>>> 
>>>>>> enum ParseResult { 
>>>>>>   case NumericValue(Int) 
>>>>>>   case Error(String) 
>>>>>> } 
>>>>>> 
>>>>>> let a = ParseResult.NumericValue(1) 
>>>>>> switch a { 
>>>>>> case let .NumericValue(v): 
>>>>>>   "Success; numeric value is \(v)"
>>>>>> case .Error(let err): 
>>>>>>   "Failed; error message is \(err)"
>>>>>> }
>>>>>> Types (13:20)
>>>>>> 
>>>>>> The main type of switch is the type/sub-class pattern. If your switch 
>>>>>> conditional in this clause is a class, then class will have sub- or 
>>>>>> superclasses. In this example, the UIView is matched against the 
>>>>>> different possible types of views: UIImageView, UILabel, and 
>>>>>> UITableView. The “as” keyword differs from the “is” keyword in that “as” 
>>>>>> allows you to use the let binding and do something with myView, while 
>>>>>> “is” is used simply to check the type.
>>>>>> 
>>>>>> let myView : UIView = getView() 
>>>>>> switch myView { 
>>>>>> case is UIImageView: 
>>>>>>   println("It's an image view")
>>>>>> case let lbl as UILabel: 
>>>>>>   println("It's a label, with text \(lbl.text)") 
>>>>>> case let tv as UITableView: 
>>>>>>   println("It's a table view, with"+ " \(tv.numberOfSections()) 
>>>>>> sections") 
>>>>>> default: 
>>>>>>   println("It's some other type of view") 
>>>>>> }
>>>>>> where clause (14:33)
>>>>>> 
>>>>>> Another important thing about switch statements is the where cause. This 
>>>>>> clause can be added to any case and acts as a boolean expression that 
>>>>>> returns true or false. The case is then taken only if this where clause 
>>>>>> returns true. This switch example relies not on pattern matching but 
>>>>>> instead on these where clauses, following through with the case if 
>>>>>> myView is of a certain size or other characteristic.
>>>>>> 
>>>>>> let myView : UIView = getView() 
>>>>>> switch myView { 
>>>>>> case _ where myView.frame.size.height < 50: 
>>>>>>   println("Your view is shorter than 50 units") 
>>>>>> case _ where myView.frame.size.width > 20: 
>>>>>>   println("Your view is at least 50 units tall," + " and is more than 20 
>>>>>> units wide") 
>>>>>> case _ where
>>>>>>   myView.backgroundColor == UIColor.greenColor(): 
>>>>>>   println("Your view is at least 50 units tall," + " at most 20 units 
>>>>>> wide, and is green.") 
>>>>>> default: 
>>>>>>   println("I can't describe your view.") 
>>>>>> }
>>>>>> Expression Operator (15:28)
>>>>>> 
>>>>>> A final important feature in Swift is the expression operator.
>>>>>> 
>>>>>> func ~=(pattern: Type1, value: Type2) -> Bool
>>>>>> This operator takes the pattern and the value, and then uses pattern 
>>>>>> matching to return true or false. It can be overloaded as well to 
>>>>>> implement custom matching behaviour. The following piece of code is 
>>>>>> Swift pseudo-code to demonstrate what you could build. In an array four 
>>>>>> elements long, you could create cases that matched any combination of 
>>>>>> the elements.
>>>>>> 
>>>>>> let myArray = [1, 2, 4, 3]
>>>>>> switch myArray { 
>>>>>> case [..., 0, 0, 0]: 
>>>>>>   doSomething()
>>>>>> case [4, ...]: 
>>>>>>   doSomething() 
>>>>>> case [_, 2, _, 4]: 
>>>>>>   doSomething() 
>>>>>> case [_, _, 3, _]: 
>>>>>>   doSomething() 
>>>>>> case [_, _, _, 3]: 
>>>>>>   doSomething() 
>>>>>> default: 
>>>>>>   doDefault() 
>>>>>> }
>>>>>> Expression Patterns (17:42)
>>>>>> 
>>>>>> The following extended example is a custom implementation of the pattern 
>>>>>> match operator. This custom operator turns the elements of an array into 
>>>>>> the enum values.
>>>>>> 
>>>>>> enum WCEnum { 
>>>>>>   case Wildcard 
>>>>>>   case FromBeginning 
>>>>>>   case ToEnd 
>>>>>>   case Literal(Int) 
>>>>>> }
>>>>>> 
>>>>>> func ~=(pattern: [WCEnum], value: [Int]) -> Bool { 
>>>>>>   var ctr = 0
>>>>>>   for currentPattern in pattern { 
>>>>>>     if ctr >= value.count || ctr < 0 { return false } 
>>>>>>     let currentValue = value[ctr] 
>>>>>>     switch currentPattern { 
>>>>>>     case .Wildcard: ctr++
>>>>>>     case .FromBeginning where ctr == 0: 
>>>>>>       ctr = (value.count - pattern.count + 1) 
>>>>>>     case .FromBeginning: return false
>>>>>>     case .ToEnd: return true
>>>>>>     case .Literal(let v): 
>>>>>>       if v != currentValue { return false } 
>>>>>>       else { ctr++ } 
>>>>>>     } 
>>>>>>   } 
>>>>>>   return true
>>>>>> }
>>>>>> Protocols (21:06)
>>>>>> 
>>>>>> In order to understand generics, you have to understand protocols, which 
>>>>>> are something that existed in Objective-C as well. Protocols are 
>>>>>> basically a contract that can define nothing at all or any number of 
>>>>>> methods and properties. However, protocols can’t have any implementation 
>>>>>> details - they can only have method signatures and property names. 
>>>>>> MyProtocol in this code defines just one property as requiring a getter 
>>>>>> and setter, as well as one method.
>>>>>> 
>>>>>> protocol MyProtocol { 
>>>>>>   var someProperty : Int { get set } 
>>>>>>   func barFunc (x: Int, y: Int) -> String
>>>>>> }
>>>>>> Types can conform to none, one, or multiple protocols. Protocols can 
>>>>>> also inherit from other protocols, thereby getting all the parent 
>>>>>> protocol’s methods and properties.
>>>>>> 
>>>>>> Conformance (23:18)
>>>>>> 
>>>>>> With protocols, you can make classes, structs, and enums conform to 
>>>>>> them. By making a type conform to a protocol, you are telling the 
>>>>>> compiler that your type will match the definitions set in the protocol. 
>>>>>> MyClass conforms to MyProtocol in providing implementations that match.
>>>>>> 
>>>>>> class MyClass { 
>>>>>>   // Nothing here... 
>>>>>>   // This won't compile!
>>>>>> }
>>>>>> 
>>>>>> class MyClass : MyProtocol { 
>>>>>>   var myProperty : Int = 0
>>>>>>   // Property conformance 
>>>>>>   func barFunc (x: Int, y: Int) -> String { 
>>>>>>     return "\(x) + \(y) = \(x + y)"
>>>>>>   } 
>>>>>>   var someProperty : Int { 
>>>>>>   get { 
>>>>>>     return myProperty
>>>>>>   } 
>>>>>>   set { 
>>>>>>     myProperty = newValue 
>>>>>>   } 
>>>>>>   } 
>>>>>> }
>>>>>> Uses (24:06)
>>>>>> 
>>>>>> There are a few reasons you may want to use protocols. The first reason 
>>>>>> is parent-child relationships, where you don’t want all the children to 
>>>>>> have a specific class of a parent. For example, UITableView comes with 
>>>>>> Cocoa and is a list of objects that specifies the number and content of 
>>>>>> cells. For the delegate to provide that information, it just has to 
>>>>>> implement the protocol which has methods for the cells. This way, you 
>>>>>> can avoid specifying the delegate as a sub-class of a class.
>>>>>> 
>>>>>> A second major use for protocols can be seen in the Swift Standard 
>>>>>> Library, where they add functionality to a type, piece by piece. 
>>>>>> Equatable, LogicValue, and AbsoluteValuable are all protocols that are 
>>>>>> implemented by different types in the library. The LogicValue protocol 
>>>>>> has a method that takes an object and turns it into true or false, so if 
>>>>>> you create a custom type and implement this protocol, you can use that 
>>>>>> type in an if statement’s clause.
>>>>>> 
>>>>>> One final use for protocols is to allow different types to be described 
>>>>>> by the same generic type parameter. For example, if you wanted to put 
>>>>>> different types into an array, you could give the objects a protocol and 
>>>>>> then declare the array with the protocol. You then have an array of 
>>>>>> equatables and anything that conforms to the equatable in that array can 
>>>>>> be added.
>>>>>> 
>>>>>> protocol JSONType { } 
>>>>>> extension String : JSONType { } 
>>>>>> extension Float : JSONType { } 
>>>>>> extension Bool : JSONType { } 
>>>>>> extension Array : JSONType { } 
>>>>>> extension Dictionary : JSONType { } 
>>>>>> 
>>>>>> let b : Array<JSONType> = [10.1, 10.2, "foo"] 
>>>>>> let a : Array<JSONType> = [10.0, "bar", false, b]
>>>>>> Generics (28:36)
>>>>>> 
>>>>>> Generics did not exist in Objective-C. THey are basically the statically 
>>>>>> typed languages’ answer to the flexibility of dynamically typed 
>>>>>> languages. Generics are used to allow you to use the same code for 
>>>>>> different types. The type parameter allows you to do this generically.
>>>>>> 
>>>>>> func swapItems<T>(inout this: T, inout that: T) { 
>>>>>>  let tempThis = this 
>>>>>>  this = that 
>>>>>>  that = tempThis 
>>>>>> }
>>>>>> With generics, you can also enforce more constraints, as in the 
>>>>>> following example. The “: Equatable” allows you to constrain T to any 
>>>>>> type that conforms to Equatable, or is valid with the double equals 
>>>>>> operator.
>>>>>> 
>>>>>> func firstAndLastAreEqual<T : Equatable> 
>>>>>>  (someArray: Array<T>) -> Bool { 
>>>>>>  let first = someArray[0] 
>>>>>>  let last = someArray[someArray.count - 1] 
>>>>>>  return first == last 
>>>>>> }
>>>>>> You can also use generics for either functions or type declarations. 
>>>>>> Type information is available at runtime, which is helpful. The compiler 
>>>>>> can optimize by creating specific versions for each type that’s being 
>>>>>> used (like C++ templates), but it can also fall back to the generic 
>>>>>> implementation.
>>>>>> 
>>>>>> Extended Example (33:56)
>>>>>> 
>>>>>> In the extended example, the goal was to create a function that was 
>>>>>> typesafe and could handle every case that involved the following types: 
>>>>>> Array, Dictionary, SquareMatrix, TreeNode. The function was to take a 
>>>>>> collection of one of the above types, take an array, and append the 
>>>>>> items in that collection to the array.
>>>>>> 
>>>>>> A protocol was defined to specify that a type can give back all of the 
>>>>>> elements inside of it. You have containers that can implement 
>>>>>> “AllElements”. On a generic level, you might need to know the type of 
>>>>>> the elements inside the collection, and so a wildcard is called 
>>>>>> “ElementType”. And so, you specify the element type when you implement 
>>>>>> the function itself.
>>>>>> 
>>>>>> protocol AllElements {
>>>>>>   typealias ElementType
>>>>>>   // Return an array containing all the objects 
>>>>>>   // in the collection
>>>>>>   func allElements() -> Array<ElementType> 
>>>>>> }
>>>>>> Another thing you can use is the NilLiteral protocol, the point of which 
>>>>>> is to take nil and turn it into something equivalent to nil in that 
>>>>>> type. For an int, it would return 0, or maybe for a string, it would 
>>>>>> return “”. In the following example, you would want it to return 
>>>>>> something of type self.
>>>>>> 
>>>>>> protocol NilLiteralConvertible { 
>>>>>>   class func convertFromNilLiteral() -> Self
>>>>>> }
>>>>>> Extensions then add methods, computed properties, and protocol 
>>>>>> conformance to existing types. Array and SquareMatrix are both fairly 
>>>>>> straightforward - you just return the arrays themselves. For the 
>>>>>> Dictionary, you iterate through all the elements, create a buffer, and 
>>>>>> return it with the elements inside. Finally, for the tree, you go 
>>>>>> through the tree in a recursive traversal and again add the elements to 
>>>>>> a buffer.
>>>>>> 
>>>>>> Put together, the final function appendToArray calls AllElements and 
>>>>>> gives “a”, which is an array with all the elements on the source. Then 
>>>>>> each of those elements is just added to the array in “dest”. This works 
>>>>>> because the generic argument “T” has to implement AllElements, and U has 
>>>>>> been constrained to the same type as T. The where clause is included in 
>>>>>> case you want to do more than have this type implement one protocol. 
>>>>>> Before the where, you declare type arguments, which can conform to 
>>>>>> either one or none protocols. If you want T to conform to 2+ protocols, 
>>>>>> add a “where” clause to constrain. You can then constrain any free type 
>>>>>> arguments you declared earlier and any associated types associated with 
>>>>>> the type arguments via protocols (e.g. T.SomeType).
>>>>>> 
>>>>>> func appendToArray 
>>>>>>   <T: AllElements, U where U == T.ElementType> 
>>>>>>   (source: T, inout dest: Array<U>) {
>>>>>>   
>>>>>>   let a = source.allElements() 
>>>>>>   for element in a { 
>>>>>>     dest.append(element) 
>>>>>>   } 
>>>>>> }
>>>>>> 
>>>>>> var buffer = ["a", "b", "c"] 
>>>>>> appendToArray([1: "foo", 2: "bar"], &buffer)
>>>>>> Now you’ve created five methods for this one process. In actuality, you 
>>>>>> would have your containers implement Sequence and use a for-in loop to 
>>>>>> go through all the elements. This requires knowledge of Generators, 
>>>>>> EnumerateGenerators, and other material.
>>>>>> 
>>>>>> Q&A (46:05)
>>>>>> 
>>>>>> Q: In the extension example, are we extending all arrays of anything?
>>>>>> Austin: Yes, which is why this is a bad idea in practice. You can’t 
>>>>>> actually say that you only want arrays with JSON type objects to also 
>>>>>> implement JSON array, which is needed to ensure that you have valid JSON.
>>>>>> 
>>>>>> Q: Is the type T built-in? Where does it come from?
>>>>>> Austin: T is actually coming from the declaration of array. If you 
>>>>>> command-click an array in XCode, the declaration of the array shows that 
>>>>>> it declares a generic argument T that has some constraints.
>>>>>> 
>>>>>> Q: Is there any kind of trace for generics and the way it works? Is it 
>>>>>> traceable to an existing language or is it brand-new?
>>>>>> Austin: I don’t know the answer, but I’m sure there are precedents. 
>>>>>> Generics in Swift kind of de-emphasize object oriented programming 
>>>>>> because they’re built more around protocols than around class 
>>>>>> hierarchies. You might get a closer procedent if you looked at Haskell.
>>>>>> 
>>>>>> Q: What is the exclamation point used for?
>>>>>> Austin: The exclamation mark is for optionals. Everything in Swift is 
>>>>>> non-nilable by default, so if you want to set something to nil, it must 
>>>>>> be declared as an optional. The question mark after the type signifies 
>>>>>> this. Then, the exclamation mark, or bang, takes the value out of the 
>>>>>> optional so you can use it.
>>>>>> 
>>>>>> Q: Is there something like value template parameters in Swift? Or should 
>>>>>> we just type in, type template?
>>>>>> Austin: I don’t think so, I don’t think Swift generics are as powerful.
>>>>>> 
>>>>>> Q: Can you explain let? It seemed like it would sometimes check the case 
>>>>>> and othertimes it would set it to the constant.
>>>>>> Austin: A let pattern kind of matches everything, but also takes a value 
>>>>>> and puts it in the constant for later use. When we use “as”, it both 
>>>>>> checks the type and also puts it in the constant.
>>>>>> 
>>>>>> Sign up to be notified of future videos
>>>>>> 
>>>>>> We won’t email you for any other reason, ever.
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> -- 
>>>>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da 
>>>>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do 
>>>>>> Grupos do Google.
>>>>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, 
>>>>>> envie um email para [email protected].
>>>>>> Para publicar uma mensagem neste grupo, envie um email para 
>>>>>> [email protected].
>>>>>> Visite este grupo em http://groups.google.com/group/riapt.
>>>>>> Para mais opções, visite https://groups.google.com/d/optout.
>>>>> 
>>>>> 
>>>>> -- 
>>>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da 
>>>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do 
>>>>> Grupos do Google.
>>>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, 
>>>>> envie um email para [email protected].
>>>>> Para publicar uma mensagem neste grupo, envie um email para 
>>>>> [email protected].
>>>>> Visite este grupo em http://groups.google.com/group/riapt.
>>>>> Para mais opções, visite https://groups.google.com/d/optout.
>>>> 
>>>> 
>>>> -- 
>>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da 
>>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do 
>>>> Grupos do Google.
>>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, 
>>>> envie um email para [email protected].
>>>> Para publicar uma mensagem neste grupo, envie um email para 
>>>> [email protected].
>>>> Visite este grupo em http://groups.google.com/group/riapt.
>>>> Para mais opções, visite https://groups.google.com/d/optout.
>>> 
>>> 
>>> -- 
>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da 
>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do 
>>> Grupos do Google.
>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, 
>>> envie um email para [email protected].
>>> Para publicar uma mensagem neste grupo, envie um email para 
>>> [email protected].
>>> Visite este grupo em http://groups.google.com/group/riapt.
>>> Para mais opções, visite https://groups.google.com/d/optout.
>> 
>> -- 
>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da Comunidade 
>> Portuguesa de Rich Internet Applications - www.riapt.org" do Grupos do 
>> Google.
>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, 
>> envie um email para [email protected].
>> Para publicar uma mensagem neste grupo, envie um email para 
>> [email protected].
>> Visite este grupo em http://groups.google.com/group/riapt.
>> Para mais opções, visite https://groups.google.com/d/optout.
> 
> -- 
> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da Comunidade 
> Portuguesa de Rich Internet Applications - www.riapt.org" do Grupos do Google.
> Para anular a subscrição deste grupo e parar de receber emails do mesmo, 
> envie um email para [email protected].
> Para publicar uma mensagem neste grupo, envie um email para 
> [email protected].
> Visite este grupo em http://groups.google.com/group/riapt.
> Para mais opções, visite https://groups.google.com/d/optout.

-- 
Recebeu esta mensagem porque está inscrito no grupo "Mailing List da Comunidade 
Portuguesa de Rich Internet Applications - www.riapt.org" dos Grupos do Google.

Para anular a subscrição deste grupo e parar de receber emails do mesmo, envie 
um email para [email protected].
Para publicar uma mensagem neste grupo, envie um e-mail para 
[email protected].
Visite este grupo em http://groups.google.com/group/riapt.
Para mais opções, consulte https://groups.google.com/d/optout.

Responder a