// this no longer works let a: String! = "asd" let b: String = "asd" switch a { case b: // error: expression pattern of type 'String' cannot match values of type 'String!' break default: break }
When upgrading my xcode from 8.0 to 8.1 and Swift to 3.0.1, I found that I can no longer compare type with implicitly unwrapped optional in a switch statement. I need to explicitly unwrap the optional
0 Comments
lately I had to deal with window layering and ordering is Swift. I had to make sure some windows are always on top of other windows. This can be done with window levels.
in objective-c I found that you can simply call [NSWindow setLevel] with defined values such as NSMainMenuWindowLevel. in Swift, these defines doesnt exist. we have to use CGWindowLevelKey enum However, this enum is not a value we can use directly for NSWindow.level. We have to convert it to a usable value by using CGWindowLevelForKey(), which returned an Int32. Since NSWindow.level is an Int, we also have to cast it to Int. window.level = Int(CGWindowLevelForKey(.normalWindow)) Here's the list of the values of CGWindowLevelKey sorted from bottom to top. At the time of this writing, these values are generated with Swift 3.0.1 and macOS 10.12 SDK baseWindow: -2147483648 minimumWindow: -2147483643 desktopWindow: -2147483623 desktopIconWindow: -2147483603 backstopMenu: -20 normalWindow: 0 floatingWindow: 3 tornOffMenuWindow: 3 modalPanelWindow: 8 utilityWindow: 19 dockWindow: 20 mainMenuWindow: 24 statusWindow: 25 popUpMenuWindow: 101 overlayWindow: 102 helpWindow: 200 draggingWindow: 500 numberOfWindowLevelKeys: 999 screenSaverWindow: 1000 assistiveTechHighWindow: 1500 cursorWindow: 2147483630 maximumWindow: 2147483631
let's say you want your Mac app to have multiple windows, pretty reasonable request right? Now, lets say you have 2 monitor setup on your Mac, and you like to have each window on its own screen. Move one window to the first screen, and move the other window to the second screen, got it. Now what if you want both to be full screened on each screen?
if you have this setting under System Preferences > Mission Control enabled, then you wont hit this problem. But if you're like me and have it disabled, you might be wondering why your secondary monitor stays black. keep on reading...
One of the key feature in MacOS is Spaces. It's that thing that you see at the top when you go to Mission Control (usually by pressing F3 in most Mac keyboard) that helps you organize and declutter apps windows.
The deal with the setting I mentioned in the beginning has to do with what happen when you attach a second, or third, or 'n'th monitor to your Mac. If you have the setting enabled, it will create a Space for each monitor. But if you disable it, all monitors will share the same space. This isn't really an issue until you want your app to be fullscreened. When a window is changed to full screen, MacOS will create a new exclusive space for it and move the window there. So when you make 1 of your window a fullscreen window, a new exclusive space will be created, and only your window will be placed there. To add your other windows to this fullscreen space, you need to do this to your window: window.collectionBehavior.remove(.fullScreenPrimary) window.collectionBehavior.insert(.fullScreenAuxiliary)
Recently I've had to go through the hellish task of upgrading my Swift 2 projects to Swift 3. tldr, 1000+ errors fixed later, I was left with 1 persistent error. command failed due to signal: Segmentation fault: 11
I've never seen this compiler error before, and preliminary research suggested that it's a possible bug in the swift compiler itself. Thankfully it tells me which file did the fault happened: While type-checking declaration 0x7fc447c12e00 at /Users/gietal/dev/project/source/Extensions/FileManager+Extensions.swift:5:8 It doesn't tell me where in the file did it breaks, but at least I had a starting point. Luckily this file of mine is not that huge, so I'm able to brute force isolate each functions in the file and found that the culprit is a very specific function declaration. This form of function declaration is the one that's causing the segmentation fault: public extension FileManager { public func foo() throws -> URLRelationship { return URLRelationship.other } }
I've found that omitting the throws keyword will avoid this error:
public extension FileManager { public func foo() -> URLRelationship { return URLRelationship.other } }
This is a very weird behaviour, since if I mark the function with the throws keyword and have it return anything else EXCEPT URLRelationship it will compile just fine. This only happens if the function is marked throws and returns a URLRelationship.
I've filed a bug to Apple regarding this, as I've found someone else had had a similar issue like this with Swift 2.2 before: http://blog.bellebethcooper.com/xcode-bug.html Anyway, this has been an annoying one to track. For now I will just have to workaround the issue by omitting the throws keyword and handle error thrown inside the function some other way. I hope this post can help someone else who ran into the same issue. If this doesn't help, at least I hope this can give you some ideas into where to start isolating your code to find the offending piece of code.
Learning swift for iOS and macOS development. I was creating a closure to sort strings reversely this way:
let reversed = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 })
The sort() function simply takes a function that takes 2 strings and returns a bool. What I didn't realize is the the "operator >" that I'm using on the closure is itself a function that takes 2 strings and return a bool.
So that chunk above can be reduced to: let reversed = names.sorted(by: >)
A couple months ago, I encountered an issue in which I have to perform some cleanup on one of my ViewModel. I know that there's an OnExit() function on the Application class, but I didn't know how to let my VM know from here without causing some tight coupling between the Application class and my VM (which is not ideal).
I gave up trying to solve it since I couldn't found a viable solution back then, and always put this bug aside. Today I decided to spend the day fixing this issue, and I did, with a lot of help from the internet. The solution was to use the EventAggregator in the PRISM 5 library 1. Make a singleton which contain the EventAggregator // singleton event system public static class EventSystem { public static IEventAggregator Instance { get { // ?? operator, return left if not null, otherwise, return right return m_Instance ?? (m_Instance = new EventAggregator()); } } private static IEventAggregator m_Instance; }
2. Create the Event to be broadcasted
public class ApplicationExitEvent : PubSubEvent<int> { }
3. Make my VM subscribe to the event
token = EventSystem.Instance.GetEvent<ApplicationExitEvent>().Subscribe( OnApplicationExit, ThreadOption.PublisherThread );
The ThreadOption CANNOT be UIThread, I guess since the UI is closed there's no more UI Thread.
The token is used to unsubscribe from the event (not shown)
4. Broadcast the event from Application.OnExit
protected override void OnExit(ExitEventArgs e) { // broadcast that we're exiting EventSystem.Instance.GetEvent<ApplicationExitEvent>().Publish(e.ApplicationExitCode); }
I wonder if I would've solved this issue a lot sooner if I know about EventAggregator beforehand (I didnt know about it before I found someone else's blog trying to solve the same issue)
Links that helped me: Last week, I went down to San Jose to help Jeremy host the VR Arcade Conference and meet most of the team from Virtual World Arcade for the first time. The conference was held on May 2 - 4 at Computer History Museum in Mountain View, California. Day 3 of the conference is Hackathon day. It's a day where everyone can try to develop game for each other's platform/techonology. Today is more of an experiment, to see whether or not companies are interested in this sort of idea. I only stayed for about 2 hours since my flight back to Redmond is at noon. However, according to Jeremy there weren't that many attendee since most people already got what they needed from day 1 and 2. At least now we know that we don't have to do the Hackathon day for next year's conference. Full Video: Last week, I went down to San Jose to help Jeremy host the VR Arcade Conference and meet most of the team from Virtual World Arcade for the first time. The conference was held on May 2 - 4 at Computer History Museum in Mountain View, California. The second day of the conference is where each company gave out a 45-60 minutes presentation about their company, technology, and vision. There are a lot of interesting talks, but the ones I find most interesting are the ones that talk about the problems and challenges they faced when building VR games. This post is going to be about the compilation of those problems that we are currently facing on our game "VR Jurassic Island", as well as the general rule of thumbs when making game for VR that I learned from the presenters. Minimum 60 Frames Per Second (FPS) This is the general rule when making VR experience. If the game runs under 60 FPS, it will usually make most people sick. Some people can handle as low as 30 FPS, but lower than that is pushing it. Our game did not have much optimization done, so it ran at a whopping 28 fps... There were times when people put the head gear on for 5 seconds and gave up. This was a wake up call for us. Dont F**k Around With The Camera We wanted to show a couple different scenes in our game. The first scene was where you have to hide from the lurking T-rex, while the second scene is on a lake where you can see a Brachiosaurus eating from a tall tree. We needed a way to take the player to the second scene, but they are pretty far apart in the game world. So we made a Magic carpet that moves the player to the lake scene, as if it's a vehicle. We had mixed feedback about it. Some people loved it, they said it made them feel like they're surfing. Others are either confused, dizzy, or worse, got motion sick. Another thing we did was to set 1 meter in real life to be 4 meter in game, since our game world is pretty big. This also triggers confusion and motion sickness to some people. The key learning here is to not modify the in game camera's position abruptly. If a user doesn't execute any movement but they see movement in game, it will mess with their brain's balance and visual system, which causes motion sickness. So just don't touch the damn camera. Don't Get People Lost/Confused When you start playing our game, you are dropped in the middle of a forest. Then suddenly a T-rex pop up. Do you fight it? Do you run? Do you hide? You don't know, since you don't even know the goal of the game. We learned that since we are essentially putting people on an "alternate reality", we need to give them time to assimilate this new world. We can't just assume they know what to do. They dont. We have to ease the experience in. Start with a very simple world, then bring the intensity up incrementally. Don't make an experience that want to make people run. Do you remember that moment when you're between dreaming and being awake? Where your dream is blending a little bit with your reality? According to the Zero Latency VR guys, it takes about 20 minutes for people to be immersed in VR games and starts to "forget" that they are in a virtual world. The Zero Latency VR guys did an experiment where they put VR headset to people and show them a familiar scene. They showed them an apartment scene, where everything is normal. Then, after a while and the player started getting comfortable with the scene, they changed the scene to be the top of a mountain. They then asked the players to jump off from the mountain. When the players refused, they know that they have gotten them immersed into the virtual world. Complete coverage of the second day: Last week, I went down to San Jose to help Jeremy host the VR Arcade Conference and meet most of the team from Virtual World Arcade for the first time. The conference was held on May 2 - 4 at Computer History Museum in Mountain View, California. This post is mainly going to be about the problems we faced while hosting this conference, and the things we learned. As this was our very first time hosting an event such as this, there are a lot of things we can improve on. The first day was for panel talks and exhibition. All the attending companies setup their booths and their tech to show some demo to the attendees. We came at 6 in the morning to setup our motion capture cameras, server, and calibrate them all, which took about 2 hours. The conference officially started at 9am. I manned our exhibition booth, showing attendees our game demo. However, around 9.30am, a couple of our volunteers who manned the registration booth had to go. So me and Patrick went to man the registration booth since there are still a lot of attendees coming in late. This was when I realized a HUGE problem. Problem #1: The Attendee list is not synced at all Essentially what we had was an excel spreadsheet filled with attendees information like name, email, company, confirmation number, etc. An attendee came and gave me her confirmation number, I tried looking up her confirmation number on the sheet and found nothing. I tried searching by name as well and still no luck. When I asked Jeremy about it his answer surprised me. "Oh, the spreadsheet was from 2 days ago, I stopped updating it since we were so busy". What do you mean you stop updating it? It should have been automated! This was a VERY BIG issue, and I'm glad we hit it. Clearly we need a system to automatically update the spreadsheet/database when someone registered online. Problem #2: What is when? After attendees are verified, we hand them out a map of the exhibition. The first thing they said after that was "Thanks! do you know what time is <insert company name> panel will be?" and unfortunately our answer would always be "you could view the event itinerary on the website". This makes me think that maybe we should hand out the day's itinerary on top of the map of the event. The venue was not that huge, so people should be able to figure out where things are. But people would most definitely like to know what is happening when. Problem #3: Do you guys have coffee? I think only Patrick is a coffee drinker in the team, so does 90% of the attendees. In the early morning when we were setting up our booths, one of the exhibitor asked if there's any coffee provided. Unfortunately the museum cafe was closed, so we directed them to the starbucks across the street, and we went back to whatever we were doing. A few minutes later, a different exhibitor asked the same question. And we started to think "maybe we should get coffee after all". long story short, I went to starbucks to get coffee for 50 people. Key Learning:
Day 1 video: A couple days ago, there was a seminar/training on cyber security at my workplace. The seminar reminded me of how little I know about cyber security. I looked around the internet for additional resources to increase my understanding on cyber security. In my findings, these resources helped me understand the basic of cyber security (without getting technical)
http://www.pbs.org/wgbh/nova/labs/videos/#cybersecurity they also have an interactive game to help understand how malicious hackers try to hack/steal information from you http://www.pbs.org/wgbh/nova/labs/lab/cyber/research#/newuser |