 Hello, let me start. Hi, I'm Samuel and I'm working for Crop Group and today I want to talk about the Suisly, one of the forgotten Objective C features. A lot of people are scared of it but it's actually a good thing to know about it. So one of the examples I want to give is that, imagine if you own a highway and you also have a sign board on the road, it says slow down, speedly means 5 km. And imagine you have a chance to change the road sign anytime you want it. So you don't have to go do the construction, hey I want to change something. So this is a simple example of what's exactly Suisly. Another example is actually, there's not been second ones because we didn't come to the point that we can actually agree on what is the meaning of Suisly. Second one is that, let's say you're on the lift, you select the level, that's a level 8. Instead of going to level 8, I take you to level 11 and I show you a C level 8. You assume that you're on level 8 without you actually knowing it. That's exactly what is Suisly. So in a simple definition, Suisly is a fact of changing the function of a method on the run time. So imagine you have a two method, function A and function B with the representative selectors. So on the run time you are able to change the selectors pointer to different methods. Well it's kind of dangerous, I agree, but it's a good thing to know about it before we actually say, oh it's scary, we're not never going to use it. So Suisly is a dirty hack, but in some situations it's the only solution to our problems. I will give an example why. Suisly works unfortunately only on objective C run time. What does that mean is that if you optimize your code for Suisly, you get a point, some objective C or dynamic variable into it. So basically objective C run time, everything in the function is going to be looks like this, objective C methods based on a C structs method. So basically methods is the selector that we use inside the objective C and method types are C string of the encoding parameters for return and passing parameters. And the last one is the method implementation which is pointing to your function. Object C2 on avoidable is actually a marker that indicates that the member is not avoidable and only provides something inside into the structure. So that's not really important in this part. So why using Suisly? The reason is that none of the Apple's frameworks are written in Suisly. That's true, none of the Apple's framework are written in Suisly. And many part of the are still running on objective C run time. My proof is this code. This actually can be found on Ruby code. I actually looked for a lot of the frameworks written by Apple and by just using O2, you can see what are the frameworks that use written in Suisly which is none. So now it's a good time to use Suisly in our run time. Who uses Suisly? Well, most of the good analytics, such as Mixpanel, they're used for A-B testing. Push notifications such as one signal and Firebase, if anyone use the Firebase, that's a good thing to know that they're actually what they're doing behind the scenes. And that's why API is, it used to be a good idea that back in the time used for unit testing used to use the new methods. Well, this part is safe because it's just for unit testing. And so how to use it? You need to create a method that will be in the new implementation. You can do it on fly or using a class method that create a new method on fly. Get the class representation, get the old implementation reference, and then get the new implementation reference at the same time and ask objects to sit on time to swap them for you. Very easy, right? So any class method that uses dynamic method can be Suisly and Suisly. I'm not suggesting to use objects parameter because since Suis 2.2, if you use it, this does not guarantee that your function going to go through the dispatch of object to sit on time. So it's good to stay safe, use always dynamic if you want to do Suisly. And using suit classes that are subclass of NS object that are guaranteed, they're going to use object to sit on time. So this is the example. Let's say you have a normal class, suit class. If you want this object, you should use dynamic function. This means that your method is going to be dynamically dispatched at the run time. Or just simply using this object. Oops, sorry. So how do we do it? It's very simple. We have API, which is, this is actually the object to sit. API bridge to suit, which is you get the class, get instance method of your class and your selector name. And you just swap them. Metal exchange. Very simple. So let me give you exact, very simple. You can do the action in the playground. So let me, in this example, I'm creating a simple class favorite color, which I'm going to store my favorite color and my second favorite color. So it's blue and my second is going to be red. No, it's PG. Yeah, probably group. So return the red color. All right. So I, I'm initializing the class and I'm just going to print out the top colors. So let's do the magic. Yeah, let's do the selectors. I'm not typing because I thought I'm going to make mistakes on the life. So I didn't want to take your time to. So class get instance method. And if you're outside your class, like it, this is my extension. So you always have to mention switch class reaction selecting. So favorite color does self adjust to get the class identifier. And this is the suicidal methods, or we can say a second method that you want to swap with it. And my second color can be, that's my second selector. So as I said, we just used to swap them. Well, it happens sometimes when you try to do them playground cause it to crash because you're actually using the object to see around time. But it works. Don't worry. So now if I try to call it my top colors, you're going to show red is actually my top color. Oh, yeah. See, if I put it dynamic, now is actually the object to see around time. So my second color now is blue. But so this is not a proper way to actually doing it. We always do inside a category classes or extension. So in objective C, we had a good thing used to call load function that you only call once in the classes loaded. But unfortunately if you don't have access to the load method, so you have to use initialize. So for that reason, we have to make sure that we only call whatever classes I initialize once. So we use a dispatch once to do the safety check that nothing goes wrong. And it's a good practice. Any time we do the reasoning, we always call back to the original method that has been called. Because imagine you're not the only one doing the reasoning. A lot of people doing the reasoning the same methods. So you're going to be messed up if everyone tries to do that. So I have an example. This is a normal app which has a tree view controller. You go inside and let's say you're tasked to create a analytics. Every time you go to a view controller, I want to print out what is the name of that controller. So the simplest method, you just go make that subclass of view controller or you create a protocol that calls to that methods, whatever you have in there to represent it. Or the easiest hack is to use it seriously. Which is not a good idea, but a lot of analytics are actually doing it. So I'm creating an extension of your view controller. And I'm making sure that this is not a subclass of the view controller because a lot of things are going to be represented. And I'm selecting the view view app here. Original view view app here of your view controller. And my seasonal method. So since I'm an extension, I have to create a method in here that I can call it. So let's call it new view view app here. So you should be exact same kind of method that is in the same parameter that I'm accepting here as the original selector. And creating a method which is get instance method. So here I can just call set because I'm in the extension class. And calling a selector. So this is the seasonal selector and seasonal method. So here we're swapping, sorry, original method with the seasonal method. So this is dangerous actually to run this one. As I said, we need to do the safety check so you will not run the same type of system every time. So we got to make sure we're using the dispatch once in this class. So we use the token in here. The color reference of the token. So there is a one hiccup. What if in the future apple start to removing view view will appear? So in order that doesn't happen, we use the class admittal. This function check if I can add this class. So it will return, this is actually class admittal return back here. Boolean. So if I can add this method which means this class doesn't exist, original method. So I can replace it with a new method which I created over here. If it does exist, which is already exist in the view view control, then you should do the method exchange get implementation. So class admittal. And this is the return back. And this is the part since the class already exists. I say class replace with a new method which takes the new selector and the old implementation. Just to make sure everything is already done perfectly. So I think there is an example inside too. I'm just going to clean up a little bit. So as I mentioned, the best practice is that any class we create can stop. So in my new view view will appear. I'm not going to say I'm at the Susan method and I'm also printing the name of the class. And this is the original view controller. I'll give you the custom one and all of the view control is part of this. I'm going to print out the statement and say I'm in the class. So you can see what are the results. You can see this is in your navigation control and other hierarchy as well you can see in here. So you can see that actually your Susan method get called and then you're in original class. So this part is okay. This is just the object you see since you already know it. So as I mentioned before is that the best practice is that you always call it original method as well. This is like a recursion. If you call yourself you're actually calling the original method. This could cause you a lot of trouble but it does not deserve this part because you've got to make sure that this is different on some class of that view controller you want. I'm just giving an example on your view controller. You can just go for any type of custom controller you want to do or sometimes you are alert that you want to do modification on it. So yes that's pretty much it. The next thing I believe is more or less is very relative is associated objects. So associated arbitrary values for the key on a runtime and add custom properties to the existing classes in category or extension. It define a key variable whose address we use as a key. So you know in a lot of example that in an extension of category we can have a property. We can store in a value. Not true. With the associated object which is a runtime you can actually store anything you want. Let's say in a UI alert you want to pass some custom parameters with an extension. You can do it with the associated object on a runtime. It doesn't have to be, your class does not have to be any sort of swift underline swift optimization. It doesn't matter. As long as you use associated object everything can be run on an object you see on time. So let's say I have a custom name string and I've created a struct method right inside my extension just to store a value and I'm setting the associated object and with the reference key to that name and I can get the value from it. Very easy. So this is my example class. So I have a sample class and let's make an extension out of it. So I want to create the name. The moment you do that you get a compiler that says the extension may not come to store properties. Which is a valid error but you can skip that part. So I'm adding a setting associated type. This is the reference to, so I have an outside string if you look at it. I'm just referencing to that one. And this is the object associated and non-atomic. Basically it's the object you see all those kind of reference that you have over here as well. So you have access to everything you want. And this is going back to the pointer and making sure that this is written in by as a string. So let's do a quick example. I create a name and I print it out. Ta-da. We have custom name in our extension. And final note. So do not suizzle Swift classes in Objective-C files. For some reason there are some weird behavior may occur because Swift tries to optimize your code and you're trying to break it down in Objective-C. So some weird behavior I notice that it happens. Do not suizzle everything. If you suizzle everything then your app is like a whole exception to trying to run your app. Be aware of multiple methods that suizzle the same method. Then this happens is all about race conditions. So which methods can I get called first? That's why I'm saying always call back to the original method so you won't break anything. So, any question? Yes. Can you write this for? This is the hardest part because this is a run time and a lot of shit could happen on a run time. So it's kind of hard but it's possible. I've seen a lot of people actually write tests for these things but it's hard. Actually if you look at the mix panel, the unit tests are writing tests for suizzling methods that they've done. But it's nothing that is not possible. It's possible. The moment you swap the code you just have to make sure that this code has been swapped. In a test you would suizzle at low set up test, right? Yes. Then throw away the object. Can be done. Crazy. It's crazy but it's nothing like you have to be scared every time when people say suizzle it's like oh my god but it's something cool that we all have to learn and it's a good thing to be kind of used at once in a lifetime. Alright that's from me and I pass it to my friends to watch. Thank you very much.