I am trying to get previews to work with swiftUI and my issue is
Library not loaded: /System/Library/Frameworks/AddressBook.framework/AddressBook
and it just loops my previews continually. I am using an older version of Xcode it is 13.1 but it is one of the latest ones my os supports. What can I do to fix this issue?
Post
Replies
Boosts
Views
Activity
So I have an app and it relies on Core Data to save and load favourite players. The issue I have is the data being loaded in my viewwillappear method is the max number of all the players regardless whether or not I save the data. When I access my favouritesVC I can't go back and add more players because they take up the max amount of storage. I need my app to retrieve the favourites I saved not all the players.
class FavouritesVC {
//this is a button I save my favourite players
//the print statements are accurate
@IBAction func save(_ sender: UIBarButtonItem) {
let entity = NSEntityDescription.entity(forEntityName: "CurrentPlayers", in: context)!
let saveFav = CurrentPlayers(entity: entity, insertInto: context)
for o in prefArr {
saveFav.yahooName = o.yahooName
saveFav.team = o.team
saveFav.position = o.position
saveFav.photoUrl = o.photoUrl
do {
try context.save()
print("These are my saved objects: \(saveFav)")
print("how many saved objects: \(prefArr.count)")
} catch {
print("error is: \(error)")
}
}
}
}
//what I use to load the data
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let fetchRequest = NSFetchRequest<CurrentPlayers>(entityName: "CurrentPlayers")
do {
prefArr = try context.fetch(fetchRequest)
for p in prefArr {
if p.yahooName == "Jordan *****" {
print("Jordan added")
}
}
print("There are this many saved favourites \(prefArr.count)")
} catch let error {
print("Could not fetch. \(error)")
}
}
}
//core data class file
import Foundation
import CoreData
enum DecoderConfigurationError: Error {
case missingManagedObjectContext
}
extension CodingUserInfoKey {
static let managedObjectContext = CodingUserInfoKey(rawValue: "managedObjectContext")!
}
@objc(CurrentPlayers)
public class CurrentPlayers: NSManagedObject, Decodable {
enum CodingKeys: String, CodingKey {
case photoUrl = "PhotoUrl"
case firstName = "FirstName"
case lastName = "LastName"
case position = "Position"
case team = "Team"
case yahooName = "YahooName"
case status = "Status"
case jerseyNumber = "Jersey"
}
public static var managedObjectContext: NSManagedObjectContext?
required public convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[.managedObjectContext] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
self.init(context: context)
//...
let values = try decoder.container(keyedBy: CodingKeys.self)
photoUrl = try values.decode(String.self, forKey: CodingKeys.photoUrl)
firstName = try values.decode(String.self, forKey: CodingKeys.firstName)
lastName = try values.decode(String.self, forKey: CodingKeys.lastName)
position = try values.decode(String.self, forKey: CodingKeys.position)
team = try values.decode(String.self, forKey: CodingKeys.team)
yahooName = try values.decodeIfPresent(String.self, forKey: CodingKeys.yahooName)
status = try values.decode(String.self, forKey: CodingKeys.status)
jerseyNumber = try values.decodeIfPresent(Int64.self, forKey: CodingKeys.jerseyNumber) ?? 0
}
}
I have an issue fetching objects from Core Data in my favourites section. I can save it with a button but I can not seem to retrieve the objects when I restart the app. I get it to print over 40000 (I have no idea why) and I see no favourites in my favourites section when I added them before.
override func viewDidLoad() {
super.viewDidLoad()
if currentFav == nil {
//display nil
fetchSave()
self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
} else {
NotificationCenter.default.post(name: .passFavNotification,
object: self.currentFav)
DispatchQueue.main.asyncAfter(deadline: .now() + 300) {
self.reviewRating.requestReview(isWrittenReview: false)
}
}
}
//trying to get this function to retrieve my objects in the persistent store
func fetchSave() {
let fetchRequest: NSFetchRequest<CurrentPlayers>
fetchRequest = CurrentPlayers.fetchRequest()
do {
let objects = try context.fetch(fetchRequest)
//I get over 40000 objects
print("These are how many saved favourites I have: \(objects.count)")
tableView.reloadData()
} catch {
print("Fetch failed")
}
}
@IBAction func save(_ sender: UIBarButtonItem) {
let saveFav = CurrentPlayers(context: context)
// Assign values to the entity's properties
for o in prefArr {
saveFav.yahooName = o.yahooName
saveFav.team = o.team
saveFav.position = o.position
saveFav.photoUrl = o.photoUrl
print("These are my saved objects: \(saveFav)")
// To save the new entity to the persistent store, call
// save on the context
}
do {
try context.save()
} catch {
print(error)
}
}
I have delete functionality in my app for favourites but when I delete a row but add another a favourite that row I just deleted is just added back to the top (gotta make sure that does not happen). I think this has to do with the notification.
class FavouriteManager {
static let shared = FavouriteManager()
//it's an array now
var favArr : [CurrentPlayers] = []
var noRepFav : [CurrentPlayers] = []
func add(_ player: CurrentPlayers) {
favArr.append(player)
for player in favArr {
if !noRepFav.contains(player) {
noRepFav.append(player)
}
}
NotificationCenter.default.post(
name: .passFavNotification,
object: player
)
}
}
class FavouritesVC: UITableViewController {
var prefArr: Array<CurrentPlayers> {
get { FavouriteManager.shared.noRepFav }
set { FavouriteManager.shared.noRepFav = newValue }
}
@objc
func handleFavNotification(notification: Notification) {
tableView.reloadData()
}
//delete function
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
prefArr.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
}
I'm trying to add delete functionality to my app and I am wondering how I can fix this error Cannot use mutating member on immutable value: 'favSet' is a get-only property.
class FavouriteManager {
static let shared = FavouriteManager()
var favSet: OrderedSet<CurrentPlayers> = OrderedSet()
func add(_ player: CurrentPlayers) {
favSet.append(player)
NotificationCenter.default.post(
name: .passFavNotification,
object: player
)
}
}
var favSet: OrderedSet<CurrentPlayers> {
FavouriteManager.shared.favSet
}
//delete function
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
favSet.remove(at: favSet.index(favSet.startIndex, offsetBy: indexPath.row)) //this is where the error is
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
I am trying to have my favourites persist when the app gets terminated and relaunches using Core Data. I made a save button to do just that but it does not seem to save the data in the way I intended and I lose the data when the app relaunches I don't get an error message. Any help is appreciated.
//this is my class for my favourites
import CoreData
enum DecoderConfigurationError: Error {
case missingManagedObjectContext
}
extension CodingUserInfoKey {
static let managedObjectContext = CodingUserInfoKey(rawValue: "managedObjectContext")!
}
@objc(CurrentPlayers)
public class CurrentPlayers: NSManagedObject, Decodable {
enum CodingKeys: String, CodingKey {
case photoUrl = "PhotoUrl"
case firstName = "FirstName"
case lastName = "LastName"
case position = "Position"
case team = "Team"
case yahooName = "YahooName"
case status = "Status"
case jerseyNumber = "Jersey"
}
public static var managedObjectContext: NSManagedObjectContext?
required public convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[.managedObjectContext] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
self.init(context: context)
//...
let values = try decoder.container(keyedBy: CodingKeys.self)
photoUrl = try values.decode(String.self, forKey: CodingKeys.photoUrl)
firstName = try values.decode(String.self, forKey: CodingKeys.firstName)
lastName = try values.decode(String.self, forKey: CodingKeys.lastName)
position = try values.decode(String.self, forKey: CodingKeys.position)
team = try values.decode(String.self, forKey: CodingKeys.team)
yahooName = try values.decodeIfPresent(String.self, forKey: CodingKeys.yahooName)
status = try values.decode(String.self, forKey: CodingKeys.status)
jerseyNumber = try values.decodeIfPresent(Int64.self, forKey: CodingKeys.jerseyNumber) ?? 0
}
}
//this is the class that has access to the saveContext
class PersistenceService {
private init() {}
static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: CoreData
static var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "playerModel")
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)")
}
})
return container
}()
static func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.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)")
}
}
}
}
//this is my save button function
@IBAction func saveFav(_ sender: UIBarButtonItem) {
print("saved button pressed")
let saveFav = CurrentPlayers(context: context)
for o in favSet {
saveFav.yahooName = o.yahooName
saveFav.team = o.team
saveFav.position = o.position
saveFav.photoUrl = o.photoUrl
}
PersistenceService.saveContext()
}
I am not sure how to transfer data a name from a button in my UITableViewCell to a UIViewController. I have a prepare function but it doesn't work gives me an unrecognized selector error. Is there a way to use it for this instance?
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "hs" {
let destinationController = segue.destination as! HighlightsVC
destinationController.playerName = (item.yahooName!)
}
}
I have an alert that I want to go to a specific site but after the user presses okay and for it to show only once. I can't figure out the part where the site is delayed because the user did not press okay.
var justOnce: Bool = true
@IBAction func playStats(_ sender: Any) {
//show alert only once
if justOnce {
let alert = UIAlertController(title: "Stats Important", message: "You can copy and paste the name here when you see the searchbar", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
justOnce = false
gotoSite()
}
}
I have an issue where the emulator behaves differently then the actual iPhone when running my Xcode app, (it has nothing to do with email). What could be the issue?
I have an issue with my SearchBar with scope working on my emulator but not on my iPhone properly. When I type the name of a specific player the iPhone shows me duplicates of the player but my emulator does not. What causes this issue? (I made the scoped bar programmatically but I don't see how that could cause an issue).
I'm trying to filter my players using searchBar with scope in a collectionview using a switch statement and my case 0 works but the issue is my other cases I can type into the searchBar but I can't seem to filter (nothing shows up) nor can I delete all the characters when I type.
I have 2 arrays my cPlayerArr is my original array when data is recieved and my allTextArr is my filtered array when any kind of filtering is done.
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
allTextArr = cPlayerArr.filter({ player - Bool in
switch searchBar.selectedScopeButtonIndex {
case 0:
if searchText.isEmpty {
fetchAllPlayers()
} else {
return
player.yahooName!.lowercased().contains(searchText.lowercased())
}
case 1:
if searchText.isEmpty {
fetchForwards()
} else {
print(searchText)
return player.yahooName!.lowercased().contains(searchText.lowercased()) && player.position == "C" &&
player.position == "RW" && player.position == "LW"
}
case 2:
if searchText.isEmpty {
fetchDefense()
} else {
return player.yahooName!.lowercased().contains(searchText.lowercased()) && player.position == "D"
}
case 3:
if searchText.isEmpty {
fetchGoalies()
} else {
return player.yahooName!.lowercased().contains(searchText.lowercased()) && player.position == "G"
}
default:
return false
}
return true
})
collections.reloadData()
}
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange: Int) {
if (searchBar.selectedScopeButtonIndex == 0) {
cPlayerArr.removeAll()
allTextArr.removeAll()
fetchAllPlayers()
} else if (searchBar.selectedScopeButtonIndex == 1) {
allTextArr.removeAll()
fetchForwards()
} else if (searchBar.selectedScopeButtonIndex == 2) {
allTextArr.removeAll()
fetchDefense()
} else {
allTextArr.removeAll()
fetchGoalies()
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) - Int {
if (searchBar.text != "" || searchBar.selectedScopeButtonIndex 0) {
return allTextArr.count
} else {
return cPlayerArr.count
}
}
I'm trying to figure out how to add a searchbar and a scope as a header to my UIViewController. The issue is I don't know the code to add it as a header.
func customizeSearch() {
let searchBar = UISearchBar(frame: CGRect(x:0, y:0, width: (UIScreen.main.bounds.width), height: 70))
searchBar.backgroundColor = UIColor.black
searchBar.delegate = self
searchBar.scopeButtonTitles = ["All", "Forwards", "Defensemen", "Goalies"]
//self.tableView.tableHeaderView = searchBar if I had a tableview, I have a vc.
}
I'm trying to use CoreData to save my favourites so that they will be accessed when the program terminates but I am not sure how to make my object persistent to do that.
@IBAction func addToFav(_ sender: Any) {
let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
alert.addAction(UIAlertAction(
title: "OK",
style: UIAlertAction.Style.default)
{ _ in
if let favPlayer = self.item /*this needs to be persistent*/ {
FavouriteManager.shared.add(favPlayer)
PersistenceService.saveContext()
}
})
self.present(alert, animated: true, completion: nil)
print("Favourite button Pressed")
}
I have a PersistenceService class I can more easily access my CoreData values.
class PersistenceService {
private init() {}
static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: CoreData
static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "playerModel")
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)")
}
})
return container
}()
static func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.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)")
}
}
}
}
I'm trying to pass data forward from my HdVC to my FaVC with Notification Center using a button called addToFav and it does not seem to pass my data I call var item. I need a little help figuring it out a way to modify the code so my item can be passed and set to a variable currentFav I have in my FaVC.
HdVC
class HockeyDetailVC: UITableViewController {
let imageController = FetchImage()
var item: CurrentPlayers? /* This object value I want in FaVC */
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(handleFavNotification(notification:)),
name: .passFavNotification,
object: nil)
}
@objc func handleFavNotification(notification:Notification){
if let theFav = notification.object as? CurrentPlayers {
self.item = theFav
}
}
@IBAction func addToFav(_ sender: Any) {
let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
print("Favourite button Pressed")
let passDataVC = FavouritesVC() /* I think passDataVC is supposed to be different because I use storyboard but I don't know what else it's supposed to be. */
self.present(passDataVC, animated: true, completion:nil)
}
FaVC
class FavouritesVC: UITableViewController {
var currentFav: CurrentPlayers? /*this is the variable I want to set my item too. */
var favArr = [CurrentPlayers]()
override func viewDidLoad() {
super.viewDidLoad()
if currentFav == nil {
self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
} else {
NotificationCenter.default.post(name: .passFavNotification,
object: self.currentFav)
favArr.append(currentFav!)
print(currentFav!)
}
}
I'm trying to pass data forward and I am using storyboard but I can't use a segue because it will dismiss my initial view controller. What technique should I do to pass it forward without pushing my initial viewcontroller? I tried using storyboardID to initialize the destination viewcontroller but that does not work either.