Post not yet marked as solved
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 not yet marked as solved
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 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 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()
}
}
Post not yet marked as solved
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()
}
}
Post not yet marked as solved
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?
Post not yet marked as solved
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).
Post not yet marked as solved
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 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 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 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.