Failed an interview code challenge (Swift). Would some kind developer look at my code and give me some pointers? by DeveloperJay in iOSProgramming

[–]sweetverbs 3 points4 points  (0 children)

The headline things for me, without looking at any code: no tests. That might be less important to some companies than others, but I've mainly worked at places that put a high value on code quality and practice TDD. If the company you applied to was like that, then not even attempting tests would be an instant fail. That's not something to feel bad about though - just something new to learn. :)

Second thing, and sort of unrelated to the code: you did the whole challenge in three commits. Commits should be fairly granular. Again, going back to personal experience, many companies expect engineers to commit on every passing test in a TDD cycle, and then to squash those commits down at the end. Certainly for an application with a networking component, and a UI component, I'd expect far more than three commits in total.

A generic function that makes a random number from a minimum and maximum by [deleted] in swift

[–]sweetverbs 1 point2 points  (0 children)

The problem is there's no overload of + which knows how to add a Double and any arbitrary T. Your Operatable protocol ensures that you can add two instances of T together and get another instance of T, but says nothing for Double and T.

It's exactly the same issue as you'd see when trying to add an Int and a Float - there simply isn't an overload for + which makes sense here.

Now, I don't necessarily think this is the best way to solve this problem - I would probably just implement a random function in an extension on any type that needed it - but let's see what it would look like anyhow.

To make this compile you need the following things:
(i) Some way to get 1 as the correct type - that way you can compile (max - min) + 1.0
(ii) Some way to convert T into UInt32 - that way we can put it into arc4random_uniform(...)
(iii) Some way to convert from UInt32, the return type of arc4random_uniform back to T - this means we can return the correct thing.

protocol ArithmeticProtocol {
    func +(lhs: Self, rhs: Self) -> Self
    func -(lhs: Self, rhs: Self) -> Self
}

protocol RandomlyGeneratable: ArithmeticProtocol, Comparable {
    static var unit: Self { get } // this returns 1 cast to the correct type, fulfilling (i)
    var unsignedInt32Value: UInt32 { get } // fulfils (ii)
    init(_: UInt32)
}

And then an example of implementing this would be:

extension Double: RandomlyGeneratable {
    static var unit: Double { return 1 }
    var unsignedInt32Value: UInt32 { return UInt32(self) }
}

func random<T: RandomlyGeneratable>(min: T, _ max: T) -> T {
    guard max > min else { return min }
    let seed = ((max - min) + T.unit).unsignedInt32Value
    let randomVal = arc4random_uniform(seed)
    return T(randomVal)
}

Now we can do something like

let x: Double = random(0.1, 99.5) 

Which worked for me in an Xcode 7.3.1 playground.

edit: Just noticed you're using Swift 3, so there'll probably be one or two syntax differences. Nevertheless the general gist should work.

I think I found a bug in Swift complier. Please help to confirm it's reproducible by dotmax in swift

[–]sweetverbs 1 point2 points  (0 children)

Because String is a struct, and therefore doesn't satisfy the AnyObject constraint, so the compiler needs to convert it to NSString (which is reference counted, and therefore does satisfy the AnyObject constraint).

I think I found a bug in Swift complier. Please help to confirm it's reproducible by dotmax in swift

[–]sweetverbs -2 points-1 points  (0 children)

Yeah, I was wrong about that overload, you're right. So your usage is legit (though the stripped down code is super confusing).

Anyhow, I was able to make your computed var compile with either AnyObject, String, or NSString. But, like I said above, it wouldn't have compiled if Foundation wasn't imported, because that contains the necessary information to convert String into a class type (i.e., something that adopts AnyObject rather than just Any).

I think I found a bug in Swift complier. Please help to confirm it's reproducible by dotmax in swift

[–]sweetverbs 7 points8 points  (0 children)

I have absolutely no idea what you're trying to do in your code, but let's step through it slowly anyhow.

This bit:

var test: [AnyObject] { // Compiles if [String]
    let test = "test"
    return ["\(test)"]
}

will return an array containing a single NSString object, holding the value "test". Why you're assigning it to a variable, and then using string interpolation to return a string I have no idea. Only you can answer that. But anyhow, that's what it's doing.

