Value of type 'UIViewController' has no member 'mapView'; did you mean 'loadView'? - mkmapview

I try to Search for locations using MKLocalSearchRequest in Swift4 (for ios 12). When I append thelocationSearchTable.mapView = mapViewat the end of viewDidLoad I get the error.
In ViewController
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
var resultSearchController: UISearchController? = nil
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
let locationSearchTable = storyboard!.instantiateViewController(withIdentifier: "LocationSearchTable")
resultSearchController = UISearchController(searchResultsController: locationSearchTable)
resultSearchController?.searchResultsUpdater = locationSearchTable as! UISearchResultsUpdating
let searchBar = resultSearchController!.searchBar
searchBar.sizeToFit()
searchBar.placeholder = "Search for places"
navigationItem.titleView = resultSearchController?.searchBar
resultSearchController?.hidesNavigationBarDuringPresentation = false
resultSearchController?.dimsBackgroundDuringPresentation = true
definesPresentationContext = true
locationSearchTable.mapView = mapView
}...
In the LocationSearchTable
import UIKit
import MapKit
class LocationSearchTable: UITableViewController {
var matchingItems: [MKMapItem] = []
var mapView: MKMapView? = nil
}
extension LocationSearchTable: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let mapView = mapView,
let searchBarText = searchController.searchBar.text else { return }
let request = MKLocalSearch.Request()
request.naturalLanguageQuery = searchBarText
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.start { response, _ in
guard let response = response else {
return
}
self.matchingItems = response.mapItems
self.tableView.reloadData()
}
}
}...

Maybe locationSearchTable is not LocationSearchTable class.
Try the following code
if let locationSearchTable = locationSearchTable as? LocationSearchTable {
locationSearchTable.mapView = mapView
}

Related

ARKit + SceneKit: not able to move node anchored to face

EDIT: link to project
I have a simple box anchored to the user's face, and I'd like to change it's XYZ position with 3 different UISlider controls. I have tried several methods, but nothing happens. The object stays static.
I think the code can speak better:
import Foundation
import UIKit
import ARKit
import SceneKit
class SceneKitViewController: UIViewController {
#IBOutlet private var sceneView: ARSCNView!
var rootNode: SCNNode!
override func viewDidLoad() {
super.viewDidLoad()
guard ARFaceTrackingConfiguration.isSupported else { return }
sceneView.delegate = self
sceneView.session.delegate = self
sceneView.automaticallyUpdatesLighting = true
sceneView.showsStatistics = true
rootNode = box
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARFaceTrackingConfiguration()
configuration.maximumNumberOfTrackedFaces = 1
configuration.isLightEstimationEnabled = true
sceneView.session.run(configuration, options: [])
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
sceneView.session.pause()
}
var box: SCNNode {
let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
let node = SCNNode(geometry: box)
node.position = SCNVector3(0,0,0)
return node
}
#IBAction func setXAxis(sender: UISlider) {
setNewPosition(SCNVector3(sender.value, rootNode.position.y, rootNode.position.z))
}
#IBAction func setYAxis(sender: UISlider) {
setNewPosition(SCNVector3(rootNode.position.x, sender.value, rootNode.position.z))
}
#IBAction func setZAxis(sender: UISlider) {
setNewPosition(SCNVector3(rootNode.position.x, rootNode.position.y, sender.value))
}
#IBAction func setScale(sender: UISlider) {
rootNode.scale = SCNVector3(sender.value, sender.value, sender.value)
}
private func setNewPosition(_ vector: SCNVector3) {
//
print("moving to \(vector)")
// rootNode.position = vector
// rootNode.localTranslate(by: vector)
updatePositionOf(rootNode, withPosition: vector)
}
func updatePositionOf(_ node: SCNNode, withPosition position: SCNVector3) {
var translationMatrix = matrix_identity_float4x4
translationMatrix.columns.3.x = position.x
translationMatrix.columns.3.y = position.y
translationMatrix.columns.3.z = position.z
node.transform = SCNMatrix4(translationMatrix)
}
}
extension SceneKitViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
if let _ = anchor as? ARFaceAnchor {
return rootNode
}
return nil
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
}
}
What am I not understanding here? Thanks!

fetch core data string and place in a label (Swift4)

