Skip to content

Commit

Permalink
Merge pull request #102 from andrew-winn-br/master
Browse files Browse the repository at this point in the history
Extend CLLocationCoordinate2D with `isValid` computed property
  • Loading branch information
wmcginty committed Jan 19, 2022
2 parents 3016650 + 6176de8 commit 601fbe1
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

##### Enhancements

* Extend CLLocationCoordinate2D with isValid computed property
[Andrew Winn](https://github.com/andrew-winn-br)
[#102](https://github.com/BottleRocketStudios/iOS-UtiliKit/pull/102)

* Improve support for registering supplementary and decoration views with UICollectionView.
[Will McGinty](https://github.com/willmcginty)
[#110](https://github.com/BottleRocketStudios/iOS-UtiliKit/pull/110)
Expand Down
32 changes: 32 additions & 0 deletions Sources/UtiliKit/General/CLLocationCoordinate2D+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// CLLocationCoordinate2D+Extensions.swift
// UtiliKit-iOS
//
// Created by Andrew Winn on 8/24/21.
// Copyright © 2021 Bottle Rocket Studios. All rights reserved.
//

import CoreLocation

public extension CLLocationCoordinate2D {

/// Checks if a coordinate is valid. Attempting to use an invalid coordinate (e.g. by setting a map region to center on it) will crash the app.
///
/// A coordinate is considered **invalid** if it meets at least one of the following criteria:
/// - Its latitude is greater than 90 degrees or less than -90 degrees.
/// - Its longitude is greater than 180 degrees or less than -180 degrees.
///
/// An invalid coordinate can be generated from:
/// - Invalid data from an API
/// - `mkMapView.userLocation.coordinate` is not an optional property and will provide an invalid coordinate when the user is not sharing their location.
/// - `locationManager.location.coordinate` is an optional property but may still provide an invalid coordinate (e.g. when the user has revoked location permissions while the app is running after previously granting)
var isValid: Bool {
if CLLocationCoordinate2DIsValid(self) {
return true
}
debugPrint("================================================")
debugPrint("Invalid CLLocationCoordinate2D Detected: \(self)")
debugPrint("================================================")
return false
}
}
42 changes: 42 additions & 0 deletions Tests/UtiliKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import XCTest
import CoreLocation
@testable import UtiliKit

class OpenSourceUtilitiesTests: XCTestCase {
Expand Down Expand Up @@ -77,4 +78,45 @@ class OpenSourceUtilitiesTests: XCTestCase {

XCTAssertEqual(superview.bounds.inset(by: insets), view.frame)
}

//MARK: - CLLocationCoordinate2D Tests
func test_CLLocationCoordinate2D_Valid() {
let coordinates = [CLLocationCoordinate2D(latitude: CLLocationDegrees(0),
longitude: CLLocationDegrees(0)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(-0),
longitude: CLLocationDegrees(-0)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(90),
longitude: CLLocationDegrees(180)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(-90),
longitude: CLLocationDegrees(180)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(90),
longitude: CLLocationDegrees(-180)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(-90),
longitude: CLLocationDegrees(-180))
]

XCTAssertTrue(coordinates.allSatisfy { $0.isValid }, "All test coordinates should be valid")
}

func test_CLLocationCoordinate2d_Invalid() {
let coordinates = [CLLocationCoordinate2D(latitude: CLLocationDegrees(95),
longitude: CLLocationDegrees(0)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(-95),
longitude: CLLocationDegrees(0)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(0),
longitude: CLLocationDegrees(185)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(0),
longitude: CLLocationDegrees(-185)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(95),
longitude: CLLocationDegrees(185)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(-95),
longitude: CLLocationDegrees(185)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(95),
longitude: CLLocationDegrees(-185)),
CLLocationCoordinate2D(latitude: CLLocationDegrees(-95),
longitude: CLLocationDegrees(-185))
]

XCTAssertTrue(coordinates.allSatisfy { !$0.isValid }, "All test coordinates should be invalid")
}
}
4 changes: 4 additions & 0 deletions UtiliKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
8698D0272061A3930065AE20 /* ViewControllerA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8698D0072061A3930065AE20 /* ViewControllerA.swift */; };
8698D0282061A3930065AE20 /* ViewControllerB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8698D0082061A3930065AE20 /* ViewControllerB.swift */; };
8698D0292061A3930065AE20 /* WipeTransitionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8698D0092061A3930065AE20 /* WipeTransitionAnimator.swift */; };
A3C49DC226D56CFD00A4FCBB /* CLLocationCoordinate2D+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3C49DC126D56CFD00A4FCBB /* CLLocationCoordinate2D+Extensions.swift */; };
B4A5231A22E6925B00AB1424 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4A5231922E6925B00AB1424 /* URL+Extensions.swift */; };
B4CCCAEF22D57284001A7A4F /* DefaultContainerTransitionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8698CFA620619EAD0065AE20 /* DefaultContainerTransitionAnimator.swift */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -193,6 +194,7 @@
8698D0072061A3930065AE20 /* ViewControllerA.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerA.swift; sourceTree = "<group>"; };
8698D0082061A3930065AE20 /* ViewControllerB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerB.swift; sourceTree = "<group>"; };
8698D0092061A3930065AE20 /* WipeTransitionAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WipeTransitionAnimator.swift; sourceTree = "<group>"; };
A3C49DC126D56CFD00A4FCBB /* CLLocationCoordinate2D+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CLLocationCoordinate2D+Extensions.swift"; sourceTree = "<group>"; };
B4A5231922E6925B00AB1424 /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -438,6 +440,7 @@
8698CFA820619EAD0065AE20 /* FileManager+Extensions.swift */,
8698CFA920619EAD0065AE20 /* UIView+Extensions.swift */,
B4A5231922E6925B00AB1424 /* URL+Extensions.swift */,
A3C49DC126D56CFD00A4FCBB /* CLLocationCoordinate2D+Extensions.swift */,
);
path = General;
sourceTree = "<group>";
Expand Down Expand Up @@ -707,6 +710,7 @@
5936A29324632D9B006E3FA6 /* ScrollingPageControl.swift in Sources */,
8698CFCA20619EAD0065AE20 /* VersionConfig.swift in Sources */,
B4A5231A22E6925B00AB1424 /* URL+Extensions.swift in Sources */,
A3C49DC226D56CFD00A4FCBB /* CLLocationCoordinate2D+Extensions.swift in Sources */,
8698CFC420619EAD0065AE20 /* UICollectionView+Extensions.swift in Sources */,
0EC8025C209CE9C90051F732 /* Configurable.swift in Sources */,
8698CFC820619EAD0065AE20 /* TimelessDate.swift in Sources */,
Expand Down

0 comments on commit 601fbe1

Please sign in to comment.