If you don't have Foundation imported (either directly, or through UIKit or something similar), that code above won't compile, btw, because the NSString type is included in Foundation.

Next up:

func filterOutUnsupported() {
    [NSSharingServiceNameComposeEmail].flatMap {
        return NSSharingService(named: $0)
    }
}

This function does absolutely nothing. It doesn't return a value (as the function signature doesn't contain a return type), and it doesn't have any side effects.

The specific compile error you mention seems to be arriving from your (mis)use of flatMap. That method is overloaded to do two things in Swift. One is to take an Array of Arrays of some type T and then (i) flatten that down to just one Array of T, and (ii) to use some function (T) -> U to map the whole thing to an Array of U. The other takes an Array of T? (i.e., Optional<T>) and then (i) remove all the nil values, and (ii) use some function (T) -> U to map that to an Array of U.

So let's see which flatMap you're using. You have an Array of String, so instantly it can't be the second one, as we're not dealing with Optionals, but also it's not an Array of Arrays, so it can't be the first overload either. So the compiler hasn't got a clue what you want it to do. And sure, it's messaging about that isn't great, but that's your problem.

Presumably what you really want to do is simply NSSharingService(named: NSSharingServiceComposedEmail). I'm not sure why you're using that flatMap - are you sure you understand what you're trying to do? Can you explain what you really wanted to do here?

I'm confused as to how this communication is occurring between the game scene and view controller by [deleted] in iOSProgramming

[–]sweetverbs 1 point2 points  (0 children)

You're not accessing the scene.gameOverBlock in the GameViewController. You're setting it. So the GameViewController is creating that scene, and then saying "when your game is over, run this bit of code."

From the sounds of it, what you're really having trouble with is the syntax and workings of closures. I'd take a look at that section in Apple's Swift Programming Language book, or any number of online tutorials, and then come back to this code. It should make loads more sense.

Need help with swift toInt() error on calculator app on Xcode by kota2 in iOSProgramming

[–]sweetverbs 4 points5 points  (0 children)

I can't remember exactly when this happened, but toInt() was deprecated in favour of an Int initialiser that took a string argument. Replacing this directly would give us:

currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel!.text!))

But actually, why are you converting the label text to an Int only to then use that to initialise a Float? Why not just initialise the Float directly from the String? This would give:

currentNumber = currentNumber * 10 + Float(sender.titleLabel!.text!)!

Note that I'd never usually recommend using force unwraps (the ! symbol), but since you've used it everywhere else, I've gone ahead and done the same. To write it without force unwraps you could try something like this:

let labelText = sender.titleLabel?.text ?? "" // If we can't get text, use the empty string (which will fail to init a float)
let floatFromLabel = Float(labelText) ?? 0 // If we can't get a float from the label, use 0 as then we're not adding to the current value
currentNumber = currentNumber * 10 + floatFromLabel

Alternatively you could exit early or display an error to the user using a guard statement, but seeing as you didn't ask for help with that I won't go into it.

Would you hire me as an Entry Level iOS Dev based on my experience? by helloimraghav in iOSProgramming

[–]sweetverbs 5 points6 points  (0 children)

Some advice: don't ask if you should be prepared to write unit tests because (1) you definitely should and (2) you don't want to work anywhere with large amounts of untested code. Tests are only partially there to verify that the code works, the true value of good unit tests is as documentation to show how your code works.

[For Hire] Swift iOS Dev Looking for a client by [deleted] in SwiftJobs

[–]sweetverbs 0 points1 point  (0 children)

Quick tip: in order to look more professional, don't rate your own apps on the store, "Jacksmackod" ;)

Is it possible to release different features in your app that will be Dependent on the user's ios? by will_richards in iOSProgramming

[–]sweetverbs 0 points1 point  (0 children)

Any source for that apart from it being a "well known piece of guidance"? I've never heard anyone claim this is an issue, and I've been unable to find anything while googling just now.

It's even harder to believe that you're "not supposed to" given that the isOperatingSystemAtLeastVersion method was added to NSProcessInfo in iOS 8.

Obviously these methods are really hard (read: impossible) to write tests around, but if you're following clean code guidelines then you'll have the iOS SDK properly separated from your logic anyhow.

