diff --git a/APPROBATION.md b/APPROBATION.md
index 83f656a..bd41971 100644
--- a/APPROBATION.md
+++ b/APPROBATION.md
@@ -1,10 +1,18 @@
-# Approbation Matrix / PerseusGeoLocationKit 1.0.0 && 1.0.1 && 1.0.2 && 1.0.2 && 1.0.3 && 1.0.4 && 1.1.0 && 1.1.1 && 1.1.2
+# Approbation Matrix for PerseusGeoLocationKit
+
+## Approbated Versions
+
+> This report is actual for the following product versions:
+
+v1.0.0 v1.0.1 v1.0.2 v1.0.2 v1.0.3 v1.0.4 v1.1.0 v1.1.1 v1.1.2 **v1.2.0**
+
+## Approbation Note
> NOTE: To catch all log messages Mac Console should be started first then after a little while the logged app.
> Compilation: macOS Monterey 12.7.6 / Xcode 14.2
-## macOS approbation result
+# macOS approbation result
> The macOS app used to approbate PerseusGeoLocationKit is [Arkenstone](https://github.com/perseusrealdeal/Arkenstone).
@@ -19,7 +27,7 @@
| Sonoma | 14.7 | ok | Returns LS status .notDetermed if turn LS off, OpenCore usage case. |
| Sequoia | 15.1 | ok | Returns LS status .notDetermed if turn LS off, OpenCore usage case. |
-## iOS approbation result
+# iOS approbation result
> The iOS app used to approbate PerseusGeoLocationKit is [The One Ring](https://github.com/perseusrealdeal/TheOneRing).
@@ -28,9 +36,9 @@
| iPad Air | no | 12.5.7 | ok | - |
| iPhone SE (3rd) | yes | 16.2 | ok | Simulator generates error on every event of currentLocation/start but value received |
-## A3 environment
+# A3 environment
-### List of available Apple machines
+## List of available Apple machines
> Excluded: virtualization (e.g. VirtualBox) and hackintosh
@@ -39,7 +47,7 @@
| Mac mini | 16GB | SATA 480GB, NVMe 256GB |
| MacBook Pro | 8GB | 256GB |
-### System configuration for A3 environment
+## System configuration for A3 environment
| macOS | Version | Machine | Xcode | OpenCore | Git Client |
| ----------- | ------- | ----------- | ------ | -------- | -------------- |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ef9a84..0cccbc5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,19 +5,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Dates in this file meets Gregorian calendar. Date in format YYYY-MM-DD.
-## [1.1.2] - [2025-12-14], PGK
+## [1.2.0] - [2026-03-03], PerseusGeoKit
+
+### Included
+
+- The support code to the main code.
+
+### Renamed
+
+- `PGKStar.swift` to `TheGeoStar.swift`.
+
+### Added:
+
+- Minor changes to documentation.
+
+### Updated:
+
+- CPL dependency to v1.7.1.
+
+## [1.1.2] - [2025-12-14], PerseusGeoKit
### Added:
- Calculated property to ActionAlertText to simplify complex localization issues.
-## [1.1.1] - [2025-11-30], PGK
+## [1.1.1] - [2025-11-30], PerseusGeoKit
### Updated
- CPL dependency to v1.7.0.
-## [1.1.0] - [2025-10-30], PGK
+## [1.1.0] - [2025-10-30], PerseusGeoKit
### Added
@@ -27,7 +45,7 @@ Dates in this file meets Gregorian calendar. Date in format YYYY-MM-DD.
- CPL dependency to v1.6.0.
-## [1.0.4] - [2025-07-22], PGK
+## [1.0.4] - [2025-07-22], PerseusGeoKit
### Removed
@@ -38,25 +56,25 @@ Dates in this file meets Gregorian calendar. Date in format YYYY-MM-DD.
- GitHub CI scripts.
- CPL dependency to v1.5.1.
-## [1.0.3] - [2025-06-18], PGK
+## [1.0.3] - [2025-06-18], PerseusGeoKit
### Fixed
- Logger access modifier, typealias `log` must be not public.
-## [1.0.2] - [2025-06-17], PGK
+## [1.0.2] - [2025-06-17], PerseusGeoKit
### Upgraded
- PerseusLogger to [CPL v1.5.0](https://github.com/perseusrealdeal/ConsolePerseusLogger).
-## [1.0.1] - [2025-05-31], PGK
+## [1.0.1] - [2025-05-31], PerseusGeoKit
### Fixed
- iOS: Location Services permission request if status in .notDetermined.
-## [1.0.0] - [2025-05-31], PGK
+## [1.0.0] - [2025-05-31], PerseusGeoKit
- Minimum build requirements: macOS 10.13+, iOS 11.0+, Xcode 14.2+. If standalone Xcode 10.1+.
diff --git a/LICENSE b/LICENSE
index 3acc76a..d5a098b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -4,9 +4,9 @@ Copyright © 7531 - 7534 Mikhail A. Zhigulin of Novosibirsk
Copyright © 7533 - 7534 PerseusRealDeal
The year starts from the creation of the world according to a Slavic calendar.
-September, the 1st of Slavic year.
+September, the 1st of Slavic year. For instance, "Sep 01, 2025" is the beginning of 7534.
-Use Stars to adopt for the specifics you need.
+Stars to adopt for the specifics you need.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Package.swift b/Package.swift
index de899b7..3a8ba95 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,7 +1,7 @@
// swift-tools-version:5.7
/* Package.swift
- Version: 1.1.2
+ Version: 1.2.0
For iOS and macOS only. Use Stars to adopt for the specifics you need.
diff --git a/README.md b/README.md
index 3a74981..e5ff2b4 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,25 @@
-# PerseusGeoKit — Xcode 14.2+
+
+
+Perseus Geo Kit
+==
+
+HAVE A DEAL WITH WHERE YOU ARE
[](https://github.com/perseusrealdeal/PerseusGeoKit/actions/workflows/main.yml)
[](https://github.com/perseusrealdeal/PerseusGeoKit/actions/workflows/swiftlint.yml)
-[](/CHANGELOG.md)
+[](/CHANGELOG.md)
[](https://en.wikipedia.org/wiki/List_of_Apple_products)
[](https://en.wikipedia.org/wiki/Xcode)
[](https://www.swift.org)
-[](/LICENSE)
-> This is the great home-made product in Swift for easily managed `Location Services API`.
+[`A3 Environment`](/APPROBATION.md) • [`CHANGELOG`](/CHANGELOG.md) • [`MIT License`](/LICENSE)
+
+
+
+---
+
+Usages
+==
> `1:` Be awared of Location Services Status.
> `2:` Request permission for Location Services.
@@ -16,45 +27,42 @@
> `4:` Get Current Location.
> `5:` Request Location Updates.
-> `PGK` is a single author and personale solution developed in `P2P` relationship paradigm.
-
-## Integration Capabilities
+Integration
+==
-[](/PGKStar.swift)
+[](/TheGeoStar.swift)
[](/Package.swift)
-## Dependencies
+Dependencies
+==
-[](https://github.com/perseusrealdeal/ConsolePerseusLogger.git)
+[](https://github.com/perseusrealdeal/ConsolePerseusLogger.git)
-## Support Code
+Support Code
+==
-[](/PGKSupportingStar.swift)
+[](/Sources/PerseusGeoKit/TheGeoSupport.swift)
[](http://unlicense.org/)
-> [`PGKSupportingStar.swift`](/PGKSupportingStar.swift) is a peace of code a widly helpful in accord with PGK.
-> `PGKSupportingStar.swift` goes as an external part of PGK.
+> [`TheGeoSupport.swift`](/Sources/PerseusGeoKit/TheGeoSupport.swift) is a peace of code a widly helpful in accord with `PGK`.
-## Our Terms
+PGK in Use
+==
-> [`CPL`](https://github.com/perseusrealdeal/ConsolePerseusLogger.git) stands for `C`onsole `P`erseus `L`ogger.
-> [`PGK`](https://github.com/perseusrealdeal/PerseusGeoKit.git) stands for `P`erseus `G`eo `K`it.
-> [`PDM`](https://github.com/perseusrealdeal/PerseusDarkMode.git) stands for `P`erseus `D`ark `M`ode.
-> `P2P` stands for `P`erson-`to`-`P`erson.
-> [`A3`](https://docs.google.com/document/d/1K2jOeIknKRRpTEEIPKhxO2H_1eBTof5uTXxyOm5g6nQ) stands for `A`pple `A`pps `A`pprobation.
-> [`T3`](https://github.com/perseusrealdeal/TheTechnologicalTree) stands for `T`he `T`echnological `T`ree.
+> `Approbation:`
-## PGK in Use
+- [`Swift macOS app`](https://github.com/perseusrealdeal/Arkenstone)
+- [`Swift iOS app`](https://github.com/perseusrealdeal/TheOneRing)
-> `In approbation:` [`iOS app`](https://github.com/perseusrealdeal/TheOneRing) [`macOS app`](https://github.com/perseusrealdeal/Arkenstone)
-> `In business:` [`The Dark Moon`](https://github.com/perseusrealdeal/TheDarkMoon)
+> `Business:`
-> `For details:` [`Approbation and A3 Environment`](/APPROBATION.md) / [`CHANGELOG`](/CHANGELOG.md)
+- Swift macOS app [`The Dark Moon`](https://github.com/perseusrealdeal/TheDarkMoon)
-# Contents
+Contents
+==
* [In brief](#In-brief)
-* [Build requirements](#Build-requirements)
+* [Requirements](#Requirements)
* [First-party software](#First-party-software)
* [Third-party software](#Third-party-software)
* [Installation](#Installation)
@@ -68,22 +76,44 @@
* [Location status](#Location-status)
* [Current location](#Current-location)
* [Location updates](#Location-updates)
-* [Points taken into account](#Points-taken-into-account)
+* [Account points](#Account-points)
* [License](#License)
- * [Other required license notices](#Other-required-license-notices)
+ * [Other required licenses details](#Other-required-licenses-details)
* [Credits](#Credits)
+* [Contributing](#Contributing)
* [Author](#Author)
+ * [Contact](#Contact)
+
+Our Terms
+--
-# In brief
+| Acronym | Stands for |
+| :-----: | --------------------------------------------------------------------------------------------------------- |
+| CPL | [Console_Perseus_Logger](https://github.com/perseusrealdeal/ConsolePerseusLogger.git) |
+| PDM | [Perseus_Dark_Mode](https://github.com/perseusrealdeal/PerseusDarkMode.git) |
+| PGK | [Perseus_Geo_Kit](https://github.com/perseusrealdeal/PerseusGeoKit.git) |
+| A3 | [Apple_Apps_Approbation](https://docs.google.com/document/d/1K2jOeIknKRRpTEEIPKhxO2H_1eBTof5uTXxyOm5g6nQ) |
+| T3 | [The_Technological_Tree](https://github.com/perseusrealdeal/TheTechnologicalTree) |
+| P2P | Person_to_Person |
-> HAVE A DEAL WITH WHERE YOU ARE
+In brief
+==
+
+The great home-made product for easily managed `Location Services API`. `PGK` is a single author and personale solution developed in `P2P` relationship paradigm.
- | Approbation App: iOS 16.2 |
- Approbation App: macOS Monterey |
+ macOS app |
+ iOS app |
+
+
+ The Current Location Dialog
+
+ System Services and The Redirect Dialog
+
+ |
The Current Location Dialog
@@ -93,44 +123,56 @@
System Services
|
-
-
- The Current Location Dialog
-
- System Services and The Redirect Dialog
-
- |
-> [!NOTE]
-> [`The iOS App`](https://github.com/perseusrealdeal/TheOneRing) scenes taken from the motion picture `The Lord of The Rings` based on the novel by J.R.R. Tolkien.
-> [`The macOS App`](https://github.com/perseusrealdeal/Arkenstone) scenes taken from the motion picture `The Hobbit` based on the novel by J.R.R. Tolkien.
+> [!IMPORTANT]
+> [`The macOS App`](https://github.com/perseusrealdeal/Arkenstone) scenes taken from the motion picture `The Hobbit` based on the novel by J.R.R. Tolkien.
+> [`The iOS App`](https://github.com/perseusrealdeal/TheOneRing) scenes taken from the motion picture `The Lord of The Rings` based on the novel by J.R.R. Tolkien.
+
+Requirements
+==
+
+`To build:`
+
+- [macOS Monterey 12.7.6+](https://apps.apple.com/by/app/macos-monterey/id1576738294)
+- [Xcode 14.2+](https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_14.2/Xcode_14.2.xip)
-# Build system requirements
+First-party software
+==
-- [macOS Monterey 12.7.6+](https://apps.apple.com/by/app/macos-monterey/id1576738294) / [Xcode 14.2+](https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_14.2/Xcode_14.2.xip)
+MIT
+--
-# First-party software
+| Type | Name |
+| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Star | [ConsolePerseusLogger](https://github.com/perseusrealdeal/ConsolePerseusLogger) / [1.7.1](https://github.com/perseusrealdeal/ConsolePerseusLogger/releases/tag/1.7.1) |
-| Type | Name | License |
-| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
-| Star | [ConsolePerseusLogger](https://github.com/perseusrealdeal/ConsolePerseusLogger) / [1.7.0](https://github.com/perseusrealdeal/ConsolePerseusLogger/releases/tag/1.7.0) | MIT |
+Third-party software
+==
-# Third-party software
+MIT
+--
-| Type | Name | License |
-| ------ | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
-| Style | [SwiftLint](https://github.com/realm/SwiftLint) / [v0.57.0 for Monterey+](https://github.com/realm/SwiftLint/releases/tag/0.57.0) | MIT |
-| Script | [SwiftLint Shell Script](/SucceedsPostAction.sh) to run SwiftLint | MIT |
-| Action | [mxcl/xcodebuild@v3](https://github.com/mxcl/xcodebuild) | [Unlicense](https://unlicense.org) |
-| Action | [cirruslabs/swiftlint-action@v1](https://github.com/cirruslabs/swiftlint-action/) | MIT |
+| Type | Name |
+| ------ | --------------------------------------------------------------------------------------------------------------------------------- |
+| Style | [SwiftLint](https://github.com/realm/SwiftLint) / [v0.57.0 for Monterey+](https://github.com/realm/SwiftLint/releases/tag/0.57.0) |
+| Script | [SwiftLint Shell Script](/SucceedsPostAction.sh) to run SwiftLint |
+| Action | [cirruslabs/swiftlint-action@v1](https://github.com/cirruslabs/swiftlint-action/) |
-# Installation
+[Unlicense](https://unlicense.org)
+--
+
+| Type | Name |
+| ------ | --------------------------------------------------------------------------------------------------------------------------------- |
+| Action | [mxcl/xcodebuild@v3](https://github.com/mxcl/xcodebuild) |
+
+Installation
+==
`Step 1:` Import PGK either with SPM or standalone.
-> Standalone: the single source code file [PGKStar.swift](/PGKStar.swift)
+> Standalone: the single source code file [TheGeoStar.swift](/TheGeoStar.swift)
> Swift Package Manager: `https://github.com/perseusrealdeal/PerseusGeoKit`
@@ -143,9 +185,11 @@
`Step 3, macOS:` Tap `Location` in `App Sandbox` of your project target.
-# Usage
+Usage
+==
-## Get location services status
+Get location services status
+--
Location Services Status is calculated as a unified value for both iOS and macOS.
@@ -165,7 +209,7 @@ let statusInDetail = GeoAgent.aboutLocationServices().inDetail
|.notAllowed |.deniedForTheApp |Location Services turned on but the app not restricted. |
|.allowed |.allowed |Authorized. |
-> [!IMPORTANT]
+> [!NOTE]
> To be awared of Location Services Status changes, register:
```swift
@@ -182,7 +226,8 @@ GeoAgent.register(self, #selector(locationStatusHandler(_:)), .locationStatus)
```
-## Request permission
+Request permission
+--
Statement **GeoAgent.requestPermission()** can be combined with the action to be called if status has already determined.
@@ -214,7 +259,7 @@ GeoAgent.showRedirectAlert(REDIRECT_ALERT_TITLES)
```
-> [!NOTE]
+> [!IMPORTANT]
> `iOS:` The Redirect Dialog by **GeoAgent.showRedirectAlert(vc)** requires the parent ViewController.
```swift
@@ -227,7 +272,8 @@ GeoAgent.shared.requestPermission { status in
```
-## Request current location
+Request current location
+--
> [!WARNING]
> Statement **GeoAgent.shared.requestCurrentLocation()** causes stop updating location.
@@ -269,7 +315,8 @@ do {
```
-## Request updating location
+Request updating location
+--
`Step 1:` Register for Geo events both error and updating location.
@@ -317,7 +364,8 @@ GeoAgent.shared.stopUpdatingLocation()
```
-## Geo events processing
+Geo events processing
+--
### Location error
@@ -484,60 +532,87 @@ GeoAgent.register(self, #selector(locationUpdatesHandler(_:)), .locationUpdates)
```
-# Points taken into account
+Account points
+==
- Preconfigured Swift Package manifest [Package.swift](/Package.swift)
- Preconfigured SwiftLint config [.swiftlint.yml](/.swiftlint.yml)
- Preconfigured SwiftLint CI [swiftlint.yml](/.github/workflows/swiftlint.yml)
- Preconfigured GitHub config [.gitignore](/.gitignore)
- Preconfigured GitHub CI [main.yml](/.github/workflows/main.yml)
+- [Changelog](/CHANGELOG.md)
+- [A3 environment specification](/APPROBATION.md)
+- [SwiftLint shell script](/SucceedsPostAction.sh)
-# License
+License
+==
-`License:` MIT
+`MIT License`, see [LICENSE](/LICENSE) for details.
Copyright © 7531 - 7534 Mikhail A. Zhigulin of Novosibirsk
Copyright © 7533 - 7534 PerseusRealDeal
- The year starts from the creation of the world according to a Slavic calendar.
-- September, the 1st of Slavic year. It means that "Sep 01, 2025" is the beginning of 7534.
-
-## Other required license notices
+- September, the 1st of Slavic year. For instance, "Sep 01, 2025" is the beginning of 7534.
-© 2025 The SwiftLint Contributors **for** SwiftLint
-© GitHub **for** GitHub Action cirruslabs/swiftlint-action@v1
-© 2021 Alexandre Colucci, geteimy.com **for** Shell Script SucceedsPostAction.sh
+Other required licenses details
+--
-[LICENSE](/LICENSE) for details.
+`© 2025 The SwiftLint Contributors` **for** SwiftLint
+`© GitHub` **for** GitHub Action cirruslabs/swiftlint-action@v1
+`© 2021 Alexandre Colucci, geteimy.com` **for** Shell Script SucceedsPostAction.sh
-## Credits
+Credits
+==
-
- | Balance and Control |
- kept by |
- Mikhail Zhigulin |
-
-
- | Source Code |
- written by |
- Mikhail Zhigulin |
-
-
- | Documentation |
- prepared by |
- Mikhail Zhigulin |
-
-
- | Product Approbation |
- tested by |
- Mikhail Zhigulin |
-
+
+ | Balance and Control |
+ Mikhail Zhigulin |
+
+
+ | Source Code |
+ Mikhail Zhigulin |
+
+
+ | Documentation |
+ Mikhail Zhigulin |
+
+
+ | Approbation |
+ Mikhail Zhigulin |
+
+
+ | English |
+ Mikhail Zhigulin |
+
- Language support: [Reverso](https://www.reverso.net/)
- Git clients: [SmartGit](https://syntevo.com/) and [GitHub Desktop](https://github.com/apps/desktop)
-# Author
+Contributing
+==
+
+> [!NOTE]
+> The product is constructed in `P2P` relationship paradigm that means the only one single and the same face in the product team during all development process stages.
+
+`Bug reports are welcome`, create an issue and give details.
+
+Author
+==
+
+
+
+`© Mikhail A. Zhigulin of Novosibirsk`
+
+
+
+Contact
+--
+
+
+
+[E-mail](mailto:mzhigulin@gmail.com) • [Telegram](https://t.me/velociraptor1985) • [GitHub](https://github.com/perseusrealdeal)
-> © Mikhail A. Zhigulin of Novosibirsk.
+
diff --git a/PGKSupportingStar.swift b/Sources/PerseusGeoKit/TheGeoSupport.swift
similarity index 98%
rename from PGKSupportingStar.swift
rename to Sources/PerseusGeoKit/TheGeoSupport.swift
index 2ff29c1..32ccdee 100644
--- a/PGKSupportingStar.swift
+++ b/Sources/PerseusGeoKit/TheGeoSupport.swift
@@ -1,16 +1,15 @@
//
-// PGKSupportingStar.swift
-// Version: 1.1.2
+// TheGeoSupport.swift
//
// PerseusGeoKit Support Code
//
//
-// For iOS and macOS only. Use Stars to adopt for the specifics you need.
+// Stars to adopt for the specifics you need.
//
// Created by Mikhail Zhigulin of Novosibirsk in 7533.
//
// The year starts from the creation of the world according to a Slavic calendar.
-// September, the 1st of Slavic year. It means that "Sep 01, 2025" is the beginning of 7534.
+// September, the 1st of Slavic year. For instance, "Sep 01, 2025" is the beginning of 7534.
//
//
// Unlicensed Free Software
diff --git a/Sources/PerseusGeoKit/CPLStar.swift b/Sources/PerseusGeoKit/TheLoggerStar.swift
similarity index 99%
rename from Sources/PerseusGeoKit/CPLStar.swift
rename to Sources/PerseusGeoKit/TheLoggerStar.swift
index 26ddbb1..d3eb6dc 100644
--- a/Sources/PerseusGeoKit/CPLStar.swift
+++ b/Sources/PerseusGeoKit/TheLoggerStar.swift
@@ -1,10 +1,10 @@
//
-// CPLStar.swift
-// Version: 1.7.0
+// TheLoggerStar.swift
+// Version: 1.7.1
//
// Standalone ConsolePerseusLogger.
//
-// For iOS and macOS. Use Stars to adopt for the specifics you need.
+// Stars to adopt for the specifics you need.
//
// DESC: USE LOGGER LIKE A VARIABLE ANYWHERE YOU WANT.
//
@@ -27,7 +27,7 @@
// Copyright © 7531 - 7534 PerseusRealDeal
//
// The year starts from the creation of the world according to a Slavic calendar.
-// September, the 1st of Slavic year. It means that "Sep 01, 2025" is the beginning of 7534.
+// September, the 1st of Slavic year. For instance, "Sep 01, 2025" is the beginning of 7534.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/PGKStar.swift b/TheGeoStar.swift
similarity index 70%
rename from PGKStar.swift
rename to TheGeoStar.swift
index be6c872..5334570 100644
--- a/PGKStar.swift
+++ b/TheGeoStar.swift
@@ -1,11 +1,11 @@
//
-// PerseusGeoKitStar.swift
-// Version: 1.1.2
+// TheGeoStar.swift
+// Version: 1.2.0
//
// Standalone PerseusGeoKit
//
//
-// For iOS and macOS only. Use Stars to adopt for the specifics you need.
+// Stars to adopt for the specifics you need.
//
// DESC: HAVE A DEAL WITH WHERE YOU ARE.
//
@@ -23,7 +23,7 @@
// Copyright © 7533 - 7534 PerseusRealDeal
//
// The year starts from the creation of the world according to a Slavic calendar.
-// September, the 1st of Slavic year. It means that "Sep 01, 2025" is the beginning of 7534.
+// September, the 1st of Slavic year. For instance, "Sep 01, 2025" is the beginning of 7534.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -54,8 +54,6 @@ import UIKit
import Cocoa
#endif
-// import ConsolePerseusLogger
-
// MARK: - Constants
public let APPROPRIATE_ACCURACY_DEFAULT = GeoAccuracy.threeKilometers
@@ -1073,3 +1071,372 @@ public func redirectToSettingsApp() {
}
#endif
+
+// MARK: - The Geo Support
+//
+// The Geo Support
+//
+//
+// Stars to adopt for the specifics you need.
+//
+// Created by Mikhail Zhigulin of Novosibirsk in 7533.
+//
+// The year starts from the creation of the world according to a Slavic calendar.
+// September, the 1st of Slavic year. For instance, "Sep 01, 2025" is the beginning of 7534.
+//
+//
+// Unlicensed Free Software
+// Sstarting from here and further in the file
+//
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+//
+// In jurisdictions that recognize copyright laws, the author or authors
+// of this software dedicate any and all copyright interest in the
+// software to the public domain. We make this dedication for the benefit
+// of the public at large and to the detriment of our heirs and
+// successors. We intend this dedication to be an overt act of
+// relinquishment in perpetuity of all present and future rights to this
+// software under copyright law.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// For more information, please refer to
+//
+
+import MapKit
+
+// MARK: - Geo Constants
+
+let DEFAULT_ACCURACY: GeoAccuracy = .threeKilometers
+
+let DEFAULT_MAP_POINT = CLLocation(latitude: 55.036857, longitude: 82.914063)
+let DEFAULT_MAP_RADIUS: CLLocationDistance = 1000
+
+let DEFAULT_VISIBLE_REGION = MKCoordinateRegion(center: DEFAULT_MAP_POINT.coordinate,
+ latitudinalMeters: DEFAULT_MAP_RADIUS,
+ longitudinalMeters: DEFAULT_MAP_RADIUS)
+
+var REDIRECT_ALERT_TITLES = ActionAlertText(
+ title: "Location Services.",
+ message: "The Current Location Services Status can be changed in System Services.",
+ buttonCancel: "OK",
+ buttonFunction: "System Services")
+
+extension ActionAlertText {
+ var titleWithStatus: String {
+ guard let status = titleCalculated else {
+ return "Location Services: \(GeoAgent.currentStatus.description.capitalized)."
+ }
+ return status()
+ }
+}
+
+extension Notification.Name {
+ static let ReloadGeoDataNotification = Notification.Name("ReloadGeoDataNotification")
+}
+
+#if os(iOS)
+
+extension UIView {
+
+ func parentViewController() -> UIViewController? {
+
+ guard let responder = self.next as? UIViewController else {
+ guard let responder = self.next as? UIView else {
+ return nil
+ }
+
+ return responder.parentViewController()
+ }
+
+ return responder
+ }
+}
+
+#endif
+
+// MARK: - LocationDealer class
+
+class LocationDealer {
+
+ // MARK: - iOS Contract
+
+#if os(iOS)
+
+ public class func requestPermission(_ alertViewController: UIViewController? = nil) {
+ GeoAgent.shared.requestPermission { status in
+ if status != .allowed, let parentVC = alertViewController {
+ REDIRECT_ALERT_TITLES.title = REDIRECT_ALERT_TITLES.titleWithStatus
+ GeoAgent.showRedirectAlert(parentVC, REDIRECT_ALERT_TITLES) // Offer redirect.
+ }
+ }
+ }
+
+ public class func requestCurrent(_ alertViewController: UIViewController? = nil) {
+ do {
+ try GeoAgent.shared.requestCurrentLocation()
+ } catch LocationError.permissionRequired(let status) { // Permission required.
+
+ log.message("[\(type(of: self))].\(#function) permission required", .notice)
+
+ if status == .notDetermined {
+ GeoAgent.shared.requestPermission() // Request permission.
+ } else if let parentVC = alertViewController {
+ REDIRECT_ALERT_TITLES.title = REDIRECT_ALERT_TITLES.titleWithStatus
+ GeoAgent.showRedirectAlert(parentVC, REDIRECT_ALERT_TITLES) // Offer redirect.
+ }
+
+ } catch {
+ log.message("[\(type(of: self))].\(#function) something went wrong", .error)
+ }
+ }
+
+ public class func requestUpdatingLocation(_ alertViewController: UIViewController? = nil) {
+ do {
+ try GeoAgent.shared.requestUpdatingLocation()
+ } catch LocationError.permissionRequired(let status) { // Permission required.
+
+ if status == .notDetermined {
+ GeoAgent.shared.requestPermission() // Request permission.
+ } else if let parentVC = alertViewController {
+ REDIRECT_ALERT_TITLES.title = REDIRECT_ALERT_TITLES.titleWithStatus
+ GeoAgent.showRedirectAlert(parentVC, REDIRECT_ALERT_TITLES) // Offer redirect.
+ }
+
+ } catch {
+ log.message("[\(type(of: self))].\(#function) something went wrong", .error)
+ }
+ }
+
+#elseif os(macOS)
+
+ // MARK: - macOS Contract
+
+ public class func requestPermission() {
+ GeoAgent.shared.requestPermission { status in
+ if status != .allowed {
+ REDIRECT_ALERT_TITLES.title = REDIRECT_ALERT_TITLES.titleWithStatus
+ GeoAgent.showRedirectAlert(REDIRECT_ALERT_TITLES) // Offer redirect.
+ }
+ }
+ }
+
+ public class func requestCurrent() {
+ do {
+ try GeoAgent.shared.requestCurrentLocation()
+ } catch LocationError.permissionRequired(let status) { // Permission required.
+
+ log.message("[\(type(of: self))].\(#function) permission required", .notice)
+
+ if status == .notDetermined {
+ GeoAgent.shared.requestPermission() // Request permission.
+ } else {
+ REDIRECT_ALERT_TITLES.title = REDIRECT_ALERT_TITLES.titleWithStatus
+ GeoAgent.showRedirectAlert(REDIRECT_ALERT_TITLES) // Offer redirect.
+ }
+
+ } catch {
+ log.message("[\(type(of: self))].\(#function) something went wrong", .error)
+ }
+ }
+
+ public class func requestUpdatingLocation() {
+ do {
+ try GeoAgent.shared.requestUpdatingLocation()
+ } catch LocationError.permissionRequired(let status) { // Permission required.
+
+ if status == .notDetermined {
+ GeoAgent.shared.requestPermission() // Request permission.
+ } else {
+ REDIRECT_ALERT_TITLES.title = REDIRECT_ALERT_TITLES.titleWithStatus
+ GeoAgent.showRedirectAlert(REDIRECT_ALERT_TITLES) // Offer redirect.
+ }
+
+ } catch {
+ log.message("[\(type(of: self))].\(#function) something went wrong", .error)
+ }
+ }
+
+#endif
+
+}
+
+// MARK: - GeoCoordinator class
+
+class GeoCoordinator: NSObject {
+
+ // MARK: - Properties
+
+ public var notifier: NotificationCenter?
+
+ public var locationRecieved: ((GeoPoint) -> Void)?
+ public var locationUpdatesRecieved: (([GeoPoint]) -> Void)?
+
+ public var onStatusAllowed: (() -> Void)?
+
+ // MARK: - Singletone
+
+ public static let shared = GeoCoordinator()
+
+ private override init() {
+
+ log.message("[\(GeoCoordinator.self)].\(#function)", .info)
+
+ super.init()
+
+ GeoAgent.register(self, #selector(locationErrorHandler(_:)), .locationError)
+ GeoAgent.register(self, #selector(locationStatusHandler(_:)), .locationStatus)
+ GeoAgent.register(self, #selector(currentLocationHandler(_:)), .currentLocation)
+ GeoAgent.register(self, #selector(locationUpdatesHandler(_:)), .locationUpdates)
+ }
+
+ // MARK: - Contract
+
+ public static func register(stakeholder: Any, selector: Selector) {
+ shared.notifier?.addObserver(stakeholder,
+ selector: selector,
+ name: .ReloadGeoDataNotification,
+ object: nil)
+ }
+
+ public static func reloadGeoComponents() {
+ log.message("[\(type(of: self))].\(#function)")
+ shared.updateGeoComponents()
+ }
+
+ // MARK: - Implementation
+
+ private func updateGeoComponents() {
+ log.message("[\(type(of: self))].\(#function)")
+ self.notifier?.post(name: .ReloadGeoDataNotification, object: nil)
+ }
+
+ // MARK: - Event Handlers
+
+ @objc private func locationErrorHandler(_ notification: Notification) {
+
+ log.message("[\(type(of: self))].\(#function) [EVENT]")
+ var errtext = ""
+
+ guard let error = notification.object as? LocationError else {
+ errtext = "nothing is about error"
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ return
+ }
+
+ switch error {
+ case .failedRequest(let desc, let domain, let code):
+ let domaincode = "domain: \(domain), code: \(code)"
+ if desc.contains("[NOTKNOWN]") {
+ errtext = "\(desc), \(domaincode)"
+ } else {
+ switch code {
+ case 0:
+ errtext = "hardware issue: try to tap Wi-Fi in system tray, \(domaincode)"
+ case 1:
+ errtext = "permission required, \(domaincode)"
+ default:
+ break
+ }
+ }
+ default:
+ break
+ }
+
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ }
+
+ @objc private func locationStatusHandler(_ notification: Notification) {
+
+ guard let sysStatus = notification.object as? CLAuthorizationStatus else {
+ let errtext = "nothing is about status event"
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ return
+ }
+
+ let lmStatus = GeoAgent.aboutLocationServices().auth
+
+ if lmStatus != sysStatus {
+ let statues = "lm status: \(lmStatus), system status: \(sysStatus)"
+ log.message("[\(type(of: self))].\(#function) \(statues)", .error)
+ }
+
+ let status = GeoAgent.currentStatus
+
+ log.message("[\(type(of: self))].\(#function) currentStatus: \(status) [EVENT]")
+
+ updateGeoComponents()
+
+ if status == .allowed {
+ onStatusAllowed?()
+ }
+ }
+
+ @objc private func currentLocationHandler(_ notification: Notification) {
+
+ log.message("[\(type(of: self))].\(#function) [EVENT]")
+
+ var errtext = ""
+ var location: GeoPoint?
+
+ guard let result = notification.object as? Result else {
+ errtext = "nothing is about location"
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ return
+ }
+
+ switch result {
+ case .success(let point):
+ location = point
+ case .failure(let error):
+ errtext = "\(error)"
+ }
+
+ if let current = location {
+ locationRecieved?(current)
+ } else if !errtext.isEmpty {
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ }
+
+ updateGeoComponents()
+ }
+
+ @objc private func locationUpdatesHandler(_ notification: Notification) {
+ log.message("[\(type(of: self))].\(#function) [EVENT]")
+
+ var errtext = ""
+ var updates: [GeoPoint]?
+
+ guard let result = notification.object as? Result<[GeoPoint], LocationError> else {
+ errtext = "nothing is about location updates"
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ return
+ }
+
+ switch result {
+ case .success(let points):
+ updates = points
+ case .failure(let error):
+ errtext = "\(error)"
+ }
+
+ if let updates = updates {
+ locationUpdatesRecieved?(updates)
+ } else if !errtext.isEmpty {
+ log.message("[\(type(of: self))].\(#function) \(errtext)", .error)
+ }
+
+ updateGeoComponents()
+ }
+}