I use the realm database for my application (to-do list), everything works fine, BUT once I flew to another country and noticed that the records in the database are empty (the application gives out an empty list), upon arrival back to my country everything returned to normal ... Now I am again in a different country and the situation repeats again (database is empty), for some reason the database gives an empty list result, can you please explain why this is happening and how to fix that?
Output example
var dbToDoList = DBrealmToDoList()
var arrayToDoList: Results<RealmToDoList> {
get {
return dbToDoList.getArray()
}
}
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
dbToDoList.realm = realm
let current = arrayToDoList.filter { (_todo) -> Bool in
return _todo.date == date
}.first
self.selectedDate = date
if current != nil {
self.selectedLists = current?.lists
self.selectedListsSorted = self.selectedLists?.sorted(by: { (val, val2) -> Bool in
return (!val.value && val2.value)
})
}
}
And then in tableView I display the data from the selectedListsSorted
// MARK: UITableView
extension ToDoListViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return selectedListsSorted?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ToDoListTableViewCell
let current = selectedListsSorted?[indexPath.row]
cell.nameLabel.text = current?.key
cell.checkBox.isSelected = current?.value ?? false
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 90
}
}
Here is a class for working with db
class RealmToDoList: Object {
#objc private dynamic var dictionaryData: Data?
var lists: [String: Bool] {
get {
guard let dictionaryData = dictionaryData else {
return [String: Bool]()
}
do {
let dict = try JSONSerialization.jsonObject(with: dictionaryData, options: []) as? [String: Bool]
return dict!
} catch {
return [String: Bool]()
}
}
set {
do {
let data = try JSONSerialization.data(withJSONObject: newValue, options: [])
dictionaryData = data
} catch {
dictionaryData = nil
}
}
}
#objc dynamic var date : Date?
}
class DBrealmToDoList {
var realm: Realm!
func write(_ data: RealmToDoList) throws -> Bool {
var result = false
if (realm != nil) {
try! realm.write {
realm.add(data)
result = true
}
return result
} else {
throw RuntimeError.NoRealmSet
}
}
func getArray() -> Results<RealmToDoList> {
return realm.objects(RealmToDoList.self)
}
func delete(_ data: RealmToDoList) throws -> Bool {
var result = false
if (realm != nil) {
try! self.realm.write {
self.realm.delete(data)
result = true
}
return result
} else {
throw RuntimeError.NoRealmSet
}
}
func update(ofType:Object,value:AnyObject,key:String)->Bool{
do {
let realm = try Realm()
try realm.write {
ofType.setValue(value, forKeyPath: key)
}
return true
}catch let error as NSError {
fatalError(error.localizedDescription)
}
}
func filter(id:Int) -> RealmToDoList? {
let match = realm.objects(RealmToDoList.self).filter("id == %#",id).first
return match
}
func newToDoList(date : Date?,lists: [String: Bool]) -> RealmToDoList{
let pill = RealmToDoList()
pill.date = date
pill.lists = lists
return pill
}
}
I doubt that the matter is in the database, but I cannot understand what it is, because I don’t do a filter by country, etc.
The issue is the date because the date will change based on time zone and if you're selecting today's date/time in one time zone, it will be different that's what's in the database. So if a filter is based on this date
#objc dynamic var date : Date?
then that date will be "today" for whatever time zone you're in but a "today" date that was created this morning in a different time zone will not return the current time zones date.
e.g. if you create a new date/time it will be today in this timezone but could be yesterday in a different time zone.
Related
I retrieve data from MySql via PHP file to get users information and scores to load them in a table. I need to get the value of the first 3 users and put them in a Label outside the Table, it is like game leaders list. I attached an image to explain the idea.
Here is the structure code:
import Foundation
protocol HomeModelProtocol: AnyObject {
func itemsDownloaded(items: NSArray)
}
class HomeModel: NSObject, URLSessionDataDelegate {
weak var delegate: HomeModelProtocol!
let urlPath = "https://mywebsite.com/folder/callUserList.php" //this will be changed to the path where service.php lives
func downloadItems() {
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) { (data, response, error) in
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON(data!)
}
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let users = NSMutableArray()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let user = UsersModel()
//the following insures none of the JsonElement values are nil through optional binding
if let name = jsonElement["name"] as? String,
let email = jsonElement["email"] as? String,
let phoneNumber = jsonElement["phone"] as? String,
let userImage = jsonElement["image"] as? String
{
user.name = name
user.email = email
user.phoneNumber = phoneNumber
user.userImage = userImage
}
users.add(user)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: users)
})
}
}
Here is the model:
import Foundation
class UsersModel: NSObject {
//properties
var name: String?
var email: String?
var phoneNumber: String?
var userImage: String?
//empty constructor
override init()
{
}
//construct with #name, #address, #latitude, and #longitude parameters
init(name: String, email: String, phoneNumber: String, userImage: String) {
self.name = name
self.email = email
self.phoneNumber = phoneNumber
self.userImage = userImage
}
//prints object's current state
override var description: String {
return "Name: \(String(describing: name)), Email: \(String(describing: email)), Phone Number: \(String(describing: phoneNumber)), User Image: \(String(describing: userImage))"
}
}
Here is the code in the TableView controller:
var feedItems: NSArray = NSArray()
override func viewDidLoad() {
super.viewDidLoad()
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of feed items
return feedItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Retrieve cell
let cellIdentifier: String = "BasicCell"
let myCell: WinnerTableCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! WinnerTableCell
// Get the location to be shown
let item: UsersModel = feedItems[indexPath.row] as! UsersModel
// Get references to labels of cell
myCell.lbTextName!.text = item.name
return myCell
}
The data shows in the Table but I have no idea how to fill the 3 label with the 3 first users from the Table.
How can I get these values from the table and pass it to a label in the same ViewController?
Thanks
When adding this code:
if feedItems.count >= 3 {
lblFirstWinner.text = feedItems[0].name // 1st winner
lblSecondWinner.text = feedItems[1].name // 2nd winner
lblThirdWinner.text = feedItems[2].name // 3rd winner
}
it shows error: Value of type 'Any' has no member 'name'
Change itemsDownloaded method as
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
for (index, user) in items.enumerated() {
let user = user as! UserModel
switch index {
case 0: // 1st winner
lblFirstWinner.text = user.name
case 1: // 2nd winner
lblSecondWinner.text = user.name
case 2: // 3rd winner
lblThirdWinner.text = user.name
}
}
}
OR
Change your HomeModelProtocol method and feedItems type to [UsersModel]
protocol HomeModelProtocol: AnyObject {
func itemsDownloaded(items: [UsersModel]) // Changed
}
var feedItems =[UsersModel]() // Changed
override func viewDidLoad() {
super.viewDidLoad()
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func itemsDownloaded(items: [UsersModel]) {
feedItems = items
self.listTableView.reloadData()
if feedItems.count >= 3 {
lblFirstWinner.text = feedItems[0].name // 1st winner
lblSecondWinner.text = feedItems[1].name // 2nd winner
lblThirdWinner.text = feedItems[2].name // 3rd winner
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of feed items
return feedItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Retrieve cell
let cellIdentifier: String = "BasicCell"
let myCell: WinnerTableCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! WinnerTableCell
// Get references to labels of cell
myCell.lbTextName!.text = feedItems[indexPath.row].name // Changed
return myCell
}
Just you need to add a few lines in the below function and your solution will be done.
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
if feedItems.count >= 3 {
lblFirstWinner.text = feedItems[0].name // 1st winner
lblSecondWinner.text = feedItems[1].name // 2nd winner
lblThirdWinner.text = feedItems[2].name // 3rd winner
}
}
Let me know... is it working for you? and please also refer to #vadian comment on your question.
I'm trying to make a simple currency conversion application . here I am parsing json
static func fetchJson(key: String = "USD", completion: #escaping (ExchangeRates) -> ()) {
guard let url = URL(string: "https://open.er-api.com/v6/latest/\(String(describing: key))") else {return}
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
guard let safeData = data else {return}
do {
let results = try JSONDecoder().decode(ExchangeRates.self, from: safeData)
completion(results)
} catch {
print(error)
}
}.resume()
}
then I get a dictionary looks like:
"rates": {
"USD": 1,
"AED": 3.67,
"AFN": 105,
"ALL": 107.39,
"AMD": 481.52,
"ANG": 1.79,
"AOA": 538.31,
..... etc
this is how the structure in which the data is stored looks like
struct ExchangeRates: Codable {
let rates: [String: Double]
}
in the ViewController I have created an object that has the type of ExchangeRates struct and call the func fetchJson in viewDidLoad and save the result in finalCurrencies
var finalCurrencies: ExchangeRates?
then I created a tableview with the number of cells equal to
finalCurrencies.rates.count
tableViewCell has a currencyLabel with currency name (finalCurrencies.rates.key) and currencyTextField with currency value (finalCurrencies.rates.value)
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let currencyFetched = finalCurrencies {
return currencyFetched.rates.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? TableViewCell {
if let currencyFetched = finalCurrencies {
cell.currencyLabel.text = Array(currencyFetched.rates.keys)[indexPath.row]
cell.currencyTextField.accessibilityIdentifier = Array(currencyFetched.rates.keys)[indexPath.row]
let selectedRate = Array(currencyFetched.rates.values)[indexPath.row]
cell.currencyTextField.text = "\(selectedRate)"
return cell
}
}
return UITableViewCell()
}
}
And that's what I get in the end as a result enter image description here
QUESTION: I need to make it so that when the value in the textfield for a certain currency changes, the values of the other currencies change in real- time. as a live google currency converter. I should also be able to switch between currencies and change their values, while also the values of other currencies should change. also how to make it so that with each new number an existing dictionary finalCurrencies is used and not a func fetchJson ?
I suppose that I should use this func textField (so that the textField reacts to each addition of a number).
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
}
I'm a beginner and I've been thinking about this for a few days now and I don't know how to do it.thanks in advance.
First you need to calculate the ratio of the change for the currency which had its value modified, you'll then just map the values of the dictionary with that ratio:
extension Dictionary where Key == String, Value == Double {
mutating func applyChange(of currency: Key, with newValue: Value) {
guard
newValue != .zero,
let oldValue = self[currency],
oldValue != newValue,
oldValue != .zero
else { return }
let ratio = 1.0 + ((newValue - oldValue) / oldValue)
indices.forEach { values[$0] *= ratio }
}
}
If I've understood you correctly, I believe this would work.
Each time the user adjusts the value in the textField you'd loop through your rates dictionary, calculate the new rate and return an updated dictionary.
If I've misunderstood your goal please let me know and I'll do my best to assist :)
struct Converter {
let exchangeRates: [String: Double] = [
"USD": 1,
"AED": 3.67,
"AFN": 105,
"ALL": 107.39,
"AMD": 481.52,
"ANG": 1.79,
"AOA": 538.31
]
func convert(_ amount: String) -> [String: Double] {
var newRates = [String: Double]()
exchangeRates.forEach { (code, value) in
if let amount = Double(amount) {
newRates[code] = value * amount
}
}
return newRates
}
}
let converter = Converter()
let userInput = "10.00"
print(converter.convert(userInput))
I have a model object being returned in JSON from Firebase.
{
"id": 1,
"name": "Jon Doe",
"time": ["1525592246"]
},
{
"id": 2,
"name": "Jane Doe",
"time": ["1525592266"]
},
I would like to structure these objects into sections in a UITableView based on the below:
enum DiarySectionType {
case Today
case Tomorrow
case ThisWeek
case ThisMonth
case Later
}
I.e If a "time" is today it will be in the today section of the UITableView
What is the best way to approach this? I've thought of having separate arrays for each. But don't think that's the way to go.
As always any help appreciated.
First you need helper extension for your Date
extension Date {
public func component(_ component: Calendar.Component) -> Int {
let calendar = Calendar.autoupdatingCurrent
return calendar.component(component, from: self)
}
public var isToday: Bool {
let calendar = Calendar.autoupdatingCurrent
return calendar.isDateInToday(self)
}
public var isTomorrow: Bool {
let calendar = Calendar.autoupdatingCurrent
return calendar.isDateInTomorrow(self)
}
public var isThisWeek: Bool {
return isInSameWeek(date: Date())
}
public var isThisMonth: Bool {
return isInSameMonth(date: Date())
}
public var islater: Bool {
return isInSameMonth(date: Date()) ? false : true
}
}
extension Date {
func isInSameWeek(date: Date) -> Bool {
return Calendar.current.isDate(self, equalTo: date, toGranularity: .weekOfYear)
}
func isInSameMonth(date: Date) -> Bool {
return Calendar.current.isDate(self, equalTo: date, toGranularity: .month)
}
}
Then your Enum
enum DiarySectionType:Int{
case Today
case Tomorrow
case ThisWeek
case ThisMonth
case Later
case count // use for number of section
init (with date:Date){
if date.isToday {
self = .Today
}else if date.isTomorrow{
self = .Tomorrow
}else if date.isThisWeek{
self = .ThisWeek
}else if date.isThisMonth{
self = .ThisMonth
}else{
self = .Later
}
}
}
Your data Formalize as you need
struct Item{
var id : Int
var name : String
var time : Double
init(id:Int, name:String,time:Double) {
self.id = id
self.name = name
self.time = time
}
}
// Controller
class ViewController: UIViewController{
var data = [Item]() // your data before sections
var dataWork = [DiarySectionType: [Item]]() // date After sections
override func viewDidLoad() {
super.viewDidLoad()
self.sortData()
}
// When generating sorted table data we can easily use our TableSection to make look up simple and easy to read.
func sortData() {
dataWork[.Today] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time)) == .Today })
dataWork[.Tomorrow] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time)) == .Tomorrow })
dataWork[.ThisWeek] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time)) == .ThisWeek })
dataWork[.ThisMonth] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time)) == .ThisMonth })
dataWork[.Later] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time)) == .Later })
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
// As long as `count` is the last case in our TableSection enum,
// this method will always be dynamically correct no mater how many table sections we add or remove.
func numberOfSections(in tableView: UITableView) -> Int {
return DiarySectionType.count.rawValue
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Using Swift's optional lookup we first check if there is a valid section of table.
// Then we check that for the section there is data that goes with.
if let tableSection = DiarySectionType(rawValue: section), let data = dataWork[tableSection] {
return data.count
}
return 0
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
var title : String = ""
if let tableSection = DiarySectionType(rawValue: section) {
switch tableSection {
case .Today:
title = "Today"
case .Tomorrow:
title = "Tomorrow"
case .ThisMonth:
title = "ThisMonth"
case .ThisWeek:
title = "ThisWeek"
case .Later:
title = "Later"
default:
title = ""
}
}
return title
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
// Similar to above, first check if there is a valid section of table.
// Then we check that for the section there is a row.
if let tableSection = DiarySectionType(rawValue: indexPath.section), let item = dataWork[tableSection]?[indexPath.row] {
// use item item
}
return cell
}
}
I'm clueless as to what is wrong. My console doesn't give me any errors, my code seems fine but nothing is showing up. Could someone check my code, see why it doesn't want to work? My tableView is connected with its delegates and source. Not sure what is the problem.
Here is my code:
private let cellIdentifier = "cell"
private let apiURL = "api link"
class TableView: UITableViewController {
//TableView Outlet
#IBOutlet weak var LegTableView: UITableView!
//API Array
var legislatorArray = [congressClass]()
func getLegislators (fromSession session: NSURLSession) {
//Calling url
if let jsonData = NSURL(string: apiURL) {
// Requesting url
let task = session.dataTaskWithURL(jsonData) {(data, response, error) -> Void in
//Check for errors
if let error = error {print(error)
} else {
if let http = response as? NSHTTPURLResponse {
if http.statusCode == 200 {
//Getting data
if let data = data {
do {
let legislatorData = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
//Get API data
if let getData = legislatorData as? [NSObject:AnyObject],
findObject = getData["results"] as? [AnyObject]{
//Return data
for cellFound in findObject{
if let nextCell = cellFound["results"] as? [NSObject:AnyObject],
name = nextCell["first_name"] as? String,
lastName = nextCell["last_name"] as? String,
title = nextCell["title"] as? String,
partyRep = nextCell["party"] as? String,
position = nextCell ["position"] as? String,
id = nextCell ["bioguide_id"] as? String
{
//Add data to array
let addData = congressClass(name: name, lastName: lastName, title: title, party: partyRep, position: position, bioID: id)
self.legislatorArray.append(addData)
}
}//end cellFound
//Adding data to table
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.tableView.reloadData()
}
}
}
//end do
catch {print(error)}
}//end data
}//end statusCode
}//end http
}//else
}//end task
//Run code
task.resume()
}//end jsonData
}
override func viewDidLoad() {
super.viewDidLoad()
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let urlSession = NSURLSession(configuration: sessionConfig)
getLegislators(fromSession: urlSession)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
//TableView Rows
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return legislatorArray.count
//return 5
}
//Cell Configuration
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CellTableView
cell.lesName?.text = legislatorArray[indexPath.row].name + " " + legislatorArray[indexPath.row].lastName
cell.lesTitle?.text = legislatorArray[indexPath.row].title
cell.lesParty?.text = legislatorArray[indexPath.row].party
//These tests worked fine.. the tableView is working. But the data doesn't seem to pass.
//cell.lesName.text = "Name" + " " + "lastName"
//cell.lesTitle.text = "Title goes here"
//cell.lesParty.text = "D"
return cell
}
}
You're not reloading the tableView
The problem is in this piece of code
//-----------------------------
//New empty array for api data
var indexPath:[NSIndexPath] = []
//Adding data to new array
for i in 0..<self.legislatorArray.count{
let secondIndexPath = NSIndexPath(forRow: i, inSection: 0)
indexPath.append(secondIndexPath)
}
//Adding data to table
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.tableView.insertRowsAtIndexPaths(indexPath, withRowAnimation: .Left)
}
You don't need any of that. You can just reload the tableView as follows:
//Adding data to table
dispatch_async(dispatch_get_main_queue()) { () -> Void in
//You only need to reload it and that should do the trick
self.tableView.reloadData()
}
I know you said your tableView is connected to the delegate and dataSource but it's not showing in your code.
You conformed the ViewController to the correct protocols but you need something like this in your viewDidLoad.
self.tableView.deletage = self
self.tableView.dataSource = self
//I don't know if this was a typo but in your cellForRowAtIndexPath you are using CellTableView
let nibName = UINib(nibName: "CellTableView", bundle:nil)
self.tableView.registerNib(nibName, forCellReuseIdentifier: cellIdentifier)
I created an example of a better design for your implementation
This is for the WebService and your Custom Class
https://github.com/phantomon/Stackoverflow/blob/master/SO1/MyTableView/MyTableView/Models/WebServiceManager.swift
This is for the ViewController with your tableView
https://github.com/phantomon/Stackoverflow/blob/master/SO1/MyTableView/MyTableView/ViewController.swift
You just need to modify the UITableViewCell with your custom one.
And of course review your custom class data.
Good day! I'm using Parse in my swift project, Now my problem is loading and saving the query or objects to the localDataStore, I tried this method
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as CustomPFTableViewCell!
if cell == nil {
cell = CustomPFTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
// Extract values from the PFObject to display in the table cell
if let placeName = object?["placeName"] as? String {
cell.cellName.text = placeName
}
if let station = object?["station"] as? String {
cell.cellDetail.text = station
}
if let placeImg = object?["placeImg"] as? String {
let decodedData = NSData(base64EncodedString: placeImg, options: NSDataBase64DecodingOptions(rawValue: 0))
// var decodedimage = UIImage(data: decodedData!)
var finImage = UIImage(data: decodedData!)
cell.cellBgImg.image = finImage
}
PFObject.pinAllInBackground(self.objects, block: { (succeeded, error) -> Void in
if (error == nil) {
}else {
println(error!.userInfo)
}
})
return cell
}
now in my queryForTable method i have this
override func queryForTable() -> PFQuery {
// Start the query object
var query = PFQuery(className: "Places")
// Add a where clause if there is a search criteria
if searchBar.text != "" {
query.whereKey("filterKeyword", containsString: searchBar.text.lowercaseString)
}
// Order the results
query.orderByAscending("placeName")
var cReturn = PFQuery()
if (IJReachability.isConnectedToNetwork()) {
cReturn = query
} else {
cReturn = query.fromLocalDatastore()
}
return cReturn
}
As you can see, I'm using Reachability to check if the device is connected to the internet. If not, The query will return query.fromLocalDataStore and if the device is connected it will return the normal query to get the latest data.
Now, my problem is when I'm turning off the internet to test it, it gives me an error 'Method requires Pinning enabled.' which i already did in tableView method
PFObject.pinAllInBackground(self.objects, block: { (succeeded, error) -> Void in
if (error == nil) {
}else {
println(error!.userInfo)
}
})
What do you think I did wrong? Thanks!
I think you should put the method where you pin the objects inside your objectsDidLoad() method and not in your cellForRowAtindexPath() method.