when I click on a mapview pin, a PopupView comes up with some text and a button. I want to be able to navigate to another DetailsView by clicking on the button display in the popup, the button is embedded inside NavigationLink. But clicking on the button nothing happens. How to navigate from button click?
struct MyMapView: View {
@State var position: MapCameraPosition = .automatic
@State var showCallout: Bool = false
@State var selected: PinAnnotation?
@Binding var locationPins: [PinAnnotation]
@State private var toggler = false
var body: some View {
Map(position: $position) {
ForEach(locationPins, id: \.self) { result in
Annotation(result.title!, coordinate: result.coordinate) {
ZStack {
Image(systemName: "mappin.circle.fill")
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
.onTapGesture {
selected = result
toggler.toggle()
}
.foregroundStyle(.white, .purple)
if selected == result && toggler {
PopupView(pin: selected)
} else {
EmptyView()
}
}
}
}
}
}
struct PopupView: View {
@State var pin: PinAnnotation?
@State private var select: Int? = 0
var body: some View {
VStack (alignment: .leading) {
HStack {
if let val = pin {
Text(val.text)
.font(.system(size: 12, weight: .light, design: .default))
NavigationLink(destination: DetailsView(), label: {
Button(action: {select = 1}){
Image(systemName: "play.circle")
}
.scaledToFit()
.frame(width: 50, height: 50)
.background(Color.blue)
.foregroundColor(.white)
.clipShape(Circle())
})
} else {
Text("no data")
}
}
// .fixedSize()
}
.scaledToFit()
.foregroundStyle(.purple)
.frame(maxWidth: .infinity)
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)
.offset(x: 0, y: -45)
}
}
struct DetailsView: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Group {
Button("Back") {
self.presentation.wrappedValue.dismiss()
}
}
}
}
}
Post
Replies
Boosts
Views
Activity
Trying to get weather data for a specific location and specific timezone. Generated Service identifier and Private Key, from Apple developer site.
Then Generated public key
Generated jwt token from jwt.io by keying in the payload, header, public, and private key.
Header
{
"alg" : "ES256", // predefined
"kid" : “keyid” , // key id created for WeatherKit
"id" : “developer_team_account_id.com.company_name.MyWeatherKit,
"typ" : "JWT"
}
Payload
{
"iat" : 1710117942,
"exp" : 1710204342,
"iss" : "developer_team_account_id",
"sub" : "com.company_name.MyWeatherKit
}
I
Then call this function:
func getWeatherData(requestId: String,
latitudeStr: String,
longitudeStr: String,
completion: @escaping (Bool) -> () ){
var country = "US"
var language = "en"
var tz = "CST"
let jwtToken = "token here...."
let urlString:String = "https://weatherkit.apple.com/api/v1/availability/" + language + "/" + latitudeStr + "/" + longitudeStr + "?" + "country=" + country + "&" + "timezone=" + tz
print("Apple weather urlString: \(urlString)")
let weatherURL = URL(string: urlString)
var request = URLRequest(url: weatherURL!)
request.httpMethod = "GET"
request.setValue("Bearer \(jwtToken)", forHTTPHeaderField: "Authorization")
let dataTask = URLSession.shared.dataTask(with:weatherURL!) { [self] responseData, response, error in
do {
print(response as Any)
print(error as Any)
if let data = responseData {
try DispatchQueue.main.sync { [unowned self] in
let decoder = JSONDecoder()
let jsonData = try decoder.decode(Top.self, from: data)
// parse data here
print(jsonData)
completion(true)
}
}
}
catch {
print("error: \(error.localizedDescription)")
completion(false)
}
}
dataTask.resume()
}
Gives response with code 403
Optional(<NSHTTPURLResponse: 0x280cbcf00> { URL: https://weatherkit.apple.com/api/v1/availability/en/29.928894042968750/-95.607747517125430?country=US&timezone=CST } { Status Code: 403, Headers {
"Access-Control-Allow-Origin" = (
"*"
);
Connection = (
close
);
"Content-Security-Policy" = (
"default-src 'self';"
);
Date = (
"Tue, 12 Mar 2024 02:52:18 GMT"
);
Server = (
Apple
);
"Strict-Transport-Security" = (
"max-age=31536000; includeSubdomains"
);
"X-Cache" = (
"TCP_MISS from a23-38-189-78.deploy.akamaitechnologies.com (AkamaiGHost/11.4.3-54729273) (-)"
);
"X-Content-Type-Options" = (
nosniff
);
"X-Frame-Options" = (
SAMEORIGIN
);
"X-REQUEST-ID" = (
"bac7e5dc-c5fd-6f85-263b-8f59b169cd2f"
);
"X-XSS-Protection" = (
"1; mode=block"
);
} })
The URL I am passing is : https://weatherkit.apple.com/api/v1/availability/en/29.928894042968750/-95.607747517125430?country=US&timezone=CST
Am I calling the wrong URL? Or is Apple weather service down? I am at a loss to understand. I need some help and guidance
What I am trying to accomplish:
Navigate to MapView defined in ProfileMapView. - This works
In ProfileMapView, when calloutAccessoryControlTapped method is called Navigate from ProfileMapView when to another view: ProfileDetailsView- This is does not work
//Calling ProfileMapview like this:
@State var pins = [GpsData.MyEndPt]()
ProfileMapView(locationPins: $pins)
// ProfileMapView defined
struct ProfileMapView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@State var tracking:MapUserTrackingMode = .follow
@Environment(\.presentationMode) var presentationMode
@Binding var locationPins: [GpsData.MyEndPt]
var body: some View {
TabView {
NavigationView {
ZStack {
VStack (alignment: .leading){
MapView(locationPins: $locationPins)
.ignoresSafeArea()
}
}
//.edgesIgnoringSafeArea(.all)
.safeAreaInset(edge: .bottom) {
Color.clear
.frame(height: 0)
.background(.white)
}
}
}
struct MapView: UIViewRepresentable {
@Binding var locationPins: [GpsData.MyEndPt]
func makeUIView(context: Context) -> MKMapView {
//...
}
func updateUIView(_ uiView: MKMapView, context: Context) {
//...
}
func makeCoordinator() -> MapViewDelegate{
var del = MapViewDelegate()
del.addEndPoints(endPoints: locationPins)
return del
}
class MapViewDelegate: MKMapView, MKMapViewDelegate {
let PINID:String = "MyEndPoint"
var mylocationPins: [GpsData.MyEndPt] = []
@State var locationId: String?
@State var providerType: String?
public func addEndPoints(endPoints: [GpsData.MyEndPt]) {
self.mylocationPins = endPoints
self.removeAnnotations(endPoints)
self.addAnnotations(endPoints)
self.showAnnotations(endPoints, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
for pin in self.mylocationPins {
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.rightCalloutAccessoryView = UIButton(type: UIButton.ButtonType.detailDisclosure)
subtitleView.text = "Target: "
subtitleView.text! += String(pin.target)
}
mPin!.detailCalloutAccessoryView = subtitleView
return mPin!
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
DispatchQueue.main.async {
if let thumbnailImageButton = view.leftCalloutAccessoryView as? UIButton,
let url = (view.annotation as? GpsData.MyEndPt)?.thumbnailUrl
{
print("URL: \(url)")
do{
let imageData: Data = try Data(contentsOf: url as URL)
let image = UIImage(data: imageData)
thumbnailImageButton.setImage(image, for: UIControl.State.normal)
}catch{
print("Unable to load image data: \(error)")
}
}
}
}
//MARK:- delegate method
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
mapView.deselectAnnotation(view.annotation, animated: true)
for detail in self.mylocationPins {
locationId = detail.locationId
providerType = detail.providerType
NavigationLink(value: control) {
ProfileDetailsView(locationId: $locationId, providerType: $providerType)
}
break
}
}
}
}
}
}
ProfileDetailsView defined like this:
@StateObject var manager = LocationManager()
@State var tracking:MapUserTrackingMode = .follow
@Environment(\.presentationMode) var presentationMode
@Binding var locationId: String?
@Binding var providerType: String?
var body:some View {
VStack (alignment: .leading){
Text("Details here...")
Button {
}
label: {
Text("Share")
.foregroundColor(.blue)
}
.buttonStyle(.bordered)
Button {
}
label: {
Text("Update consumption")
.foregroundColor(.blue)
}
.buttonStyle(.bordered)
}
}
}
I get warning: "Accessing State's value outside of being installed on a View. This will result in a constant Binding of the initial value and will not update." inside ProfileMapView line wheer I define @Binding var locationPins: [GpsData.MyEndPt]. That value is being passed into ProfileMapView - so I dont know why then warning.
However, ProfileMapView gets called, the mapview is displayed and the marker pin appears and when I click on the disclosure the navigation to other view ProfileDetailsView does not work. I tried NavigationStack and could not make it work because it threw lot of errors. How to fix the code in calloutAccessoryControlTapped method, so I can navigate to other view: ProfileDetailsView. I have spent a week on this trying various things but it hasn't worked.
From core data I generate data for map marker pins. When user selects a marker pin I display the data in a popup label with multiple rows, when I click on the pin. This is working for one marker pin. Now, I need to iterate over a list and generate several of those markers each with unique popup label data.
The code:
struct MapView: UIViewRepresentable {
var annotationOnTap: (_ title: String) -> Void
@Binding var pins: [GpsData.MyEndPt]
let key: String
private static var mapViewStore = [String : MKMapView]()
func makeUIView(context: Context) -> MKMapView {
if let mapView = MapView.mapViewStore[key] {
mapView.delegate = context.coordinator
return mapView
}
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
MapView.mapViewStore[key] = mapView
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.addAnnotations(pins)
}
func makeCoordinator() -> MapCoordinator {
MapCoordinator(self)
}
final class MapCoordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let PINID:String = "MyEndPoint"
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.withSize(12)
subtitleView.numberOfLines = 0
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.leftCalloutAccessoryView = nil
let btn = UIButton(type: .detailDisclosure)
mPin?.rightCalloutAccessoryView = btn
let zip:String = "77065"
let formattedSalesStr:String = "100"
let totalTargetText:String = "500"
let paddedLoad = formattedSalesStr.padding(toLength: 50, withPad: " ", startingAt: 0)
let paddedCapacity = totalTargetText.padding(toLength: 50, withPad: " ", startingAt: 0)
subtitleView.text = "Total sales: "
subtitleView.text! += paddedLoad
subtitleView.text! += " \r\n"
subtitleView.text! += "Total Target: "
subtitleView.text! += paddedCapacity
subtitleView.text! += " \r\n"
subtitleView.text! += paddedzip
mPin!.detailCalloutAccessoryView = subtitleView
return mPin!
}
}
}
As you can see in the above method I have hardcoded values for my popup marker label. So I tried to iterate over the @Binding pins, populate each mPin, and return an array of MKAnnotationView, like this:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> [MKAnnotationView] {
let PINID:String = "MyEndPoint"
var i:Int = 1
var mPins = [MKAnnotationView]()
for detail in self.parent.pins {
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.withSize(12)
subtitleView.numberOfLines = 0
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.leftCalloutAccessoryView = nil
let btn = UIButton(type: .detailDisclosure)
mPin?.rightCalloutAccessoryView = btn
subtitleView.text! += String(i)
subtitleView.text = "Total Load: "
subtitleView.text! += String(detail.sales)
subtitleView.text! += " \r\n"
subtitleView.text! += "Total Target: "
subtitleView.text! += String(detail.target)
subtitleView.text! += " \r\n"
i += 1
// }
mPin!.detailCalloutAccessoryView = subtitleView
mPins.append(mPin!)
}
return mPins
}
The marker pins show up, but then the label does not popup. How to fix this?
Loaded both Swift-Collection package 1.1.0 from https://github.com/apple/swift-collections and Facebook 14.1.0 package from https://github.com/facebook/facebook-ios-sdk
I open swift file and type import, the prompt shows the module FBSDKCorekit and as soon as select it, it immediately says module not found
Does the same thing for OrderedCollection module.
Did a clean and then also deleted DerivedData directory contents and rebuilt, same error occurs, does not recognize the modules, even though correct packages exist in Xcode
I tied with Faebook 16.3.1 and tried.
I deleted the project, created a new project, selected Add Package Dependencies and then deleted the recently sued packages, entered the facebook ios url and tried again. Same error, does not recognize the package contents
How can I fix this? Please help.
In Core data public configuration, added new attribute to entities, new entities, but the changes are neither synchronized nor data is transferred to existing container schema in cloudkit.
private var _publicPersistentStore: NSPersistentStore?
var publicPersistentStore: NSPersistentStore {
return _publicPersistentStore!
}
private var _privatePersistentStore: NSPersistentStore?
var privatePersistentStore: NSPersistentStore {
return _privatePersistentStore!
}
private var _sharedPersistentStore: NSPersistentStore?
var sharedPersistentStore: NSPersistentStore {
return _sharedPersistentStore!
}
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: “GS”)
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
guard let defaultDescription = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): failed to retrieve a persistent store description.")
}
let containerIdentifier = defaultDescription.cloudKitContainerOptions!.containerIdentifier
print(containerIdentifier)
print(defaultDescription.url as Any)
let url = defaultDescription.url?.deletingLastPathComponent()
print(url as Any)
// Public
let publicDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("public.sqlite"))
publicDescription.configuration = "Public"
print(publicDescription.url)
let publicOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
publicOptions.databaseScope = .public
publicDescription.cloudKitContainerOptions = publicOptions
publicDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
publicDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
// Private
let privateDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("private.sqlite"))
privateDescription.configuration = "Private"
print(privateDescription.url)
let privateOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
privateOptions.databaseScope = .private
privateDescription.cloudKitContainerOptions = privateOptions
privateDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
privateDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
// Shared
guard let sharedDescription = privateDescription.copy() as? NSPersistentStoreDescription else {
fatalError("#\(#function): Copying the private store description returned an unexpected value.")
}
sharedDescription.url = url!.appendingPathComponent("shared.sqlite")
print(sharedDescription.url)
sharedDescription.configuration = "Shared"
let sharedOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
sharedOptions.databaseScope = .shared
sharedDescription.cloudKitContainerOptions = sharedOptions
sharedDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
sharedDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.persistentStoreDescriptions = [publicDescription, privateDescription, sharedDescription]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
else {
if let cloudKitContainerOptions = storeDescription.cloudKitContainerOptions {
if #available(iOS 16.0, *) {
if .public == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded public store")
// self._publicPersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
} else if .private == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded private store")
//self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
} else if .shared == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded shared store")
//self._sharedPersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
}
} else {
// Fallback on earlier versions
}
}
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy // external changes trumping in-memory changes.
}
func save() {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Show some error here
print("save error")
}
}
}
}
Tried new container on cloudkit, problem persists. Working previously until I updated Xcode to 15.2 and iOs 16.2. Can you please tell me why coredata is not synchronized for public configuration.
coredata pushed schema to cloudkit only for those entities for which I created records. But the record data did not get pushed. I set recordName as Queryable and modifiedTimestamp as both Queryable and sortable. Query does not show the records. I look at Xcode console gives this output for one of the entities that got pushed to cloudkit :
CoreData: debug: CoreData+CloudKit: -[PFCloudKitSerializer newCKRecordsFromObject:fullyMaterializeRecords:includeRelationships:error:](575): Serializer has finished creating record: <CKRecord: 0x13f40f920; recordType=CD_Contact, recordID=26809600-B329-4C17-B3E1-6EA5FC177F7C:(com.apple.coredata.cloudkit.zone:__defaultOwner__), values={
"CD_contact" = "26809600-B329-4C17-B3E1-6EA5FC177F7C";
"CD_contactEmail_ckAsset",
"CD_contact",
"CD_contactEmail",
"<CKRecord: 0x13f40f920; recordType=CD_Contact, recordID=26809600-B329-4C17-B3E1-6EA5FC177F7C:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=5, values={\n \"CD_email\" = Email;\n \"CD_entityName\" = Contact;\n \"CD_firstName\" = V;\n \"CD_imageName\" = \"{ length=20834, sha256=d582bd2ccc7d93138b3a5ad4799443152860268e34f48ace54a0708f3e2f3aba }\";\n \"CD_lastName\" = R;\n \"CD_phone\" = 2;\n \"CD_screenName\" = Vr;\n \"CD_userRating\" = \"*****\";\n \"CD_userType\" = Household;\n}>",
Also schema for some other entities that do not have any core data records did not get pushed to CloudKit. I thought the entire coredata schema should get pushed along with the records. Looks like it is pushing those entities that have some records but without pushing data. I reset the cloudkit environment and tried again, but issue is not resolved.
Also the AppDelegate never gets called. I thought the line below should have called AppDelegate @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate: AppDelegate
Cross referenced persistenceController in AppDelegate. That did not help either
Code listed below. Please let me know how to fix the above two issues?
main
struct GreenApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate: AppDelegate
static var fcmToken: String?
let gcmMessageIDKey = "gcm.Message_ID"
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
struct PersistenceController {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
// for _ in 0..<10 {
// let newItem = Item(context: viewContext)
// newItem.timestamp = Date()
// }
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "Green")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy // external changes trumping in-memory changes.
}
}
Appdelegate code:
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate, ObservableObject {
static var fcmToken: String?
let gcmMessageIDKey = "gcm.Message_ID"
let persistenceController = PersistenceController.shared
func applicationDidFinishLaunching(_ application: UIApplication) {
do {
// Use the container to initialize the development schema.
try persistenceController.container.initializeCloudKitSchema(options: [])
} catch {
// Handle any errors.
fatalError("###\(#function): failed to load persistent stores: \(error)")
}
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { granted, error in
})
} else {
let settings: UIUserNotificationSettings = UIUserNotificationSettings(types:[.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
I am trying to get all records from Entity Location and pull the data from the entity to create a array of strings and display in a MenuPicker. In getLocationNames() ForEach statement it never pulls locations even though there are records. Also I do have a warning on that line: Result of 'ForEach<Data, ID, Content>' initializer is unused
entity: Location.entity(),
sortDescriptors: [NSSortDescriptor(key: "locationName", ascending: true)]
) var locations: FetchedResults<Location>
@State private var locationNames: [String] = []
@State private var locationDetails:[String] = []
@State private var selectedLocation: String? = nil
@State private var location: Location? = nil
var body: some View {
NavigationView {
ScrollView (showsIndicators: false) {
HStack {
Text("Select Location")
Picker("Location", selection: $selectedLocation , content: {
ForEach(locationNames,id: \.self, content: { locationName in
Text(locationName )
})
})
.pickerStyle(MenuPickerStyle())
.onReceive([self.selectedLocation].publisher.first()) { value in
selectedLocation = value
print("selectedLocation: \(selectedLocation ?? "not found")")
}
.onTapGesture {
// self.callWeatherAPI(location: selectedLocation)
self.getLocationNames()
}
Section{
if ($selectedLocation.wrappedValue != nil) {
}
}
header: {
Text("**Current Weather**")
.padding(.top, 10)
}
}
.navigationTitle("Weather")
.toolbar {
ToolbarItem(placement: .confirmationAction) {
// Button("Save", action: { Task { try? await rI?(nameInput, phoneInput) } })
Button("Detail", action: { onAdd()
} )
.foregroundColor(.blue)
}
}
}
.onAppear{
self.getLocationNames()
}
}
}
func getLocationNames() -> (Void){
ForEach(locations) { location in
locationNames.append( self.getLocationString(location: location))
}
}
private func getLocationString(location: Location) -> String {
var locDetails: String = location.locationType! + "; "
locDetails += location.locationName! + ", "
locDetails += location.zip!
return locDetails
}
}
I created project with Xcode 14.3. Then I upgraded to 14.3.1, Xcode would not start. I downgraded to 14.3 same issue Xcode would not start. Then downgraded to 14.2 Xcode started. But now I cannot edit the Textfield in any of the views in side the old project. I try to highlight the textfield, it shows a paste icon and allows me to paste whatever is in buffer from previous copy command. But it will not allow me to edit and enter data. In fact none of the Textfields in any of the views are editable.
How to fix this please?
My code below:
struct AddContactView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@State private var fNameInput: String = ""
@State private var lNameInput: String = ""
@State private var phoneInput: String = ""
@State private var emailInput: String = ""
@State private var screenNameInput: String = ""
@State private var consumerTypeInput: String = ""
@State private var defaultUserRating: String = "*****"
@State private var isShowPhotoLibrary = false
@State private var image = UIImage()
@State private var selectedPhoto: PhotosPickerItem?
@State private var selectedPhotoData: Data?
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack (alignment: .leading){
Form {
TextField("Full Name", text: $fNameInput)
.textContentType(.name)
.keyboardType(.alphabet)
TextField("Last Name", text: $lNameInput)
.textContentType(.name)
.keyboardType(.alphabet)
TextField("Phone Number", text: $phoneInput)
.textContentType(.telephoneNumber)
.keyboardType(.numberPad)
TextField("Email", text: $emailInput)
.textContentType(.emailAddress)
.keyboardType(.alphabet)
TextField("Consumer Type", text: $consumerTypeInput)
.textContentType(.name)
.textContentType(.name)
.keyboardType(.alphabet)
}
Spacer()
}
.padding()
.navigationTitle("Add Contact")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: { presentationMode.wrappedValue.dismiss() }, label: {
HStack(spacing: 2) {
Image(systemName: "chevron.backward")
.foregroundColor(.black)
Button("Back", action: {
self.presentationMode.wrappedValue.dismiss()
} )
.foregroundColor(.black)
}
})
}
}
.navigationBarBackButtonHidden(true)
}
}
View:
I have an existing ScrollView view with a Picker. Upon selection of a picker value, and user pressing the details button, I want to append a view to the bottom of the existing view. I call detailsView. But it does not seem to work.
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@Environment(\.presentationMode) var presentationMode
@Binding var chosenProvider: Provider?
@State var selectedLocation: Location?
@State private var vendorNames: [String] = []
@State private var selectedVendor:String? = nil
@State private var showingSheet = false
@State var state: String?
@State var zip: String?
var body: some View {
ScrollView {
VStack {
HStack {
Text("Select Vendor")
Picker("Provider", selection: $selectedVendor , content: {
ForEach(vendorNames,id: \.self, content: { name in
Text(name)
})
})
.pickerStyle(MenuPickerStyle())
.onTapGesture {
self.getVendorNames() { providers, status in
if (status) {
vendorNames = providers
}
}
}
}
.onChange(of: selectedVendor, perform: { newValue in
selectedVendor = newValue
})
.tint(.orange)
Button {
DetailsView()
} label: {
Label("Details", systemImage: "list.bullet.rectangle")
.foregroundColor(.blue)
}
Spacer()
}
}
.onAppear{
self.getVendorNames() { providers, status in
if (status) {
vendorNames = providers
}
}
}
.navigationTitle("Add Vendor")
.toolbar {
// Back button
ToolbarItem(placement: .navigationBarLeading) {
Button(action: { presentationMode.wrappedValue.dismiss() }, label: {
HStack(spacing: 2) {
Image(systemName: "chevron.backward")
.foregroundColor(.black)
Button("Back", action: {
self.presentationMode.wrappedValue.dismiss()
} )
.foregroundColor(.black)
}
})
}
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarBackButtonHidden(true)
}
struct DetailsView: View {
var body: some View {
VStack {
Text("Some Details")
}
}
}
func getVendorNames (completionHandler: @escaping ([String], Bool) -> Void ) {
var names = ["Acme", "Abc"]
completionHandler(names, true)
}
}
display simple view with two text fields inside a vStack/HStack combination. It leaves huge gap at the top as shown on the attached image. I tried vStack, it has .leading and .trailing which justifies left or right. How can set specific spacing at the top? code:
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@Environment(\.presentationMode) var presentationMode
@Binding var chosenPlan: ProviderApiCaller.ProviderData
@State var state: String?
@State var zip: String?
func onAdd(plan: ProviderApiCaller.ProviderData ) {
}
var body: some View {
NavigationView {
VStack {
HStack {
Text(chosenPlan.name!)
}
HStack {
Text(chosenPlan.plans.first!.planUrl)
}
}
}
.navigationTitle("Plan Details")
.toolbar {
// Back button
ToolbarItem(placement: .navigationBarLeading) {
Button(action: { presentationMode.wrappedValue.dismiss() }, label: {
HStack(spacing: 2) {
Image(systemName: "chevron.backward")
.foregroundColor(.black)
Button("Back", action: {
self.presentationMode.wrappedValue.dismiss()
} )
.foregroundColor(.black)
}
})
}
ToolbarItem(placement: .confirmationAction) {
// Button("Save", action: { Task { try? await rI?(nameInput, phoneInput) } })
Button("Save", action: { onAdd(plan: chosenPlan)
} )
.foregroundColor(.blue)
}
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarBackButtonHidden(true)
}
![]("https://developer.apple.com/forums/content/attachment/7510538e-c8b1-42d2-a68a-94d5aeaac186" "title=Screenshot 2023-05-26 at 4.11.30 PM.png;width=429;height=881")
In Xcode 14.2 Data Model is displayed as source code. I cannot change the view to relationships and cannot generate NSManagedObject classes. It is veriy difficult tom work with source code as I have more than 30 entities with inter-relationships. Can someone help.
If several users are sharing records with .readwrite permission with me, how can I find out who shared which CKRecord? I know user information is confidential information. But I need to be able to find out who shared so I can react to the shared record by either modifying or ignoring. I cannot find anything in Cloud Sharing website by Apple. Can someone give ideas/ponters?
The NSPersistentCloudKitContainer synchronization between core data and
iCloud was working fine with phone 15.1. Connected a new iPhone iOS 15.5, it gives error:
CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate managedObjectContextSaved:](2504): <NSCloudKitMirroringDelegate: 0x28198c000>: Observed context save: <NSPersistentStoreCoordinator: 0x2809c9420> - <NSManagedObjectContext: 0x2819ad520>
2022-12-05 13:32:28.377000-0600 r2nr[340:6373] [error] error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _importFinishedWithResult:importer:](1245): <PFCloudKitImporter: 0x2837dd740>: Import failed with error:
Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x65, 0x78, 0x61)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x65, 0x78, 0x61)}
CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _importFinishedWithResult:importer:](1245): <PFCloudKitImporter: 0x2837dd740>: Import failed with error:
Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x65, 0x78, 0x61)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x65, 0x78, 0x61)}
I go back and try with my old iPhone iOS 15.1, gives same error.
Inside the core data database, I created new private configuration. Then Created a new entity which got added to default configuration. Dragged the new entity to the newly created private configuration. It crashes.
Am I doing this right? If so is it Xcode 13.3.1 bug ? and should I upgrade?
Once I get past this issue, will the below given load persistent stores code
export/synchronize the new entity from core data private configuration to cloudkit private database?
container.loadPersistentStores(completionHandler: { (loadedStoreDescription, error) in
if let loadError = error as NSError? {
fatalError("###\(#function): Failed to load persistent stores:\(loadError)")
} else if let cloudKitContainerOptions = loadedStoreDescription.cloudKitContainerOptions {
if #available(iOS 14.0, *) {
if .public == loadedStoreDescription.cloudKitContainerOptions?.databaseScope {
self._publicPersistentStore = container.persistentStoreCoordinator.persistentStore(for: loadedStoreDescription.url!)
} else if .private == loadedStoreDescription.cloudKitContainerOptions?.databaseScope {
self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: loadedStoreDescription.url!)
}
} else {
// Fallback on earlier versions
}
}