Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added Extension for UIDevice #102 #104

Merged

Conversation

thorstenstark
Copy link
Collaborator

I'm not sure if the screen sizes fit in this extension, as both use the UIScreen class to get the informations.

@brototyp brototyp added the swift label Dec 20, 2016
@brototyp brototyp added this to the Swift 3 Rewrite milestone Dec 20, 2016
@brototyp
Copy link
Member

I'm not sure if the screen sizes fit in this extension, as both use the UIScreen class to get the informations.

Yeah. I understand that. Have you seen my thought over in the #102 ? Maybe the best idea is to move all those method in a separate Class Device. Therefore we don't fiddle around with an existing class and we can keep the screen size method/property.

@thorstenstark
Copy link
Collaborator Author

As mentioned in the #102 I moved these methods to a Context class.

Copy link
Member

@brototyp brototyp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you squash all commits into one?

}()

// Returns the screen size in pixels
static let physicalScreenSize: String = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather like to name it nativeScreenSize to match it with the nativeBounds. For physicalScreenSize I would expect it to be in centimeters or inch.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Changed it.

@mattab
Copy link
Member

mattab commented Dec 29, 2016

Can you squash all commits into one?

@brototyp Fyi Github now has this feature to let you squash all commits with the UI. So usually it's not needed to ask contributors to squash. Learn more here: https://github.com/blog/2141-squash-your-commits

@brototyp
Copy link
Member

Fyi Github now has this feature to let you squash all commits with the UI.

Yeah, right. Forgot that. I rarely use GitHub.

@@ -0,0 +1,115 @@
import UIKit

public class Context {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imho, having nested classes with only static members (all internally available) does not add any value.
We are using namespace to avoid clashes and Device and Application does not share any fileprivate code not visible to the outside.

I would just make a stand-alone Device struct (prefer struct over class, or make class final)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we make two structs 'Device' and 'Application' not nested in a 'Context'?! What do you think @brototyp ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only value nesting both into a "Context" is for the developer. This way we declare both as being some Kind of Context and grouping both together. I am fine with both.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I would go with the stand-alone Device struct.

public class Device {

/// The platform name of the device i.e. "iPhone1,1" or "iPad3,6"
static let platform: String = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using static methods make access to members more easy without passing around an instance.
However it is a bit like having singletons and might bite back if you ever need to mock the class in a unit test.

But I do not think that will be an issue here, so I would keep as is and refactor later the need arise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. So refactoring wise we should add something like a current singleton which then returns an Object with all the current values. This way we cloud instantiate a Device with mocked values.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will make a proposal for the variant with the singleton.

// TODO: implement me
}

public class Device {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this a struct

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding access control information (internal) to the top level type to be consistent with the other PR.
I think this code style guide is pretty good.
https://github.com/raywenderlich/swift-style-guide
https://github.com/github/swift-style-guide

case "iPad6,4": return "iPad Pro 9.7 (Cellular)"
case "iPad6,7": return "iPad Pro 12.9 (WiFi)"
case "iPad6,8": return "iPad Pro 12.9 (Cellular)"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Piwik SDK supposed to run on WatchOS and tvOS, too? Then we should add the proper device names here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea. Yes add them please.

@thorstenstark thorstenstark force-pushed the feature/swift-device-extensions branch from 4b54950 to da55a53 Compare January 8, 2017 14:10
@thorstenstark
Copy link
Collaborator Author

I added a version with a current singleton that holds the properties for the current device.


/// A human readable version of the platform name i.e. "iPhone 6 Plus" or "iPad Air 2 (WiFi)"
/// Or the platform name in case no human readable name was found.
let humanReadablePlatformName: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The human readable name could be a function that calculates the human readable version from the platform. And it could return an optional that is nil if no human readable version exists.

Copy link
Contributor

@minitrue22 minitrue22 Jan 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that returning an optional String is probably a good thing.
If the caller really needs a string it can do

let platformName = device.humanReadablePlatformName ?? device.platform 

But that is the callers responsibility not this struct.

let osVersion: String

// The screen size in points
let screenSize: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the size should be a CGSize.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree.

private static func currentNativeScreenSize() -> String {
let bounds = UIScreen.main.nativeBounds
return "\(bounds.size.width)x\(bounds.size.height)"
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those static methods with a current prefixed to irritate me a bit. A possible alternative would be a static method on Device that returns a new Device populated with values for the current device. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a factory method would be great.
Even so, I think it is good practice to write small functions. The methods above does exactly what they promise :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the method names a bit to remove irritation ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that!

let screenSize: String

// The screen size in pixels
let nativeScreenSize: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a CGSize as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree.

internal struct Device {

/// A shared instance holding the properties for the current device
static let current:Device = Device(platform: currentPlatform(),
Copy link
Contributor

@minitrue22 minitrue22 Jan 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest removing the static current and have a factory method that returns the current device

static func makeCurrentDevice() ->  Device {
  let platform = currentPlatform()
  ...
  return Device(platform: platform, ...)
}

I would only create a global shared instance later on if it becomes needed.
Most probably the "tracker class" can have a simple instance variable it can instantiate at construction by calling the static method above (reducing coupling and making testing more simple).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

internal struct Device {

/// Creates an returns a new device object representing the current device
static func makeCurrentDevice() -> Device {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not overly happy with the word make here but it's not a huge issue.

@brototyp brototyp merged commit d5570bd into matomo-org:swift3 Jan 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants