iOS app Development with Xamarin and F#
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 170 | |
Author | ||
License | CC Attribution - NonCommercial - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/50856 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
NDC Oslo 2014151 / 170
2
3
5
6
8
11
12
16
21
22
23
27
31
35
37
42
43
45
47
48
49
50
52
54
56
57
58
61
65
66
67
71
74
77
80
81
83
84
85
87
88
89
90
91
94
95
96
97
98
100
102
107
108
112
114
115
116
118
120
121
122
123
126
127
128
130
133
135
137
138
139
140
141
142
143
144
145
147
148
149
150
153
155
156
157
158
159
160
161
162
163
166
169
170
00:00
Digital filterElectronic mailing listFundamental theorem of algebraPartition (number theory)Parallel portType theoryComputer configurationPattern matchingDefault (computer science)Operator (mathematics)Type theoryComputer configurationFundamental theorem of algebraOrder of magnitudeSpacetimeDefault (computer science)Electronic mailing listOperator (mathematics)Maß <Mathematik>Game theoryLevel (video gaming)Product (business)Sheaf (mathematics)Multiplication signWave packetTransportation theory (mathematics)Pattern matchingCodeMathematicsGreatest elementRight angleCompilation albumCompilerLogicPairwise comparisonComputer fileMobile appArmData storage deviceFigurate numberException handlingInformationSlide ruleGroup actionIterationBitCASE <Informatik>Control flowSoftware developerString (computer science)Ocean currentFunctional (mathematics)MereologyPeer-to-peerPattern languageObject (grammar)HierarchyNumberFitness functionWeb pageResultantFilter <Stochastik>Form (programming)Projective planeMetreSpeech synthesisReliefOffice suiteFamilyPoisson-KlammerWeightAdditionChainMappingGraphical user interfaceGodWindowBuildingInternet service providerAndroid (robot)Computing platformC sharpF sharpMedizinische InformatikCryptanalysisGoodness of fitLambda calculusComputer fontBus (computing)QuicksortEnumerated typeoutputDifferent (Kate Ryan album)Natural numberComputer animation
09:41
Maß <Mathematik>Data typeInferenceSynchronizationProcess (computing)Formal languageExecution unitCloningData structureParallel computingInternet service providerBitType theoryMaß <Mathematik>Goodness of fit
10:34
Module (mathematics)Open setOpen sourceTask (computing)Interactive televisionError messagePhysical systemString (computer science)Complete metric spaceBuildingReading (process)Computer fileComputer hardwareSimulationWindowSource codeGastropod shellExecution unitThread (computing)Stack (abstract data type)RWE DeaSimultaneous localization and mappingMenu (computing)Digital filterElectronic mailing listType theoryTable (information)Category of beingFunction (mathematics)SequelInternet service providerType theoryGame theorySet (mathematics)BitRadical (chemistry)Maß <Mathematik>DivisorWell-formed formulaCodeDegree (graph theory)Connected spaceSingle-precision floating-point formatLine (geometry)CASE <Informatik>PhysicalismPoint (geometry)Computer virusMeasurementIntegerTask (computing)Service (economics)Numbering schemeEndliche ModelltheorieArrow of timeLevel (video gaming)Row (database)DatabaseUniform resource locator2 (number)Focus (optics)String (computer science)Descriptive statisticsComputer configurationComplete metric spaceTable (information)Equaliser (mathematics)Server (computing)Multiplication signProjective planeProcess (computing)Civil engineeringSystem callElectronic mailing listEntire functionExecution unitCoefficientFlow separationDefault (computer science)Computer animation
17:04
Function (mathematics)Disk read-and-write headField (computer science)Error messageHash functionExecution unitGlass floatBuildingComputer fileWindowMathematicsKnotQuery languagePhysical systemParticle systemDirectory serviceModule (mathematics)Menu (computing)Interactive televisionMaxima and minimaPhysicsFreewareSpacetimeIRIS-TProduct (business)Online helpBroadcasting (networking)Partial derivativeNumeral (linguistics)Service (economics)QuarkGauge theoryString (computer science)Maß <Mathematik>TouchscreenQuicksortType theoryInternet service providerString (computer science)Game theoryExecution unitPixelMetreNumberSoftware bugMeasurementCodeDegree (graph theory)Universe (mathematics)Particle systemPhysicalismDivisorFreewareFamilyDialectWell-formed formulaInformationElectronic mailing listFigurate numberDot productTraffic reportingWeb pageContext awarenessGraph (mathematics)WebsiteCalculationBitComputer animation
23:14
Computing platformIRIS-TFundamental theorem of algebraTouchscreenAreaMaxima and minimaMaß <Mathematik>Table (information)Latent heatView (database)Matching (graph theory)Projective planeBitMenu (computing)Electronic mailing listGame controllerCodeBit rateEvent horizonGame theoryDependent and independent variablesWindowPower (physics)Line (geometry)Internet service providerStatement (computer science)Context awarenessProcess (computing)Rule of inferenceVideo gameCycle (graph theory)Numbering schemeNumberData conversionMultiplication signQuery languageInternetworkingFlagType theorySlide ruleMobile appPlanningFormal languageInheritance (object-oriented programming)Point (geometry)Structural loadWeb pageTask (computing)Group actionLink (knot theory)1 (number)Cartesian coordinate systemSoftware developerAdditionControl flowGrand Unified TheoryHookingLevel (video gaming)Data miningCryptographyCross-platformBound stateDiagram
32:24
BuildingService (economics)Type theoryInteractive televisionError messageExecution unitMeta elementString (computer science)Gauge theoryModule (mathematics)Hill differential equationFunction (mathematics)Touch typingComputer hardwareWindowComputer fileLevel (video gaming)Physical systemClique-widthThread (computing)Online helpRandom numberField (computer science)System callExploratory data analysisDrum memoryTrailRule of inferenceGame theorySoftware testingFilter <Stochastik>Group actionPrice indexMultiplication signForcing (mathematics)BitGame controllerInformationSheaf (mathematics)CodeAsynchronous Transfer ModeFlagMathematicsSquare numberFunctional (mathematics)IntegerSet (mathematics)WindowComputer configurationoutputUtility softwareData miningComputer fileCountingMobile appNumberArray data structureTotal S.A.Android (robot)TheoryElectronic mailing listTesselationRandomizationBound stateClique-widthGraphics tabletView (database)WhiteboardDebuggerTrailCASE <Informatik>TouchscreenAlgorithmInheritance (object-oriented programming)Uniformer RaumType theorySystem callGradientBit rateWeightFigurate numberProduct (business)Coma BerenicesAlpha (investment)Dot productComputer animation
41:48
WindowComputer fileTunisFunction (mathematics)System callLine (geometry)WhiteboardField (computer science)BuildingView (database)Maxima and minimaNumeral (linguistics)PiGame theoryBound stateOnline helpGamma functionFrame problemExecution unitDecision tree learningComplete metric spaceWhiteboardView (database)Data miningOcean currentGame controllerSystem callGame theoryComputer fileGreatest elementFunctional (mathematics)CodeEvent horizonThread (computing)RecursionQuicksortoutputAsynchronous Transfer ModePattern languageOrder (biology)1 (number)Software developerDataflowComputer configurationSet (mathematics)Module (mathematics)Graph coloringState of matterCellular automatonNumberLine (geometry)Frame problemInformationGroup actionOperator (mathematics)Uniformer RaumLetterpress printingRight angleNewsletterRecurrence relationMultiplication signComputer clusterComputer animation
48:22
System callFunction (mathematics)Gamma functionMathematicsGenderGame theoryComputer hardwareWindowNumeral (linguistics)WhiteboardStatisticsNormal (geometry)Utility softwareOcean currentEvent horizonWhiteboardData miningCodePoint (geometry)MereologyLine (geometry)Game theorySet (mathematics)Bookmark (World Wide Web)Medical imagingQuicksortView (database)Cellular automatonCASE <Informatik>FlagPattern languageProper mapSystem callWell-formed formulaPattern matchingLevel (video gaming)Computer animation
52:28
TwitterBlogLogicMereologyForm (programming)Mobile appTwitterComputer animation
53:59
Computer animation
Transcript: English(auto-generated)
00:04
Hi, you guys. Hi! Welcome. I'm glad you're all awake after that party. I figured there'd be no one in this talk. I'm Rachel Reese. I work for the awesome Firefly Logic out
00:21
of Nashville. I moved to Nashville actually in December, and I think it took me three months to start an F Sharp user group. I like F Sharp a little bit. I also help run the
00:41
Nashville Xamarin user group. I'm one of the Lambda ladies' founders, which is a lot of fun, so yay, all of those things. My contact information is here if you guys want to check it out. My GitHub, I will have this talk, the slides posted, and everything, and in fact, except for the changes I made this morning, everything should be there at
01:03
least through last night. You guys can see what the talk looked like last night before I changed things even this morning. So that is it. I'm going to start with why you should even look at F Sharp. First of all, how many of you are even, say, current
01:25
iOS developers? Good. Good. How many of you are current Xamarin users? Yay. How many of you have looked at F Sharp at all? Yes. Good. Yay. Very good. Okay. So this does
01:40
not need to be as intro as I thought it might need to be. That is very good. That makes me happy. I'm still going to go quickly through this bit, but then we can actually spend a little more time looking at the iOS code. So why F Sharp? I have a few different testimonials here. The first, F Sharp offers us an order of magnitude increase in productivity.
02:06
Yen, I don't know if he's here because I can't see all of you guys and I can barely see anybody over in this section, but Yen is definitely at this conference. If he's here, you guys should definitely talk to him about this. He writes games with F Sharp, so go talk to him and make sure that everything I say is actually totally true. Because it
02:24
is. Obviously. This one specifically I wanted to add, the UI work is especially gratifying. F Sharp tends to get a lot of flack for not having the same level of UI tooling as C Sharp does. I have never found that to be an issue. It's an issue when you do
02:41
your very first file new project, hello world, and after that, like, with all of the projects that you guys probably write currently, you don't spend any time in the GUI. You're not using the GUI. You go back into the code where you can actually get things done. So except for that very first project, I have never found this to be an issue
03:01
for any reason. And I wanted to say, especially, it can be very gratifying. Because there's so much more that you can do, I think, with F Sharp. I want to make sure to just the basic fundamentals so that if you haven't seen F Sharp before, you're not totally lost. The forward pipe and back pipe are very, very, very important. They're pretty key.
03:24
You can do things like this. The 1 to 10 is how you create a list. You can pipe that into a list.filter. You're taking some data and sending that into a filtering function and you take the result of that filtering function and you send it into a mapping function and you take the
03:43
result. It's a way to chain on additional commands. Pretty basic. There's also significant white space. I really love that, personally. I find it cleans up the code a ton. There's not all of these extra curly brackets hanging around. All of this extra stuff.
04:05
One of the stories I like to tell, have you guys ever been sitting in your office and there's this light flickering off in the corner. And it's been like that all day. Finally somebody bangs on it or turns the light off and everybody in your whole, the
04:22
ten of you around you just breathe a sigh of relief. Oh, thank god that's off. I didn't realize how much that was upsetting me. Thank you for fixing it. That's how I felt moving from C Sharp to F Sharp. All of that cruft, it was just gone from my code. I could concentrate on what the code was actually doing, what was right in front of
04:44
me. All the good parts. So it's, you know, significant white space. It's also immutable by default. Just means you're, there is, you can do immutability, you can manipulate that way, but when you let a variable, a value, it is immutable naturally.
05:07
So, fundamentals option types. What can C Sharp do that F Sharp cannot? And Tomás is right there in the center. No reference exceptions. Option types are sort of the entire reason
05:24
you have no reference exceptions. They're similar to nullable ints. They're a lot different. A whole function be an option type can return some or none is the way it works.
05:43
When you pattern match on them, and I'll show you an example of this in a minute, you, it basically forces you to consider the null case right up front rather than having all these null checks littered throughout your code and maybe you forgot one because you weren't paying attention and you added in later after your code breaks at 3 a.m. and you
06:00
have to go in and handle fixing it, hopefully not directly in production, which makes it take extra longer. So, all of that is just handled for you right up front. You can use all of the map and filter and iteration and iter functions that I mentioned on the last page, you can use an option.iter to iterate through those, which means you
06:21
can pipe, pipe down, and using the option, which I find really nice and actually use kind of a lot. You can also nest them. You can have an option of an option type, which is kind of cool. You can also, you know, use discriminated unions.
06:41
This is the exact same code in C sharp over here as this one little bit of F sharp here, this discriminated union. This I actually couldn't fit all of what I needed onto the slide. I figured this font would be so tiny that you guys wouldn't be able to verify that it was roughly the same code. So, yeah. Discriminated unions are sort of
07:02
like enums. You can model in some ways, you can also use them to model, you know, smaller object hierarchies. You can pattern match on them. So you see I have that same, the same DU up there. I'm trying to pattern match. You can't quite tell because the warning takes up all of it. But I only have two. I have car and bus. I'm showing down here.
07:25
And it warns you when you forget one of the extra options. Sometimes that's okay. Sometimes you, you know, you had only wanted to do one and two, and you can add an underscore for,
07:40
you know, the extra options. It's only a warning. But if you add something else, if you decide to add a train into this list of transportations, you can. And then when you recompile, you'll get 15 compiler warnings saying this is incomplete, you need to fix your code right here. So you know instantly where your code has changed and what needs to be updated.
08:02
So, quickly, these are several reasons that, you know, things that I have covered this morning, why you might want to learn F sharp. The custom operators and the REPL at the bottom you can create your own custom operators. The more ridiculous one that I've heard lately is the fish. That's a valid operator. It's like eight characters or something. It's great.
08:27
And it does have a REPL. It's basically a command line. You can help work through your code. But I specifically wanted to list these things out. There are many, many other reasons why you'd want to learn F sharp. But these, because I knew a lot of you
08:43
guys would ask me about Swift. And I wanted you to see that there are a lot of things that are already in F sharp that Swift seems to be doing. So if you're interested in Swift, if you think, like, Swift is the most amazing new thing ever, then we have a lot of that stuff already. You know, they call their discriminated unions enums, and they are, but they
09:05
do have all of the extra features or many of them. So it seems to be a fairly direct comparison. However, there's a ton of stuff that Swift doesn't even have. The most important
09:20
one, I think, is that it's only single platform. F sharp, you can build Android apps. You can build, excuse me, Windows phone and Windows store stuff, especially, you know, using Xamarin. You can't get all of the rest of this stuff. Units of measure and type providers are my two favorite things. Going to look at those a little bit more closely.
09:47
But, I mean, the rest of these things are huge, huge features in F sharp that Swift, for example, doesn't have. Type providers, nobody else has. Mattias mentioned Idris
10:00
may have them. That may be true. I'm not sure. But type providers have been by far the, I mean, they've been in F sharp for two or three years. So there are tons and tons of them. And it's a place that F sharp really, I think, stands out. So I want to look a little closely at both type providers and units of measure. First, do you guys
10:24
have any questions about the basics? So we're all there. Good. So the most important
10:41
type provider for Xamarin and for iOS, I think, is the SQLite type provider. So if we run, I built a very basic, it's not, hmm, not fully feature complete, but I've started
11:02
to redo tasky, if you guys have seen the Xamarin basic example tasky. You can add new tasks. Come back. It will be down here. I'm obviously in the middle of this. It's not quite complete, so I'm lying a little bit. But I can update it as complete. It's
11:22
no longer there. If we go back to the terminal, it's SQLite 3, I think. See, I had this all set up. Never mind. I promise it is actually there and it is actually giving
11:47
them. So if we go back to give talk, I can actually delete it, and that is not deleting because that is bad. This was working this morning, and I blame
12:05
the restart that I had to do. But I promise you guys that it does actually work, I swear. The point with the type providers. Exactly. It's a SQLite problem, clearly.
12:26
So the awesome thing with type providers is that you basically just create the single line of code. Let's close that back down. You give a connection string, you declare that it is SQLite because the SQL data provider will work with SQL server and several
12:43
other. You give the path to the model.data.SQLite and you declare whether or not you want to use option types. In this case, I happen to know that it doesn't matter, so I'm not, but normally you would definitely want to do that. I created a task for stuff to come
13:02
back out, and then it's just SQL.getDataContext returns the entire database to me. I can grab the incomplete tasks here. I can filter them. What I'm doing is filtering for on complete. I map them into my record type, and I send back a list. I can add by creating a brand
13:25
new one and sending it to not be complete. The backwards arrow is how you assign so when things are mutable, that's how you handle it. So the new task, I add the description, and then I just call a submitUpdates. If you guys know C sharp, it should be terminology
13:43
that you're fairly familiar with. I can add, I can delete, I can update the same thing, just call. For delete, I call a task.delete. For update, it's the same thing. I modify the values and then I send in a submitUpdates. This is my entire data layer for Tasky,
14:02
all 44 lines of it. That's it. It comes back. It returns me type data. It's just there. It's just available. I don't technically need to map it into this record type. I can
14:32
show me. It's not the most useful, but this is basically the ID here, and so it will tell me that, you know, if this is complete, you can see, you know, it's an int64 down here.
14:46
Task is a string. It's an int64 because that's the default that's returned back. SQLite doesn't actually have boolean, so I have to use an integer. I'm sure there's a way to default it, but I'm wondering if that's something that still needs to be added in.
15:07
But you can see you can get IntelliSense right into your database and what's going on. It doesn't have the second individual step with SQL Server. It just lists out all of your tables and you can IntelliSense into all of your tables. I've used the same
15:28
and you decide to use it with some of your other projects. It's awesome. Completely awesome. It helps you not only is it easier to use, but it helps you actually explore. If
15:43
it's a brand-new job, you don't know what you're doing, the DBA handed you this, like, wall of what the SQL schema is. You can go in and try to yeah, which has never happened to me. You can go in and just IntelliSense in and explore around and see
16:02
what's connected to what. And it's really quite lovely. So that is the SQLite type provider. Units of measure. I think units of measure are especially important for things like game physics. If you're doing anything that is that might require a unit of measure,
16:29
here it's so units of measure are basically just a tag that you can add on to any integer. In this case, I've chosen to do, you know, degrees Fahrenheit, degrees Celsius, miles, kilometers, and hours. I'm calculating the wind chill factor for both the U.S. And Canada.
16:45
Obviously, those are different. The formulas in both cases are very, very similar. They just have basic different coefficients. But the thing that I found while I was researching this example and making sure I knew what the formulas were and I got it right was
17:03
that the U.S. and Canada have very simple wind chill formulas. They don't take into account humidity. These are only valid at very low humidity when the temperatures are already fairly cold. And that makes them able to discount several different extra pieces
17:32
of it at the end. Whereas the Australians have this massive, massive, takes up a whole page formula, but they can calculate the wind chill at, you know, 80 degrees Fahrenheit
17:46
or 35 degrees Celsius, which is something that Americans find very strange. I actually don't know what the Norwegians do. I have no idea if you guys calculate wind chill factor only when it's cold. It's always cold? Yeah. So it's always cold.
18:04
But even in the summer when it's not so cold. Totally fair. But the really nice thing about this, so I can actually run, let's bring this up a little bit. I can actually run
18:26
through this example and it will calculate, you know, minus 11 degrees Fahrenheit and minus 5 degrees Celsius. But if we change these values, like if we suddenly decide we want to take in Celsius for the wind chill U.S., it warns me right away that the unit
18:44
of measure C does not match the unit of measure F. That's because I have an F over here and it's telling you that this is coming in as a C and what on earth? What should we be doing here? It also warns me down here. Because, you know, wind chill is
19:01
not defined because it can't work out what units this should be. So it makes sure that all of your units are the same. I've heard hundreds, literally hundreds, and by literally I mean figuratively, billions of stories where somebody implemented units of measure, added it throughout their code and found a bug right away that, you know, they were
19:23
trying to mix, you know, meters and miles somewhere and it just wasn't working, obviously. The other interesting thing that I've seen, one of my friends has added, because it can be just any string that you add on to verify, you know, what this number coming in is,
19:44
they have to all be tagged with the same string. It doesn't have to actually be a specific scientific unit. It can be anything. So I've had people, I've seen them tag their games and whatnot with pixel to make sure that you know when you're changing something that is actually on the screen versus changing something that is a calculation underneath.
20:05
That sort of blew my mind when I saw it. It's, you know, it's not just for science. It's for tagging anything that you just want to make sure remains the same. And another one that I really love, another type provider, actually, sometimes the type
20:26
providers will come back already tagged with your units of measure. So this one takes the Freebase type provider. Do you guys know the website Freebase? It's basically a knowledge graph. There's hundreds, thousands of millions pieces of
20:42
information out there. You can hook into it the way you do most of the rest of the data context. Once you've done that, you know, data dot,
21:02
you have arts and entertainment, books, audiobook readers, individuals, you know, these people all have read audiobooks. You can go back, data dot, come on, the
21:30
example that I'm actually doing is, oh, here we go, you know, TV, have TV actors, Colbert Report episodes, that's kind of awesome. TV producers, there's a ton of information
21:47
to just play around with here. And you can, like I said, you can tell a sense into it. You can just explore, you can investigate and figure out what's going on. So here, I'm, you know, I'm getting all the particles in science and technology, physics, subatomic particles, I know what
22:07
I should have done. There we go. Subatomic particles, and I check whether or not, you know, it has a value, and then I just select the name of the particle, the electric charge, the spin and the particle
22:22
family. But this will come back if we look at the top of it, in coulombs. So it comes back already typed for us. If this was, like, if we were actually trying to use this specifically for a scientific
22:44
purpose and we wanted to have this list of things, you know, we know the charge already in coulombs. So you can mix and match the two, and much of the rest of the free base data comes back like this.
23:00
I find this incredibly powerful. There's, you know, a ridiculous amount of stuff that you can do with this. If we come back here, I want to make sure you guys realize there are just a couple type providers already available.
23:22
This is only some of them. I had, you know, a few more important ones for each talk, but if you go to the link here, if you open up my slides, there is a full list. And it's absolutely incredible and completely mind-blowing. You can add more than one in each of your
23:41
projects. It doesn't have to be just one or two. You can mix and match entirely. There's, you know, you can take data from OData and use the type provider and an RSS. There's a CSV one that I don't think I even have on here.
24:03
But it, you know, be creative with this. You can mix and match everything. There's all these different places to get data from. That's only some of them. It's huge. You can process with all of these different things. You can send stuff out to Python. If you have code already written in Python,
24:22
you can send out bits of data and get a response back. In fairness, I've not tried to use that one, but I've heard amazing things with it. I have used the PowerShell one. That one's kind of fun. You can actually get, you know, run PowerShell commands.
24:41
So if you needed data to be processed with something that's already written, then you can do that. You just hook it in with F sharp, get the data from somewhere, send it off to this, you know, your other bit of code to process it. And then you can visualize it. I don't know if any of you guys were in Matthias' talk who just spoke, but he showed an amazing example of grabbing data, looking at it with a CSV, and then plotting a whole
25:04
bunch of stuff with R. He actually, in 20 or something lines of code, made this wonderful heat map of the U.S. and some of the data. It was incredible. And it's so few lines of code.
25:21
I mean, the examples that I showed you, it's one query statement and a get data context. That's it. They just work. They bring back, you know, all of this type data. Yeah, it's just kind of incredible. So are we solid on type providers and units
25:42
of measure and how amazing they are and why you always want to use them always? You would have to do the conversion yourself. You would have to create a, you know, let's
26:03
convert Fahrenheit to Celsius. But you could totally, you could actually pipe it through so you can have your number or your few numbers and say, send to this method, get me the response back, and then send to the new one. So, yes. Yeah.
26:30
When I say that again, it will go out and so the question was if exactly.
26:45
Yes. For example, the WSDL type provider, which is the first one I used, personally, the WSDL type provider is my favorite, even though it's not as flashy as the others. But the rest of them, definitely. But that one I know will go out, look at the schema again and come back and say, you
27:03
know, these four things have changed. If there's additional data, it won't break your code. But if there is, if there's, you know, one of the methods has changed, it will notify you. You can, there are flags to say don't do this every time because it does require Internet
27:20
access to go back and forth. So if you're stuck somewhere like on a plane and you still want your code to compile, but you know you can't, you won't have access to it, there's also a flag to cache locally so that, you know, you're not forced to go check that every time. But, yes, it will update for you when
27:40
that's what you want. So in those constantly changing projects, I find it wonderful. Awesome. So let's move on. Why Xamarin? I had really wanted to have, you know, 15 slides on Xamarin and how wonderful and amazing it was. And this, like, there is nothing else to
28:03
say. Xamarin is fully native and it's cross platform. Why on earth would you not use it? I got nothing else. It's, you know, this is also why not to use Swift, why not to use phone gap. It is actually native.
28:21
You use the native controls. I'll show you guys my code here in a minute. But you have a native experience when your user is actually using your games. You write one language. I mean, yes, yes, you can write in C sharp, but you can write in F sharp and you can have fully cross platform code.
28:42
It's awesome. When you do a final new project with Xamarin, you will get an app delegate. If you're already an iOS developer, this should actually look fairly familiar. There's lots of UI prefaced things, and
29:03
that is, those are Apple native things. You have to inherit from the UI application delegate. You have to register the app delegate for the code to actually work. You create a window. It's a new UI window. You know, you have bounds that it has. You have to override the finish launching.
29:25
The only bit of code that you actually need to add in here is your first view controller. And if you wanted to put in a navigation controller so you have menu stuff at the top, then you add that new UI navigation controller around it.
29:42
So this will all happen for you in a final new project, except this one bit that you either have to, I will often go in and create an empty project. And so when I create my first view controller, I'll have to go in and add it here. If you do a specific kind of project, it will often just have it there.
30:03
I wanted you guys to see this, too, because this is where you will add in a UI navigation controller. But also, to look at it, this is F sharp. It's very short. It's very lovely, I think. And it should be fairly easy if you're familiar with the types.
30:26
The actual view controller, this is actually my tasky view controller. So, because it's a table, I have all of my table guts up at the top. That's why the line numbering starts at 31.
30:41
But you don't have to create a new UI table view. Here's how you handle events. I have this add new task here. At the top, I'm setting a navigation bar, one of those little plus to add a new item. I have my add new task here. The most, well, probably the most important thing for you to notice here is that you'll
31:05
inherit from a UI view controller and then just override the life cycle methods. If you did load, view will appear, view did appear, view will unload. There's a whole list of them. And you just go down your page and override all of them.
31:26
I have my table here that is my new table view. Once I've created a UI something, UI label or whatever, then you're going to want to add it to, set a frame and add it to the current view.
31:44
Does this code make sense to you guys? Do we have questions? Is it, that was a kind of. Let me run, actually, yes. So I wanted to show you guys Minesweeper. I don't know if you know the Minesweeper game.
32:06
It's a very basic little game that I think Microsoft had with Windows 3.1 maybe was the first time. But you basically go through and look for mines. You can, I will run and show you guys. We'll play a game or two.
32:32
It's quite fun. So it's a little, you know, there's a grid. You click on, it will show you, these numbers here are how many mines are anywhere around this grid.
32:47
So this one, there's a mine somewhere in this square of things that are directly around it. Which means it has to be this one here. And so we can flag it and say, okay, that doesn't do anything. You can flag and unflag. It's just a notifying to you so that you don't then go and click it.
33:04
I read something after I had written this game that apparently there was a backlash to this game somewhere maybe in Windows Vista. And they had an option to just look for flowers. Apparently this was much too violent for some people.
33:25
I actually thought of, well, not for very long, but I thought of adding a switch to have it go back and forth between the flowers. It had some flower garden or something, some lovely name, and you could actually decide which one you switched on.
33:42
So the little ax here will go and step through. Oh, my algorithm is not the best. So we have three there. And basically you just go through. Oh, actually this is going to four and then this one is totally, haha, I'm so close.
34:06
Yeah. Yes! When I was testing it, I actually totally refused to print out all of the numbers.
34:22
Once I had the back board finished and working, I refused to print out the back numbers so that to test the winning case I just actually had to win. I couldn't go through and, you know, force it and cheat and try to force it to win. So it took me a really long time to actually test that.
34:42
But if you click a, you know, it will also say you lose. So let's move this down a smidge.
35:01
The mind scooper code is basically two files. If we look at the solution, you know, there's the resources. I have my pictures in there. There's the info.plist and there's app delegate but I didn't have to change anything with app delegate. It's just literally the mind scooper controller.
35:23
So the two main files are this utils file and my mind scooper view controller. Utils I actually reworked after I first wrote this and I've managed to get rid of the monotouch references. So in theory someday very soon I can move this over to its own project and create an Android front end for it.
35:46
But this is basically the heart of the game. You know, at the top we set out the width and the height so you can change those if you want to make it 10 by 10. The total number of minds in that, that should probably be a little higher.
36:05
The button size and the button padding is, you know, these buttons here. Action mode just keeps track of what I'm doing here.
36:23
And I have two main types, mind scooper data and cleared data. The cleared data being that cleared button after you click on it. So for the mind scooper data I count the number of surrounding minds so that I can decide to display that number. I count whether or not it is a mine itself.
36:41
And then I have the coordinates, an I and J. For the cleared data I only need the surrounding minds. That's it. When I create it I can create it basically in exactly the same spot so I don't need to carry over the I and J. And if it's cleared then I will immediately lose the game if it was a mine.
37:00
So it's obviously not a mine. And there's no reason to track that information either. Filtering the indices is a short little method I wrote just to make sure when I'm clicking on one of these corner Wow, that was bad. One of these corner bits and it's going to clear the edges here.
37:21
It doesn't try to clear things that are outside the bounds. Getting all the neighbors basically filters, you know, takes this giant list of indices that is that square immediately around them and filters for things that are only valid indices. Or filters out things that are not valid indices.
37:44
Set minds and count neighbors here. I grab a new random. The mutable count minds is one of my only non-UI mutables which makes me very sad. But I have not found a way to get rid of that yet.
38:00
But it is there and I'm sorry for it. So the setting minds and counting neighbors, basically I figure out, I created a 2D array just a flat integers that is the size, the width and the height that I set up above.
38:23
And I call the set is mine function to determine whether or not this thing will be a mine. And I pass back this 2D array of 0 or 1 whether or not this is mine. I count the neighbors by looking at that array and for each spot on the 2D array
38:43
I create a new 2D array that basically has counted in all of those squares around. So for this one here, it will look at this spot, this spot, this spot, all over here and be like, well, there's only one mine which must be this one here. And so this will return a 1.
39:02
Here there will be 2, so probably this one is also a mine. And so, you know, there's 1 and there's 2 and then the rest of these return 0 because they are not actually a mine. So I have those two 2D arrays and I'm able to return both of them which is another really nice thing about F sharp.
39:20
I don't have to tuple these. I can just return both of them. And when I call them down here, when I'm, you know, this get clear board, I can just decompose them and have both of them available. So it's, I'm calling out mines and neighbors.
39:41
I immediately name them right there and that was lovely and beautiful. I call, I set this create data. I'm creating new minesweeper data for, you know, each set of the mines and neighbors that I just grabbed from here. And then I create board tiles by creating data for each, in a 2D array
40:03
of each one of those bits of information. Does that make sense? So that's just the back information there. There's not, that doesn't handle any of the UI. I'm not actually creating the buttons here. I'm not actually setting them anywhere on the screen.
40:22
This is just setting up the basic innards of the game. Let me go over to the view controller. This is where we get into all of the basic front end iOS stuff.
40:43
So we create these minesweeper buttons and the cleared buttons. It's basically the exact same thing as the minesweeper data and the clear data but I'm inheriting from a UI button. So these are now actual iOS controls, native iOS controls, with this minesweeper data or clear data as the bit of data that I'm passing along.
41:04
So the minesweeper view controller, like you guys saw, I inherit from the UI view controller. I set the action mode to digging to start. You don't want to start flagging because you don't know what to flag at the beginning. You want to start actually digging in and hope you don't die immediately.
41:24
They're right, that's not a gruesome game at all. This section here sets up the slider control. I have a handle segment changed here. The segmented control that, there's only two of them.
41:42
One segment is the flag, one segment is the axe. I specifically set the selected segment to one at the beginning. So that's this piece down here. And when the segment is changed, like I was just showing you guys, I set up this new event handler.
42:01
This funny little operator, I love this guy, that casts the sender into a UI segment control. There's an up cast and a down cast. So the other one looks like this, obviously if that one's wrong, but just so you guys know. And then I'm pattern matching here on the action mode.
42:23
So there's zero and one for the options. And then if for some reason that returns two because I've selected a third segment over here, which is crazy and scary, then I can call this fail with. And that will fail.
42:42
That will throw up a no such state and everything is terrible. Everything is handled and lovely. When I actually click on one of these, the button handler when I'm digging,
43:05
and when I don't lose, that will, and when I don't lose, obviously that will clear off and create the different cleared buttons that are a slightly darker color. You guys can't tell, but I'm totally clicking on it right now.
43:22
And there's no event click handler. So this is basically the method here that just converts the two back and forth. When I'm creating a brand new cleared button, I create that with the clear data mines.
43:40
I set the frame to be the frame that was the same frame as the clear button. So I'm basically, I destroy the old mine button that was there and I create a new cleared one in its place so that I'm not piling up a whole bunch of data, unnecessary UI controls over each other.
44:06
So I set the background color to dark gray. And then I declare what the picture should be. Either it's the number of mines or it's zero. On the viewDidLoad, I add the new slider control.
44:20
To start a new game, I call this method here. I declare a brand new, complete new UI view. I grab the, I get the board and I iterate over it and add all those pieces to the subview.
44:43
Or add them all as subviews. I add this view that I had created, I add it as a subview. And then once I do that, that hides the slider control. So I have to bring that back to front. That's something if you guys aren't current iOS developers, you'll sometimes need to do. Because all of the views sometimes will hide each other.
45:03
This one took me a while to figure out because the button is still there. It's still, it's below all of this stuff. But the view extends down to the bottom. So I was clicking on it and nothing was happening. I'm like, but this worked a minute ago. So you just sometimes will have to bring these things back to the front.
45:24
It's sort of like, and I don't think I do this on anything. But if you're iOS developers, you'll often go off into the background to do something and have to come back to the current UI thread to continue processing something when you're back on the UI. It's not totally like that, but it's a little like that.
45:45
So if you'll notice, I have a recursive minesweeper button clicked. And way down here, I have an and get new board. One of the ways F Sharp works is that you can only call functions that have been written higher in your code.
46:05
This is also true for file order. You can only call files and modules that are higher in your code than where you currently are. So because get new game board needed to, I don't recall where it is, needs to set up the button click handler, needs to call this line and call the button click method.
46:30
And in the button click method, if you fail the game or you win the game, then you need to get a new game board and start over.
46:40
Yeah, here's one of those. So they need to reference each other, which means they need to be created at the same time, which one of the ways of doing that is to have them be mutually recursive. Even though they're not actually recursive, they're not calling into themselves, but they do need to call into each other.
47:03
So that's why that one is recursive. The game over here basically removes the entire view, everything that was on it, disposes that entirely, creates this alert view with the text of you win or you lose,
47:22
and then gets a new game board. And it takes that get new game board and backpipes it into start new game. I don't have to use a backpipe here. I can use an extra set of parentheses, but a lot of F Sharp developers will tell you it just looks better. It helps you understand the flow a little better. I'm actually getting the new game board first,
47:41
and then I'm sending that information into start new game. And I could also just put that first into a forward pipe. I like this better because start new game is the more important thing that's happening here, even if it technically is the second thing. So you can see when you look at the beginning of this line that,
48:01
oh, I'm starting a new game. This clear cell is the method that's called when these are actually cleared. When I click something, that method is the one that's actually called.
48:24
So I grab all the neighbors to make sure I know what's around me. This is the switch button that I was talking about. So I remove the old Minesweeper button with all the big set of Minesweeper data,
48:41
and then I create this new cleared button, and I add that into the subview. So first I create this method, and then I go ahead and call it right away. Then if the data is a mine and all of the surrounding mines are zero, then I want to continue clearing.
49:05
So here, this example, all of these here also have zeros. So I definitely want to clear this one away. This one, not all of them have zeros, but I want to recursively clear down to this point.
49:22
So I find the current neighbors from here. I iterate through. This is why this one is actually recursive. I check the Minesweeper buttons, and I iterate through that if it's a current neighbor and continue to clear those cells.
49:43
The event handler, this is actually probably the heart of the proper code, because everything sort of happens on a button click. So again, I convert down to a Minesweeper button, and I have some pattern matching here.
50:01
So if I'm just flagging, so in the case where this is set to flag and I'm just toggling whether or not that shows a flag, then basically I toggle whether or not that shows a flag. It's pretty straightforward. If it's digging on the case when it is a mine,
50:22
so if it is specifically a mine, then instantly I lose. There's nothing else to consider. That's just it. But if I'm digging otherwise, then first I clear all of the cells. I remove subviews, the curtain button from the subview. I add the new cleared button for just that one button that I had actually clicked on.
50:43
And then if it's the case that this Minesweeper buttons only, this actually calls and checks that of the buttons that are left that are Minesweeper buttons and not cleared buttons, of all of those that are left, if those are all currently mines,
51:03
then I have cleared everything that is not a mine, and so I win. So I check if all mines are cleared, and if they are, then yeah, I win. The get new game board down here basically just looks for,
51:21
you know, it starts the game. I create the buttons. I set the Minesweeper button clicked handler. I set them to light gray. I set the image to null. I set the title to null. I make sure that everything is properly reset. And then I call get clear board from utils here
51:47
and map that onto create buttons. And then I call start new game and send in get new game board as the end of my view did load.
52:01
So there's all this setup. Another one of my favorite things about F sharp is there's sometimes all these crazy formulas, and it comes down at the end to that one little line of code. That goes and does all of the work of getting a new game board and then starts it.
52:22
And that's basically the full part of that. So I am done a smidge early. Do you guys have any questions for me? Does that make sense?
52:41
Does that answer all of your questions and make you want to go out and write a new app right away because it totally should? You can see it's very easy. There's not much code. I'm sorry. I totally can't see this part over here.
53:05
So the question was about Xamarin forms. I will be honest. I haven't looked at that. I think you can. And I'm sure there are some of the folks in the audience that can answer that, and I probably should have looked at that because I figured I would get a question on it. I know, if only.
53:26
Can we use Xamarin forms with F sharp? I will find out. Tweet to me later this afternoon,
53:40
and I'll mess with it and see what I can do. Sorry. Any other questions? All right. Then thank you guys very much.