How to define objects in the code and of which type?
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate=UIApplication.sharedApplication().delegate as! AppDelegate
let context=appDelegate.managedObjectContext
let request=NSFetchRequest(entityName:lineEntityName)
do{
let objects = try context.executeFetchRequest(request)
}
catch let error as NSError {
print(error)
}
if let objectList=objects
{
for oneObject in objectList
{
let lineNum=oneObject.valueForKey(lineNumberKey) as integerValue
let lineText=oneObject.valueForKey(lineTextKey) as String
let lineField=lineFields(lineNum)
textField.text=lineText
}
}
else
{
print("There was an Error")
}
let app=UIApplication.sharedApplication()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"applicationWillResignActiveNotification", name: UIApplicationWillResignActiveNotification, object: app)
// Do any additional setup after loading the view, typically from a nib.
}
The recommended way is to put all good code in the do clause which solves the problem.
And executeFetchRequest returns a non-optional array so the optional binding can be omitted.
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDelegate.managedObjectContext
let request = NSFetchRequest(entityName:lineEntityName)
do {
let objects = try context.executeFetchRequest(request)
for oneObject in objects
{
let lineNum = oneObject.valueForKey(lineNumberKey) as integerValue
let lineText = oneObject.valueForKey(lineTextKey) as String
let lineField = lineFields(lineNum)
textField.text = lineText
}
let app = UIApplication.sharedApplication()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"applicationWillResignActiveNotification", name: UIApplicationWillResignActiveNotification, object: app)
// Do any additional setup after loading the view, typically from a nib.
}
catch let error as NSError {
print(error)
}
}
Related
I'm new to Swift, and trying my hands with UIWebView app that loads default url, with option to perform quick action and load a different url.
Problem is when I request the quick action url, code executes but the new url is not loading. So I'm missing something in the flow somewhere.
Here is the code:
import UIKit
import WebKit
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
override func loadView() {
super.loadView()
self.webView = UIWebView()
self.view = self.webView!
}
override func viewDidLoad() {
print("view did load")
super.viewDidLoad()
let url = NSURL(string: "google.com")
let req = NSURLRequest(URL:url!)
webView.loadRequest(req)
webView.delegate = self
}
func loadUrl2() {
loadView()
let url = NSURL(string: "example.com")
print(url)
let req = NSURLRequest(URL:url!)
self.webView!.loadRequest(req)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I was experimenting and added loadView to loadUrl2, as I was getting
fatal error: unexpectedly found nil while unwrapping an Optional value
before that.
Edited to Include loading secondary link:
Here are the changes and files you'll need to make to the App Delegate
enum ShortcutIdentifier: String {
case OpenNewLink
case OpenBetterLink
init?(fullIdentifier: String) {
guard let shortIdentifier = fullIdentifier.componentsSeparatedByString(".").last else {
return nil
}
self.init(rawValue: shortIdentifier)
}
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsAnnotationKey] as? UIApplicationShortcutItem {
handleShortcut(shortcutItem)
return false
}
return true
}
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
completionHandler(handleShortcut(shortcutItem))
}
private func handleShortcut(shortcutItem: UIApplicationShortcutItem) -> Bool {
let shortcutType = shortcutItem.type
guard let ShortcutIdentifier = ShortcutIdentifier(fullIdentifier: shortcutType) else {
return false
}
return selectLinkForIdentifier(ShortcutIdentifier)
}
private func selectLinkForIdentifier(identifier: ShortcutIdentifier) -> Bool {
guard let mainView = self.window?.rootViewController as? ViewController else {
return false
}
switch identifier {
case .OpenNewLink:
mainView.urlString = "http://www.bing.com"
mainView.loadWebView(mainView.urlString)
return true
case.OpenBetterLink:
mainView.urlString = "http://www.duckduckgo.com"
mainView.loadWebView(mainView.urlString)
return true
}
}
I also made changes in the MainVC
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
var urlString: String? = nil
override func viewDidLoad() {
super.viewDidLoad()
setUpWebView()
webView.delegate = self
view.addSubview(webView)
}
func setUpWebView() {
webView = UIWebView()
webView.frame = CGRectMake(0, 0, view.frame.width, view.frame.height)
loadWebView(urlString)
}
func loadWebView(var urlString: String?) {
if urlString == nil {
urlString = "http://www.google.com"
}
let url = NSURL(string: urlString!)
let req = NSURLRequest(URL:url!)
webView.loadRequest(req)
}
}
Be sure to add NSAppTransportSecurity dictionary to your .plist and add NSAllowsArbitraryLoads key set to YES.
I tested it and it should work for you.
I am creating document based app and I have strange problem - I can't open files which I saved. Each time I receive this error: "The document /name/ could not be opened". Here is output from NSError: The operation couldn’t be completed. (OSStatus error -4.)
Error Domain=NSOSStatusErrorDomain Code=-4 "kCFMessagePortTransportError / kCSIdentityDeletedErr / unimpErr: / / unimplemented core routine"
And my document class:
import Cocoa
class Document: NSDocument {
var saved: String = ""
let encoding = NSUTF8StringEncoding
override init() {
super.init()
// Add your subclass-specific initialization here.
}
override func windowControllerDidLoadNib(aController: NSWindowController) {
super.windowControllerDidLoadNib(aController)
// Add any code here that needs to be executed once the windowController has loaded the document's window.
}
override class func autosavesInPlace() -> Bool {
return true
}
override func makeWindowControllers() {
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let windowController = storyboard.instantiateControllerWithIdentifier("Document Window Controller") as! WindowController
self.addWindowController(windowController)
}
override func dataOfType(typeName: String) throws -> NSData {
saved = "tekst"
let dict: [String : AnyObject] = ["saved" : saved]
let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(dict)
return data
}
override func readFromData(data: NSData, ofType typeName: String) throws {
let dict: NSDictionary = NSKeyedUnarchiver.unarchiveObjectWithData(data)! as! NSDictionary
print(dict.objectForKey("saved")!)
print("^^")
let e = NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
print("localized desc: ")
print(e.localizedDescription)
throw e
}
}
I really can't find any solution.
i'm new in swift development, i added data in server tried to refresh tableviewcontroller with refreshcontrol function but value in table view didn't change.
class MainTableViewController: UITableViewController, UINavigationControllerDelegate {
#IBOutlet var sosTableView: UITableView!
var datas = [dataSos]()
override func viewDidLoad() {
super.viewDidLoad()
let spinningActivity = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
spinningActivity.labelText = "Loading"
spinningActivity.detailsLabelText = "Please wait"
dispatch_async(dispatch_get_main_queue()) {
self.loadDataServer()
spinningActivity.hide(true)
self.sosTableView.reloadData()
}
//loadDataSos()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
var refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: Selector("refreshData"), forControlEvents: UIControlEvents.ValueChanged)
self.refreshControl = refreshControl
}
Refresh func
func refreshData(){
dispatch_async(dispatch_get_main_queue()) {
self.loadDataServer()
self.sosTableView.reloadData()
}
refreshControl?.endRefreshing()
}
load server func
func loadDataServer(){
do {
let data = NSData(contentsOfURL: NSURL(string: "http://xxxx/scripts/xxx.php")!)
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
//let NumberOfPersons = jsonResult.count
// **LOOP THROUGH THE JSON ARRAY**
for anItem in jsonResult as! [Dictionary<String, AnyObject>] {
let userId = anItem["userId"] as! String
let userName = anItem["firstName"] as! String
let userAddress = anItem["address"] as! String
let userDate = anItem["date"] as! String
let userLocation = anItem["location"] as! String
var userEvent = anItem["event"] as? String
let sosId = anItem["sosId"] as! String
// do something with personName and personID
let imageUrl = NSURL(string:"http://xxx")
let imageData = NSData(contentsOfURL: imageUrl!)
if userEvent == nil{
userEvent = "Need Help"
}else if userEvent! == "1" {
userEvent! = "Thief"
}
else if userEvent! == "2" {
userEvent! = "Fire"
}
else{
userEvent! = "Healthy Issue"
}
//print(personName)
if imageData == nil{
let photo1 = UIImage(named: "defaultPhoto")!
let data1 = dataSos(userId: userId, name: userName, location: userLocation, address: userAddress, event: userEvent!, date: userDate, photo: photo1, sosId: sosId)
self.datas += [data1]
}
else{
let photo1 = UIImage(data: imageData!)
//let photo1 = UIImage(named: "defaultPhoto")
let data1 = dataSos(userId: userId, name: userName, location: userLocation, address: userAddress, event: userEvent!, date: userDate, photo: photo1, sosId: sosId)
self.datas += [data1]
}
}
} catch let error as NSError {
print(error)
}
// }
}
Update: table view data source
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// warning Incomplete implementation, return the number of rows
return datas.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MainTableViewCell
// Configure the cell...
let data0 = datas[indexPath.row]
cell.nameLabel.text = data0.name
cell.locationLabel.text = data0.location
cell.addressTextView.text = data0.address
cell.eventLabel.text = data0.event
cell.dateLabel.text = data0.date
cell.photoLabel.image = data0.photo
self.roundingUIView(cell.photoLabel, cornerRadiusParam: 35)
return cell
}
Ok, I just understood that you're inheriting for UITableViewController, therefor you already have tableView property inherited from it. The table view from this property has already set delegate and dataSource to your controller, but not for your custom sosTableView. You should replace your custom sosTableView with inherited tableView property and then everything gonna work as you're expecting.
import UIKit
import Parse
class HomePageViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var homPageTableView: UITableView!
var imageFiles = [PFFile]()
var imageText = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// DO any additional setup after loading the view
var query = PFQuery(className: "Posts")
query.orderByAscending("createdAt")
query.findObjectsInBackgroundWithBlock {
(posts : [AnyObject]?, error : NSError?) -> Void in
if error == nil {
//success fetxhing objects
println(posts?.count)
for post in posts! {
self.imageFiles.append(post["imageFile"] as! PFFile) ---------error here
self.imageText.append(post["imageText"] as! String)
}
println(self.imageFiles.count)
}else{ println(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
As a title, It is keep saying "unexpectedly found nil while unwrapping an Optional value" at the line I draw.
There are a lot of questions about this, it is hard to read code for me, And even if I undertood, mine didn't go right.
where should I use optional binding?
And can u explain it with really easy example what is optional binding?
Thank you
Your post dictionary does not contain an imageFile key. When you access a dictionary using post["imageFile"] the result is the value (if the key exists) and nil (if the key does not exist). You can distinguish between these cases using
if let imageFile = post["imageFile"],
let imageText = post["imageText"] {
self.imageFiles.append(imageFile as! PFFile)
self.imageText.append(imageText as! String)
} else {
print("imageFile and/or imageText missing from \(post)")
}
You need to unwrap your posts before looping through them because posts: [AnyObject]? is optional.
if error == nil {
if let postData = posts{
//success fetxhing objects
println(postData?.count)
for post in postData! {
self.imageFiles.append(post["imageFile"] as! PFFile)
self.imageText.append(post["imageText"] as! String)
}
println(self.imageFiles.count)
}
}else{
println(error)
}
Im working on an app and I would like it to populate the cells based on users who are within a set distance from the currentuser. For some reason the customcells are not being populated with the correct objects. The labels and images that are supposed to be retrieved are blank. All i get is a blank cell. I made sure i gave the cell identifier the correct name, and i also made sure to link the tableviewcontroller and the tablecellview to their respective classes,but still no luck.
first i created initializers:
class TableViewController: PFQueryTableViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
var currLocation: CLLocationCoordinate2D?
override init!(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.parseClassName = "User"
self.textKey = "FBName"
// self.imageKey = "pictureURL"
self.pullToRefreshEnabled = true
self.objectsPerPage = 10
self.paginationEnabled = true
}
Then in viewDidLoad i enabled location services:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 200
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
loadData()
println("location services enabled bruh")
}
}
Next i overrode the queryfortable function:
override func queryForTable() -> PFQuery! {
let query = PFQuery(className: "User")
if let queryLoc = currLocation {
query.whereKey("location", nearGeoPoint: PFGeoPoint(latitude: queryLoc.latitude, longitude: queryLoc.longitude), withinMiles: 50)
query.limit = 40
query.orderByAscending("createdAt")
println("\(queryLoc.latitude)")
return query
} else {
query.whereKey("location", nearGeoPoint: PFGeoPoint(latitude: 37.411822, longitude: -121.941125), withinMiles: 50)
query.limit = 40
query.orderByAscending("createdAt")
println("else statement")
return query
}
}
then the objectAtIndexPath function
override func objectAtIndexPath(indexPath: NSIndexPath!) -> PFObject! {
var obj : PFObject? = nil
if indexPath.row < self.objects.count {
obj = self.objects[indexPath.row] as? PFObject
}
return obj
}
and lastly I returned the cell, but for some reason it does not work:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!, object: PFObject?) -> PFTableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as TableViewCell
cell.userName?.text = object?.valueForKey("FBName") as? String
let userProfilePhotoURLString = object?.valueForKey("pictureURL") as? String
var pictureURL: NSURL = NSURL(string: userProfilePhotoURLString!)!
var urlRequest: NSURLRequest = NSURLRequest(URL: pictureURL)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue()) { (NSURLResponse response, NSData data,NSError error) -> Void in
if error == nil && data != nil {
cell.userImage?.image = UIImage(data: data)
}
}
cell.ratingsView?.show(rating: 4.0, text: nil)
return cell
}
ps, i have the number of sections set to 1, just didnt think that method would be useful to show here.
okay I found the issue! The issue was that I was trying to use PFQuery in order to retrieve a list of PFUsers. I found out that cannot be done using PFQuery infact PFUser has it's own query method for retrieving information from its users.
all i had to do was replace this line:
let query = PFQuery(className: "User")
with this:
let query = PFUser.query()