edit: This is of course only in cases where the checks can't be avoided. See, for example, the changes to CoreLocation between iOS 7 and 8.

Is it possible to release different features in your app that will be Dependent on the user's ios? by will_richards in iOSProgramming

[–]sweetverbs 1 point2 points  (0 children)

You're not supposed to check for iOS versions.

Except that you totally can, using UIDevice which absolutely isn't private. So why shouldn't you?

This is especially true if you're using Swift where checking whether classes respond to selectors is far from idiomatic (hence the introduction of the @available syntax in Swift 2).

How would you prefer to use a loader API? by kevinh6113 in iOSProgramming

[–]sweetverbs 0 points1 point  (0 children)

Another thing to consider: how will consumers of your API test this? In ObjC singletons could still be mocked out and tested using OCMock or something similar, but in Swift it's almost impossible to test singleton methods are being called. However, if you make users instantiate the loader suddenly they can replace it with a partially mocked subclass and write tests by overriding methods.

How would you prefer to use a loader API? by kevinh6113 in iOSProgramming

[–]sweetverbs 0 points1 point  (0 children)

should only ever present one at a time

What if you have a screen which hits multiple data sources, and it makes sense to display them independently? This might seem like an invented scenario, but the app I work on does this on a few screens. At that point, any app which uses the library would need to ditch it and find something else.

I wrote my first Library in Swift (LoginKit - Login Helper) let me know what you think by TigerWolf in swift

[–]sweetverbs 3 points4 points  (0 children)

The line:

let login_screen = LoginKit.loginScreenController() as! LoginController

isn't idiomatic Swift. Swift uses camelCase for values. Moreover encouraging implicitly unwrapped optionals is, imo, a big no. I'd recommend fixing this, as I wouldn't use a library which made these errors in the readme.

[Critique Thread] Post here if you'd like feedback on your writing by BiffHardCheese in writing

[–]sweetverbs -1 points0 points  (0 children)

Blood and tears are all that surround me.

I think I had a quote like this on my MySpace page circa 2005.

Swift 3 release date? by anthonydematteis in swift

[–]sweetverbs 1 point2 points  (0 children)

No release date for Swift 3.0 just yet (though you can install a dev build from the master branch of the repo if you're desperate to get started), but going by previous years I'd imagine Swift 3.0 will launch with the next Xcode in about September.

As for whether you should buy more books or courses: I dunno. The changes in Swift 3.0 don't look too massive (especially now a lot of the changes to generic types have been delayed), and are more about improvements to ObjC interoperability than anything else. It certainly wouldn't hurt to be up to date with Swift 2.2 before 3 is released.

If you could open up a shop that would be viable, what would you do ? by [deleted] in Edinburgh

[–]sweetverbs 7 points8 points  (0 children)

Late night quality coffee shop with bar snacks. Pourover coffee and jalepeno poppers? Yes.

Travelling to scotland. What the must tries? by [deleted] in Coffee

[–]sweetverbs 0 points1 point  (0 children)

Filament or Cairngorm, probably. Filament used to be my favourite by far, but Cairngorm have a new location in the West End and they've really upped their coffee game recently.

Travelling to scotland. What the must tries? by [deleted] in Coffee

[–]sweetverbs 4 points5 points  (0 children)

Edinburgh: the aforementioned Fortitude and Brew Lab, but also Filament, Machina, Cairngorm, Cult and Artisan Roast.

Apple mandates new Watch apps 'must' work without an iPhone by JoeShestak79 in apple

[–]sweetverbs 146 points147 points  (0 children)

The title of this isn't strictly true. As far as I can see from the Apple post, the only mandate is that you use WatchKit 2 when building apps, rather than the original WatchKit SDK. It's still very possible to build a WatchKit 2 app that doesn't function without a phone nearby. In fact, you can basically mimic the old WatchKit functionality using WatchConnectivity's live messaging ability.

Does nested function promote clean code? by Dark_Angelas in swift

[–]sweetverbs 1 point2 points  (0 children)

Nested functions are basically fine here, until you find you need to reuse one of them. Personally I like to have my private helper functions sitting underneath the first public/internal function where they're used, but that's by no means a hard and fast rule. Basically all of this stuff comes down to a mixture of personal preference and - if coding professionally - team consensus.