I am trying to call 2 different core data strings and place them each on separate labels. Right now I am getting the error Cannot invoke initializer for type 'init(_:)' with an argument list of type '([NSManagedObject])'. This error is coming from j1.text = String(itemsName). I added both view controllers for saving and displaying.
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet var j1 : UITextField!
#IBOutlet var j2 : UITextField!
#IBAction func save(){
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Team", in : context)!
let theTitle = NSManagedObject(entity: entity, insertInto: context)
theTitle.setValue(j1.text, forKey: "score")
theTitle.setValue(j2.text, forKey: "alba")
do {
try context.save()
}
catch {
print("Tom Corley")
}
}}
class twoVC: UIViewController {
#IBOutlet var j1 : UILabel!
#IBOutlet var j2 : UILabel!
var itemsName : [NSManagedObject] = []
var itemsName2 : [NSManagedObject] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Team")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "score", ascending: true)]
let fetchRequest2 = NSFetchRequest<NSManagedObject>(entityName: "Team")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "alba", ascending: true)]
do {
itemsName = try context.fetch(fetchRequest)
itemsName2 = try context.fetch(fetchRequest2)
if let score = itemsName[0].value(forKey: "score") {
j1.text = (score as! String)
}
if let alba = itemsName2[0].value(forKey: "alba") {
j2.text = (alba as? String)
}
}catch {
print("Ashley Tisdale")
}
}}
Loop over the result from the fetch and append to a string that is then used as value for the label, this goes inside the do{...} where you do the fetch today. Note that I am only using one fetch request here.
itemsName = try context.fetch(fetchRequest)
var mergedScore: String = ""
var mergedAlba: String = ""
for item in itemsName {
if let score = item.value(forKey: "score") as? String {
mergedScore.append(score)
mergedScore.append(" ") //separator
}
if let alba = item.value(forKey: "alba") as? String {
mergedScore.append(alba)
mergedScore.append(" ") //separator
}
}
j1.text = mergedScore
j2.text = mergedAlba
Try this one it's Working for me Swift 4 I think You need to store the value as int which are used as sortDescriptor.
func FetchManagedObjectFromDatabaseForStoreData(Entity :NSEntityDescription) ->
[NSManagedObject]
{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
// Add Sort Descriptor
let sortDescriptor = NSSortDescriptor(key: "order", ascending: true)
let sortDescriptor1 = NSSortDescriptor(key: "is_favourite", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor,sortDescriptor1]
// Create Entity Description
fetchRequest.entity = Entity
let result : [NSManagedObject] = []
// Execute Fetch Request
do{
let result = try appDelegate.managedObjectContext.fetch(fetchRequest) as! [NSManagedObject]
if result.count > 0
{
return result
}
else
{
// return result
}
}
catch{
let fetchError = error as NSError
print(fetchError)
}
return result
}
For Fetch Data
// Create Entity Description
let entityDescription = NSEntityDescription.entity(forEntityName: "Your Entity Name Here", in: appDel.managedObjectContext)
let DataObject = FetchManagedObjectFromDatabaseForStoreData(Entity: entityDescription!)
//Convert Array of NSManagedObject into array of [String:AnyObject]
for item in DataObject{
let keys = Array(item.entity.attributesByName.keys)
// Here is your result
print((item.dictionaryWithValues(forKeys: keys) as NSDictionary).value(forKey: "id") as Any) // And so On Whatewer you Fetch
}

UIPickerView with Core Data Swift4

I am trying to re-use a code from swift 7.3. I feel I am very close.
When I try the code on the simulator, the picker view it is empty, but when I try to use it I have only one data show up.
I also try to adapt and other code to load data from core data to it, didn't work.
Any Idea?
Thank you
import CoreData
class ViewController: UIViewController, UIPickerViewDelegate, UIImagePickerControllerDelegate {
#IBOutlet weak var TextField: UITextField!
#IBOutlet weak var stylePicker: UIPickerView!
var styleData = [PilotBase]()
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "PilotBase")
do {
styleData = try context.fetch(fetchRequest) as! [PilotBase]
} catch let err as NSError {
print(err.debugDescription)
}
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "PilotBase")
request.returnsObjectsAsFaults = false
do{
let result = try context.fetch(request)
for data in result as! [NSManagedObject]{
print(data.value(forKey: "name") as! String)
}
}catch{
print("Failed")
}
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return styleData.count
} else {
return 0
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return styleData[row].name
} else {
return nil
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(styleData[row])
stylePicker.selectRow(row, inComponent: 0, animated: true)
TextField.text = styleData[row].name
}
}
Below the code to add data to Core Data.
#IBAction func Save(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "PilotBase", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(TextField.text!, forKey: "name")
do{
try context.save()
}catch{
print("failed saving")
}
}

How to write into the CoreData entity at the same index in different view controller (also swift files)

