At the moment with my app Users have to go to Privacy & Security -> Locations Services -> On -> Scroll down to my app and turn on their Location Preference.
I am trying to incorporate in to my app the Code below to make it unecessary to leave the app to enable the User‘s location to be displayed but it does not work.
Please tell me, what am I missing here?
import MapKit
import SwiftUI
import CoreLocation
// Prompt User to choose Location Preference //
class ViewController: UIViewController, CLLocationManagerDelegate{
var locationManager: CLLocationManager?
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
view.backgroundColor = .gray
}
}
// The rest of the Code which is working okay ( Map etc.) //
struct Positions: Identifiable {
let id = UUID()
let name: String
let latitude: Double
let longitude: Double
var coordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
etc.
etc.
Post
Replies
Boosts
Views
Activity
Is there a way of deleting an app from the Location Services in the Privacy Setting?
Despite deleting the particular app evidence of it remains.
Also with a particular app there are several of the same in the list. I do understand there may be one for the Playgrounds version and one for the actual downloaded version but I have more.
Is there a way of starting with a clean slate?
Firstly I must state that although I have learned a lot on my 12 month SwifttUI journey, I would still rate my knowledge as beginner!
My app has a fair bit of processing to do which to make it work had to split the functions over two views
(770 lines approximately)
It seems that SwiftUI can’t handle too much in the way of functions in a view?
Now that I have got to the stage of trying to streamline my app I would like to eliminate one view if possible but am not sure to go about it
Please excuse the formatting at the beginning. I needed to eliminate white space to reduce the character count
FIRST VIEW FUNCTIONS
func makeFirstCardWordLetters () {
| 33 lines removed
makeSecondCardWordLetters()
}
func makeSecondCardWordLetters () {
| 33 lines removed
makeThirdCardWordLetters()
}
func makeThirdCardWordLetters () {
| 33 lines removed
makeFourthCardWordLetters()
}
func makeFourthCardWordLetters () {
| 33 lines removed
makeFifthCardWordLetters ()
func makeFifthCardWordLetters () {
| 33 lines removed
makeSixthCardWordLetters()
func makeSixthCardWordLetters () {
| 33 lines removed
makeFirstCardAnswerClue()
}
func makeFirstCardAnswerClue () {
| 33 lines removed
makeSecondCardAnswerClue()
}
func makeSecondCardAnswerClue () {
| 33 lines removed
makeThirdCardAnswerClue()
}
func makeThirdCardAnswerClue () {
| 33 lines removed
makeFourthCardAnswerClue()
}
func makeFourthCardAnswerClue () {
| 33 lines removed
makeFifthCardAnswerClue ()
}
func makeFifthCardAnswerClue () {
| 33 lines removed
makeSixthCardAnswerClue ()
}
func makeSixthCardAnswerClue () {
| 33 lines removed
replaceConsonantsFromFirstCardAnswerClue()
}
func replaceConsonantsFromFirstCardAnswerClue () {
| 4 lines removed
replaceConsonantsFromSecondCardAnswerClue()
}
func replaceConsonantsFromSecondCardAnswerClue () {
| 4 lines removed
replaceConsonantsFromThirdCardAnswerClue()
}
func replaceConsonantsFromThirdCardAnswerClue () {
| 4 lines removed
replaceConsonantsFromFourthCardAnswerClue()
}
func replaceConsonantsFromFourthCardAnswerClue () {
| 4 lines removed
replaceConsonantsFromFifthCardAnswerClue()
}
func replaceConsonantsFromFifthCardAnswerClue () {
| 4 lines removed
replaceConsonantsFromSixthCardAnswerClue()
}
func replaceConsonantsFromSixthCardAnswerClue () {
| 4 lines removed
removeVowelsFromFirstCardFirstLetters()
}
func removeVowelsFromFirstCardFirstLetters () {
| 4 lines removed
removeVowelsFromFirstCardSecondLetters()
}
func removeVowelsFromFirstCardSecondLetters () {
| 4 lines removed
removeVowelsFromFirstCardThirdLetters()
}
func removeVowelsFromFirstCardThirdLetters () {
| 4 lines removed
removeVowelsFromSecondCardFirstLetters()
}
func removeVowelsFromSecondCardFirstLetters () {
| 4 lines removed
removeVowelsFromSecondCardSecondLetters()
}
func removeVowelsFromSecondCardSecondLetters () {
| 4 lines removed
removeVowelsFromSecondCardThirdLetters()
}
func removeVowelsFromSecondCardThirdLetters () {
| 4 lines removed
removeVowelsFromThirdCardFirstLetters()
}
func removeVowelsFromThirdCardFirstLetters () {
| 4 lines removed
removeVowelsFromThirdCardSecondLetters()
}
func removeVowelsFromThirdCardSecondLetters () {
| 4 lines removed
removeVowelsFromThirdCardThirdLetters()
}
func removeVowelsFromThirdCardThirdLetters () {
| 4 lines removed
removeVowelsFromFourthCardFirstLetters()
}
func removeVowelsFromFourthCardFirstLetters () {
| 4 lines removed
removeVowelsFromFourthCardSecondLetters()
}
func removeVowelsFromFourthCardSecondLetters () {
| 4 lines removed
removeVowelsFromFourthCardThirdLetters()
}
func removeVowelsFromFourthCardThirdLetters () {
| 4 lines removed
removeVowelsFromFifthCardFirstLetters()
}
func removeVowelsFromFifthCardFirstLetters () {
| 4 lines removed
removeVowelsFromFifthCardSecondLetters()
}
func removeVowelsFromFifthCardSecondLetters () {
| 4 lines removed
removeVowelsFromFifthCardThirdLetters()
}
func removeVowelsFromFifthCardThirdLetters () {
| 4 lines removed
removeVowelsFromSixthCardFirstLetters()
}
func removeVowelsFromSixthCardFirstLetters () {
| 4 lines removed
removeVowelsFromSixthCardSecondLetters()
}
func removeVowelsFromSixthCardSecondLetters () {
| 4 lines removed
removeVowelsFromSixthCardThirdLetters()
}
func removeVowelsFromSixthCardThirdLetters () {
| 4 lines removed
cards.sixthCardThirdLetters = result
}
SECOND VIEW FUNCTIONS
shuffleFirstCardLetterClues ()
})
func shuffleFirstCardLetterClues () {
| 13 lines removed
shuffleSecondCardLetterClues()
}
func shuffleSecondCardLetterClues () {
| 12 lines removed
shuffleThirdCardLetterClues()
}
func shuffleThirdCardLetterClues () {
| 12 lines removed
shuffleFourthCardLetterClues()
}
func shuffleFourthCardLetterClues () {
| 12 lines removed
shuffleFifthCardLetterClues()
}
func shuffleFifthCardLetterClues () {
| 12 lines removed
shuffleSixthCardLetterClues()
}
func shuffleSixthCardLetterClues () {
| 12 lines removed
removeCommasFromWordClues()
}
func removeCommasFromWordClues () {
| 38 lines removed
firstCardsJoined()
}
func firstCardsJoined () {
| 5 lines removed
firstCardsLettersJoined()
}
func firstCardsLettersJoined () {
| 4 lines removed
secondCardsJoined()
}
func secondCardsJoined () {
| 5 lines removed
secondCardsLettersJoined()
}
func secondCardsLettersJoined () {
| 5 lines removed
thirdCardsJoined()
}
func thirdCardsJoined () {
| 5 lines removed
thirdCardsLettersJoined()
}
func thirdCardsLettersJoined () {
| 4 lines removed
fourthCardsJoined()
}
func fourthCardsJoined () {
| 5 lines removed
fourthCardsLettersJoined()
}
func fourthCardsLettersJoined () {
| 4 lines removed
fifthCardsJoined()
}
func fifthCardsJoined () {
| 5 lines removed
fifthCardsLettersJoined()
}
func fifthCardsLettersJoined () {
| 3 lines removed
sixthCardsJoined()
}
func sixthCardsJoined () {
| 5 lines removed
sixthCardsLettersJoined()
}
func sixthCardsLettersJoined () {
| 4 lines removed
allCardsJoined()
}
func allCardsJoined () {
| 2 lines removed
gameArray = formArray
}
Although the Markers are doing what I intended the actual Map View does not move to the new Marker location. The View remains on the first one viewed.
This I don’t understand considering the Markers are updating.
I DO APOLOGISE FOR THE FORMAT. TO FIT IT ALL IN I HAD TO REMOVE AS MUCH WHITESPACE AS POSSIBLE.
I hope despite this someone can spot where I have gone wrong because despite days of staring at this I can’t!
Location Helper
let location = LocationHelper.currentLocation
extension LocationHelper: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { }
public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location manager failed with error: \(error.localizedDescription)")
}
public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("Location manager changed the status: \(status)")
}
}
class LocationHelper: NSObject, ObservableObject {
static let shared = LocationHelper()
static let defaultLocation = CLLocationCoordinate2D(latitude: thisCardPositionLatitude, longitude: thisCardPositionLongitude)
static var currentLocation: CLLocationCoordinate2D {
guard let location = shared.locationManager.location else {
return defaultLocation
}
return location.coordinate
}
private let locationManager = CLLocationManager()
private override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
Map View
import SwiftUI
struct MyAnnotationItem: Identifiable {
var coordinate: CLLocationCoordinate2D
var color: Color?
let id = UUID()
}
struct GameMapView: View {
// Some code below deleted due to Character constraints
@ObservedObject var fourTeamBlue = FourTeamBlue()
// Some code above deleted due to Character constraints
@State private var seeNextCard = false
@State private var region: MKCoordinateRegion = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: MapDefaults.latitude, longitude: MapDefaults.longitude), span: MKCoordinateSpan(latitudeDelta: MapDefaults.zoom, longitudeDelta: MapDefaults.zoom))
let annotationItems = [MyAnnotationItem(coordinate: CLLocationCoordinate2D(latitude: thisCardPositionLatitude, longitude: thisCardPositionLongitude), color: .red)]
private enum MapDefaults {
static let latitude = thisCardPositionLatitude
static let longitude = thisCardPositionLongitude
static let zoom = 0.0001
}
var body: some View {
VStack {
Map(coordinateRegion: $region, interactionModes: .all, showsUserLocation: true, annotationItems: annotationItems) { item in
MapMarker(coordinate: item.coordinate)
}
.edgesIgnoringSafeArea(.all)
}
VStack(alignment: .center){
Button(action: {
self.seeNextCard.toggle()
}){
Text("Next ▶️")
.font(.headline)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .center)
.padding()
}.sheet(isPresented: $seeNextCard) {
// Some code below deleted due to Character constraints
if nextPosition == "FourTeamBluePositionFiveView" {
FourTeamBluePositionFiveView(fourTeamBlue:fourTeamBlue)
}else if nextPosition == "FourTeamBluePositionFourView" {
FourTeamBluePositionFourView(fourTeamBlue:fourTeamBlue)
}else if nextPosition == "FourTeamBluePositionThreeView" {
FourTeamBluePositionThreeView(fourTeamBlue:fourTeamBlue)
}else if nextPosition == "FourTeamBluePositionTwoView" {
FourTeamBluePositionTwoView(fourTeamBlue:fourTeamBlue)
}else if nextPosition == "FourTeamBluePositionOneView" {
FourTeamBluePositionOneView(fourTeamBlue:fourTeamBlue)
}
// Some code above deleted due to Character constraints
}
}
}
}
This View passes the Marker Latitude and Longitude to the Map View
struct FourTeamBluePositionTwoView: View {
@ObservedObject var fourTeamBlue = FourTeamBlue()
@State private var seePositionFourCard = false
@State private var disabled = true
@State private var fourTeamBluePositionTwoCardAnswer: String = ""
@State var color = 0;
var body: some View {
Form {
Section {
VStack(alignment: .center) {
Text ("Blue Team Position 2️⃣")
.font(.title)
.foregroundColor(.white)
.frame(maxWidth: .infinity, alignment: .center)
}
.background(Color.blue)
Section {
VStack(alignment: .center) {
TextField("answer then [RETURN]", text: $$fourTeamBluePositionTwoCardAnswer)
.keyboardType(.alphabet)
.disableAutocorrection(true)
.textInputAutocapitalization(.never)
.textCase(.lowercase)
.font(.title)
.foregroundColor(fourTeamBluePositionTwoCardAnswerColor(color: self.color))
.multilineTextAlignment(.center)
.onSubmit {
if (fourTeamBluePositionTwoCardAnswer == fourTeamBlue.fourTeamBlueSecondCardWords) {
disabled = false
color = 2
nextPosition = "FourTeamBluePositionFourView"
thisCardPositionLatitude = Double(fourTeamBlue.fourTeamBlueSecondCardLatitude)!
thisCardPositionLongitude = Double(fourTeamBlue.fourTeamBlueSecondCardLongitude)!
}
else {
disabled = true
color = 1
}
}
}
}
Section {
VStack(alignment: .center) {
Text(fourTeamBlue.fourTeamBlueSecondCardAnswerClue).kerning(10)
.font(.title)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .center)
}
}
}
}
}
}
VStack(alignment: .center) {
Button(action: {
self.seeFinish.toggle()
}) {
Text("To Position 4️⃣ ▶️")
.font(.headline)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .center)
.padding()
}.fullScreenCover(isPresented: $seeFinish) {
GameMapView()
}
}
.disabled(disabled)
}
}
func fourTeamBluePositionTwoCardAnswerColor(color: Int) -> Color
{
if(color == 1)
{
return Color.red;
}
else if(color == 2)
{
return Color.green;
}
else
{
return Color.black;
}
}
I am a “newbie” to Coding and Swift. To better understand the Code I have started breaking it up into chunks and formatting as per my example below.
My questions are 1) is “Is this bad practice”?
2) “Is it likely to lead to problems later on”?
let location = LocationHelper.currentLocation
class LocationHelper: NSObject, ObservableObject {
static let shared = LocationHelper()
static let DefaultLocation = CLLocationCoordinate2D(
latitude: (
thisCardPositionLatidude),
longitude: (
thisCardPositionLongitude))
static var currentLocation: CLLocationCoordinate2D {
guard let location = shared.locationManager.location else {
return DefaultLocation
}
return location.coordinate
}
private let locationManager = CLLocationManager()
private override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension LocationHelper: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) { }
public func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print("Location manager failed with error: \(error.localizedDescription)")
}
public func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("Location manager changed the status: \(status)")
}
}
I am trying to display two sets GPS Coordinates on a map, one being user’s current location and the other being coordinates input by the user.
The code below has been copied from a reliable source but does not work for me.
I am doing this in Playgrounds on an iPad where one can turn on permissions. I have turned on Core Location - When In Use.
The map displays and has responded to the user inputs although not centered?
Obviously I am doing something wrong and would truely appreciate some advice here.
Another question I have is regarding internet access while using MapKit and CoreLocationUI. If internet is required is there a way of pre-loading before use?
import MapKit
import CoreLocationUI
var lat = -27.907625
var long = 152.680835
struct ContentView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: (lat), longitude: (long)), span: MKCoordinateSpan(latitudeDelta: 0.00001, longitudeDelta: 0.00001))
var body: some View {
Map(coordinateRegion: $region, showsUserLocation: true, userTrackingMode: .constant(.follow))
.frame(width: 400, height: 800)
}
}
Still requires an error trap to prevent an index out of range when eg. hello.world. (no word after the world full-stop, hello..today also produces the same error for example) is mistakenly entered in my firstCardWords field. I have managed to trap spaces, not having the required number of full-stops and a nil entry but nothing after a full-stop produces an error that crashes the app.
Also is there a better way to handle this input (preferably not too complicated ) to prevent all instances that will cause index out of range in this example?
func makeFirstCardWordLetters () {
if cards.firstCardWords == "" {
cards.firstCardWords = "FIRST.CARD.WORD"
}
var numOccurrences = cards.firstCardWords.filter{ $0 == "." }.count
if numOccurrences != 2 {
cards.firstCardWords = "TWO.FULL-STOPS.PLEASE"
}
numOccurrences = cards.firstCardWords.filter{ $0 == " " }.count
if numOccurrences != 0 {
cards.firstCardWords = "NO.SPACES.PLEASE"
}
let str = cards.firstCardWords
let ch = Character(".")
cards.firstCardLettersResult = str.split(separator: ch).map { String($0) }
cards.firstCardFirstLetters = cards.firstCardLettersResult[0] as! String
cards.firstCardSecondLetters = cards.firstCardLettersResult[1] as! String
cards.firstCardThirdLetters = cards.firstCardLettersResult[2] as! String
makeSecondCardWordLetters()
}
In a nutshell I am looking for someone to either point me in the right direction for me to get help finishing my project or help me finish it.
I have written this app in Playgrounds on an iPad which works okay but it is still a bit clunky.
This is my first app ever and I might add written at the ripe old age of 69 (which is proof there are still functioning brain cells in older age). Please don’t let this influence you into thinking my app is not worth perusing to the publishing stage.
This app I am fairly sure is unique in that it is both an indoors and outdoors game which requires the participants to solve words which are used to navigate a course which can be around the world or in your backyard. It has been described to me as an excellent Team Bonding game. I have experienced the game being played with around thirty people but also as few as four people and they were all so much fun!
The app is at a stage beyond the concept stage and it is being used to build games and the games have been played successfully providing a lot of fun for a wide age group.
My vision of a completed app requires the app to still do the following…
To be able to generate a QR Code of a game built on one device which in turn can be read on other devices to play the same game.
To have the option of printing the cards that are used in the game (at present I have to do screenshots and save them for printing).
At present the game requires the participants to use two apps, mine for the clue solving and another for the navigation. If the navigation part could be done in my app it would make it so much better!
I have no idea what is involved in getting an app published which is something in itself that I need help with.
Some time in the future, maybe games in the form of a QR Code could be sold by subscription on the App Store? These games could be used for competitions or challenges etc.
This is a rough overview of where I am at and despite being pleased with my achievement (with help by Claude31, thanks again because without your help and patience I may have given up?) I realise I have reached the stage that only the experienced can get my app to the completion stage.
Any help in the form of pointers, developers that specialise in this, website suggestions or even your own similar experiences will be greatly appreciated.
Despite seeing many examples of this method used to remove “ from String VariablesI can’t get it to work…
Other characters work okay so the issue seems to be “\””
Can anyone help with this please.
inline-code
let removeQuotesFirstCardFirstWordClue = cards.firstCardFirstWordClue.replacingOccurrences(of: """, with: "")
cards.firstCardFirstWordClue = removeQuotesFirstCardFirstWordClue
inline-code
The three lines of code (//) that attempt to pass the contents from one variable to another crashes the app.
I added the (as! String) as suggested by the compiler because this error appeared instantly “ Cannot assign value of type 'Any' to type 'String' Insert " as! String" ”
I am still very new to Coding so this has me really stumped. Can someone shine some light on this please!
func extractFirstCardWordLetters () {
let str = "happy.new.year.to.one.and.all"
let ch = Character(".")
cards.firstCardLettersResult = str.split(separator: ch)
//cards.firstCardFirstLetters = cards.firstCardLettersResult [0] as! String
//cards.firstCardSecondLetters = cards.firstCardLettersResult [1] as! String
//cards.firstCardThirdLetters = cards.firstCardLettersResult [2] as! String
print(cards.firstCardLettersResult) // prints ["happy", "new", "year", "to", "one", "and", "all"]
print(cards.firstCardLettersResult[0]) // prints happy
print(cards.firstCardLettersResult[1]) // prints new
print(cards.firstCardLettersResult[2]) // prints year
}
Firstly I do apologise for the photos rather than the Code format but I am using an iPad and not a Computer.
Secondly, I am an absolute newbie and would be so grateful for some advice on this problem.
The first photo is two spliced together of one View which is a Form to input data into variables.
The second photo is of another View that I expected the data to be printed but this is not happening.
Please can somebody help as I have spent many days researching (which has been beneficial in learning more) but have hit a wall that I don’t seem to be able to get past!
Firstly I am an absolute newbie!
In Playgrounds on an iPad I have managed to convert a .csv data string to an Array that I use to print (in Console) several Cards.
Now that I have transferred this code to the “App” part I find it doesn’t work which I do understand why.
My question is how do I pass the index of this Array to the struct part in the App?
I am thinking of starting simple by passing it into a “List”.
Hope this all makes enough sense to point me in the right direction.
Thanks in advance 🙏🏻