Skip to content

Commit

Permalink
Merge pull request #224 from gaelfoppolo/feature/add-swift-rules
Browse files Browse the repository at this point in the history
Add Swift rules from ecocode-ios
  • Loading branch information
dedece35 committed Dec 5, 2023
2 parents f9bb44a + 6ee598b commit e854f83
Show file tree
Hide file tree
Showing 19 changed files with 316 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- [#224](https://github.com/green-code-initiative/ecoCode/issues/224) Add Swift rules from ecocode-ios to ecocode-rules-specifications

### Changed

### Deleted
Expand All @@ -17,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- [ios#3](https://github.com/green-code-initiative/ecoCode-ios/issues/3) Move iOS rules into centralized rules repository
- [android#67](https://github.com/green-code-initiative/ecoCode-android/issues/67) Move Android rules into centralized rules repository
- [ios#3](https://github.com/green-code-initiative/ecoCode-ios/issues/3) Move iOS rules into centralized rules repository
- [#103](https://github.com/green-code-initiative/ecoCode/issues/103) Upgrade RULES.md: set proposed HTML rule "HTML page must contain a doctype tag" as refused with link to the justification
Expand Down
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC14/EC14.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Do not disable idle timer, unless absolutely necessary.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"eco-design",
"environment",
"sobriety",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
To avoid draining the battery, an iOS device that is left idle quickly falls asleep.
Hence, keeping the screen on should be avoided, unless it is absolutely necessary. If so, developers typically
disable the idle timer with `UIApplication.shared.isIdleTimerDisabled = true`.

## Noncompliant Code Example

```swift
UIApplication.shared.isIdleTimerDisabled = true // Noncompliant
```

## Compliant Solution

```swift
UIApplication.shared.isIdleTimerDisabled = false
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC15/EC15.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Setting a tolerance for timers will allow them to fire later than the scheduled fire date.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "1min"
},
"tags": [
"eco-design",
"environment",
"idleness",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Setting a tolerance for timers will allow them to fire later than the scheduled fire date.
The system will use this flexibility to shift the execution of timers by small amounts of time,
within their tolerances, increasing the ability to optimize power savings.
Your app can set the `Timer#tolerance` property to specify a tolerance for a timer.
Using this approach dramatically increases the amount of time that the processor spends idling
while users detect no change in system responsiveness.

## Noncompliant Code Example

```swift
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in } // Noncompliant
```

## Compliant Solution

```swift
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in }
timer.tolerance = 0.5
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC16/EC16.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Monitoring power changes and customizing behavior depending on battery level is a good practice.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "0min"
},
"tags": [
"eco-design",
"environment",
"power",
"ecocode"
],
"defaultSeverity": "Info",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
It's always good that an app has different behavior when device is connected/disconnected to a power station,
or has different battery levels. Your app can query the `UIDevice#batteryLevel` and
`UIDevice#batteryState` properties at any time to determine the level of charge and
the state of the battery. Your app can also register to receive notifications when the battery level
or state changes, using `batteryLevelDidChangeNotification` and batteryStateDidChangeNotification`.

## Compliant Code Example

```swift
let level = UIDevice.current.batteryLevel
let state = UIDevice.current.batteryState
NotificationCenter.default.addObserver(forName: UIDevice.batteryLevelDidChangeNotification, object: nil, queue: nil) { _ in }
NotificationCenter.default.addObserver(forName: UIDevice.batteryStateDidChangeNotification, object: nil, queue: nil) { _ in }
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC17/EC17.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Taking into account when the device is entering or exiting the power save mode is a good practice.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "0min"
},
"tags": [
"eco-design",
"environment",
"power",
"ecocode"
],
"defaultSeverity": "Info",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Use device API to check if low power mode is enabled, and adapt resources usage accordingly.
For example, you can reduce frequency of data update if low power mode is enabled.
Your app can query the `ProcessInfo.processInfo.isLowPowerModeEnabled` property at any time
to determine whether Low Power Mode is active. Your app can also register to receive notifications
when the Low Power Mode state of a device changes, using `NSProcessInfoPowerStateDidChange`.

## Compliant Code Example

```swift
let isLowPowerModeEnabled = ProcessInfo.processInfo.isLowPowerModeEnabled
NotificationCenter.default.addObserver(forName: .NSProcessInfoPowerStateDidChange, object: nil, queue: nil) { _ in }
NotificationCenter.default.addObserver(forName: Notification.Name.NSProcessInfoPowerStateDidChange, object: nil, queue: nil) { _ in }
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC18/EC18.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Do not disable location updates pause, unless absolutely necessary.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"eco-design",
"environment",
"sobriety",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Allowing the system to pause location updates, at times when the location data is unlikely to change, can improve
battery life without sacrificing location data. This is the default behavior. For example, if the user stops for
food while using a navigation app, the location manager might pause updates for a period of time. It is possible
to disable this behavior, by setting the `CLLocationManager#pausesLocationUpdatesAutomatically`
property to `false`, but applications are strongly discouraged of doing it.

## Noncompliant Code Example

```swift
let manager = CLLocationManager()
manager.pausesLocationUpdatesAutomatically = false // Noncompliant
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC19/EC19.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Adapt location accuracy and type to applications needs.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"eco-design",
"environment",
"sobriety",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Location awareness is one of the most popular features used by apps.
By default standard location updates run with the best accuracy level,
but unless your app really needs to know the user’s position within a few meters,
this level of accuracy isn't needed.
Requesting higher accuracy than you need causes the system to power up additional hardware
and waste power for unnecessary precision. You can specify a degree of accuracy by setting
the `CLLocationManager#desiredAccuracy` property.
Also, setting the `CLLocationManager#activityType` property will let the system knows what type
of location activity your app is performing and helps it determine
the most appropriate time to perform location updates.
Finally, if your app just needs a quick fix on the user’s location,
it’s best to call the `CLLocationManager#requestLocation` method,
that will deliver a single location update.

## Compliant Code Example

```swift
let manager = CLLocationManager()
manager.desiredAccuracy = 2
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC20/EC20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Set appropriate motion sensor update rates for the application's needs.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"eco-design",
"environment",
"sobriety",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Using the Core Motion API, your app can receive continuous motion updates in the form of
accelerometer, gyroscope, and device motion (rotation, acceleration, and more) events.
Yet you don't often need these updates as soon as they are generated.
Before registering to receive these recurring motion updates, you can specify an interval
that meets your app’s needs, using `CMMotionManager#accelerometerUpdateInterval`,
`CMMotionManager#gyroUpdateInterval`, `CMMotionManager#deviceMotionUpdateInterval` and
`CMMotionManager#magnetometerUpdateInterval` properties. The larger the interval,
the fewer events are delivered to your app, improving battery life.

## Compliant Code Example

```swift
CMMotionManager.accelerometerUpdateInterval = 1000
CMMotionManager.gyroUpdateInterval = 1000
CMMotionManager.deviceMotionUpdateInterval = 1000
CMMotionManager.magnetometerUpdateInterval = 1000
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC21/EC21.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Do not force brightness in your code, unless absolutely necessary.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"eco-design",
"environment",
"sobriety",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
To avoid draining the battery, an iOS device adapt its brightness to the environment.
Hence, keeping forcing the screen brightness on should be avoided, unless it is absolutely necessary.
If so, developers typically force the brightness to 1 with `UIScreen.main.brightness`.

## Non-Compliant Code Example

```swift
UIScreen.main.brightness = 0.3
```
20 changes: 20 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC23/EC23.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "Turning on the torch mode programmatically must absolutely be avoided because the flashlight is one of the most energy-intensive component.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"eco-design",
"environment",
"sobriety",
"ecocode"
],
"defaultSeverity": "Major",
"compatibleLanguages": [
"SWIFT"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Turning on the torch mode programmatically using `AVCaptureDevice#torchMode` or `AVCaptureDevice#setTorchModeOn(level:)`
methods must absolutely be avoided because the flashlight is one of the most energy-intensive component.

## Non-Compliant Code Example

```swift
guard let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else { return }
guard videoDevice.hasTorch else { return }

videoDevice.lockForConfiguration()
videoDevice.torchMode = .on // non-compliant
videoDevice.setTorchModeOn(level: 1.0) // non-compliant
videoDevice.unlockForConfiguration()
```

0 comments on commit e854f83

Please sign in to comment.