I have created core data using 'NSFetchedResultController' and 'managedObjectContext' in a table view. But in the later view controller, after gathering accelerometer data and conduct calculation, I will get some results that I also want to store in the same row index with the core data I created before.
How can I achieve this? If I create managedObjectContext again, it will create another 'row' of core data in this table.
The code in tableViewController:
'
let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
var fetchedResultController: NSFetchedResultsController = NSFetchedResultsController()
override func viewDidLoad() {
super.viewDidLoad()
fetchedResultController = getFetchedResultController()
fetchedResultController.delegate = self
fetchedResultController.performFetch(nil)
}
func getFetchedResultController() -> NSFetchedResultsController {
fetchedResultController = NSFetchedResultsController(fetchRequest: trialFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
return fetchedResultController
}
func trialFetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Trials")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: true)]
return fetchRequest
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
let numberOfSections = fetchedResultController.sections?.count
return numberOfSections!
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let numberOfRowsInSection = fetchedResultController.sections?[section].numberOfObjects
return numberOfRowsInSection!
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let trial = fetchedResultController.objectAtIndexPath(indexPath) as Trials
cell.textLabel?.text = trial.trialName
cell.detailTextLabel?.text = trial.date?.description
return cell
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
let managedObject:NSManagedObject = fetchedResultController.objectAtIndexPath(indexPath) as NSManagedObject
managedObjectContext?.deleteObject(managedObject)
managedObjectContext?.save(nil)
}
func controllerDidChangeContent(controller: NSFetchedResultsController!) {
tableView.reloadData()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "showTrial" {
let indexPath = tableView.indexPathForSelectedRow()
let trial:Trials = fetchedResultController.objectAtIndexPath(indexPath!) as Trials
let trialController:TrialDetailViewController = segue.destinationViewController as TrialDetailViewController
trialController.trial = trial
}
}
'
The code in the createTrial Controller:
' let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "createTrial" {
if theTrialName.text != "" {
createTrial()
} else {
let alertView = UIAlertController(title: "", message: "Trial name couldn't be empty", preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
presentViewController(alertView, animated: true, completion: nil)
}
}
}
func createTrial() {
let entityDescripition = NSEntityDescription.entityForName("Trials", inManagedObjectContext: managedObjectContext!)
let trial = Trials(entity: entityDescripition!, insertIntoManagedObjectContext: managedObjectContext)
trial.trialName = theTrialName.text
trial.location = theLocation.text
trial.notes = theNotes.text
if theArm.on {
trial.arm = 1
} else {
trial.arm = 0
}
managedObjectContext?.save(nil)
}
'
ps. the view controller I want to get data from is not this following segue, it is around 3 view afterwards. And I have created a string to store the data I need in that view.
I solved the problem by creating the object in the tableViewControllerand use segue twice to transmit it to secondViewControllerand thirdViewController. So it will be at the same index for the whole time. And I can change the content of the core data at both the following view controllers.

SWIFT: Why is "NSURL(string:" returning with Nil, even though it's a valid url in a browser?

The first two example links are working the third one returns NIL.
Why is NSUrl returning nil for such string, even though it's a valid url in a browser?
Am I supposed to process the string more?
Here is my code:
import UIKit
import Foundation
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSXMLParserDelegate {
var myFeed : NSArray = []
var url : NSURL!
var feedURL : NSURL!
var selectedFeedURL = String()
#IBOutlet var tableFeeds: UITableView!
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Set feed url.
//url = NSURL(string: "http://www.skysports.com/rss/0,20514,11661,00.xml")! //This seems to work
//url = NSURL(string: "http://www.formula1.com/rss/news/latest.rss")! //This seems to work
url = NSURL(string: "http://www.multirotorusa.com/feed/")!
loadRss(url);
}
func loadRss(data: NSURL) {
var myParser : XmlParserManager = XmlParserManager.alloc().initWithURL(data) as XmlParserManager
myFeed = myParser.feeds
tableFeeds.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myFeed.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var dict : NSDictionary! = myFeed.objectAtIndex(indexPath.row) as NSDictionary
cell.textLabel?.text = myFeed.objectAtIndex(indexPath.row).objectForKey("title") as? String
cell.detailTextLabel?.text = myFeed.objectAtIndex(indexPath.row).objectForKey("description") as? String
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var indexPath: NSIndexPath = self.tableFeeds.indexPathForSelectedRow()!
var selectedFeedURL = myFeed.objectAtIndex(indexPath.row).objectForKey("link") as String
selectedFeedURL = selectedFeedURL.stringByReplacingOccurrencesOfString(" ", withString:"")
selectedFeedURL = selectedFeedURL.stringByReplacingOccurrencesOfString("\n", withString:"")
// feedURL = NSURL(fileURLWithPath: selectedFeedURL) //This returns with: URL + /%09%09 -- file:///
feedURL = NSURL(string: selectedFeedURL) //This returns with NIL
println("Selected Feed URL: \(selectedFeedURL)")
println("Feed URL: \(feedURL)")
if feedURL != nil {
let request : NSURLRequest = NSURLRequest(URL: feedURL!)
webView.loadRequest(request)
println("Feed URL: \(feedURL)") //Doesn't make it here
}
}
}
Any suggestions?
You should URL-encode the URL like this:
selectedFeedUrl = selectedFeedUrl.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
In iOs 9:
myString = myString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
Hope it helps
For swift3 you can do like this
let url = URL(string:url.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!)!
Thank you guys for your help.
I added these two lines to my code and it works now:
selectedFeedURL = selectedFeedURL.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
selectedFeedURL = selectedFeedURL.stringByReplacingOccurrencesOfString("%09%09", withString:"")

Resources