I am trying to append two Sting Arrays in tuple but it gives me error?
This is my class:
import UIKit
var tuple : [(String, String)] = []
class ViewController: UIViewController , UICollectionViewDelegate{
let reuseIdentifier = "cell"
var url : [String] = []
var image : [String] = []
override func viewDidLoad(){
}
override func viewWillAppear(animated: Bool) {
for i in tuple{
url.append(i.0)
image.append(i.1)
print("URL values.............. \(url)")
print("Image values.............. \(image)")
}
NSUserDefaults.standardUserDefaults().setObject(url, forKey: "u")
NSUserDefaults.standardUserDefaults().setObject(image, forKey: "i")
NSUserDefaults.standardUserDefaults().synchronize()
var u = NSUserDefaults.standardUserDefaults().objectForKey("u")
var i = NSUserDefaults.standardUserDefaults().objectForKey("i")
tuple.removeAll()
tuple.append(u,i)
}
When I change the types to this:
var u : String = NSUserDefaults.standardUserDefaults().objectForKey("u") as! String
var i : String = NSUserDefaults.standardUserDefaults().objectForKey("i") as! String
Now it gives me that error:
How can I append a tuple to an array?
[Code removed]
Also, as a user told you in comment, naming an array tuple is bad habit. The name tuples would fit already much better
EDIT: As #originaluser2 said, you can also use tuple.append((u,i))
EDIT2: I think this is definitely what you're looking for (I also adjusted names to avoid confusion, you should too)
import UIKit
class ViewController: UIViewController , UICollectionViewDelegate{
let reuseIdentifier = "cell"
var tuples: [(String, String)] = []
var urls: [String] = []
var images: [String] = []
override func viewDidLoad(){
}
override func viewWillAppear(animated: Bool) {
for i in tuples {
urls.append(i.0)
images.append(i.1)
print("URL values.............. \(urls)")
print("Image values.............. \(images)")
}
NSUserDefaults.standardUserDefaults().setObject(urls, forKey: "u")
NSUserDefaults.standardUserDefaults().setObject(images, forKey: "i")
NSUserDefaults.standardUserDefaults().synchronize()
// Cast objects as NSArray, since it's a subclass of NSObject
// Only NSObject derivate classes can be used for these purposes
let u = NSUserDefaults.standardUserDefaults().objectForKey("u") as! NSArray
let i = NSUserDefaults.standardUserDefaults().objectForKey("i") as! NSArray
tuples.removeAll()
// For every element of the first NSArray
for index in 0 ..< u.count {
// Append in the tuples array the strings at position index
// of both array
// NSString and String class are bridged, so you can use them both
// in order to accomplish your needs. An NSArray btw can store NSString, but not String objects
tuples.append((u.objectAtIndex(index) as! String,i.objectAtIndex(index) as! String))
}
}
}
Related
I want to add strings from an array of dictionary from backend.
but it's always empty outside the fetch function
//fetch data
func fetchFaqs(){
let manager = APIManager()
manager.parsingGet(url: BaseURL.faqs) { (JSON, Status) in
if Status {
let dict = JSON.dictionaryObject
let data = dict!["data"] as! [[String:Any]]
self.faqs = data as! [[String : String]]
}
}
}
//Viewdidload
class FaqViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
var faqs = [[String:String]]()
var questions = NSMutableArray()
var answers = NSMutableArray()
#IBOutlet var faqsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
fetchFaqs()
self.faqsTableView.reloadData()
print(faqs)
// faqsTableView.rowHeight = UITableView.automaticDimension
// faqsTableView.estimatedRowHeight = 600
}
}
Reload the tableview inside the api call closure in Main thread
func fetchFaqs(){
let manager = APIManager()
manager.parsingGet(url: BaseURL.faqs) { (JSON, Status) in
if Status {
let dict = JSON.dictionaryObject
let data = dict!["data"] as! [[String:Any]]
self.faqs = data as! [[String : String]]
DispatchQueue.main.async {
self.faqsTableView.reloadData()
}
}
}
}
I am fetching the data from JSON using http in the following code:
I have an ObjectModel, DownloadModelProtocol, and TableViewController
(Modal.swift)
class OrderItemModal: NSObject {
var deptname: String!
var staffname: String!
var status: String!
var userid: String!
}
(DownloadOrderModal.swift):
protocol OrderDownloadProtocol: class {
func itemsDownload(items: Array<Any>)
}
...
let bmsOrders = NSMutableArray()
...
weak var delegate: OrderDownloadProtocol!
let urlPath = "http://localhost/production/api/db_orders.php"
func downloadItems() {
let url = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
...
for i in 0..<jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let bmsOrder = OrderItemModal()
....
bmsOrders.add(bmsOrder)
....
declaration:
var orderItems = [OrderItemModal]()
var filterArray= [OrderItemModal]()
func itemsDownload(items: Array<Any>) {
orderItems = items as! [OrderItemModal]
}
and viewDidLoad:
let bmsOrder = DownloadOrderModal()
bmsOrder.delegate = self
bmsOrder.downloadItems()
this is the JSON result:
(
{
"deptname" = "Production";
"staffname" = Warehouse;
"status" = 1;
"userid" = ware;
})
This the the search bar code
filterArray = orderItems.filter( { ($0. staffname) (of: searchText, options: .caseInsensitive) })
And finally, this is the error:
Cannot assign value of type '[OrderItemModal]' to type '[String]'
Ultimately, I will populate the data into a table.
You have a few issues. It seems that orderItems is an NSArray array of OrderItemModal values. The first thing you need to do is to stop using NSArray and use a Swift array of the proper type. In this case it should be [OrderItemModal]. You will need to ensure filterArray is also declared as [OrderItemModal].
The result of a filter on such an array will be an array of OrderItemModal but you are attempting to force cast the result as an array of String.
You are also force-casting the closure to be (Any) -> Bool. There's no need for that.
And lastly, you are needlessly using NSString. Stick with String.
All you need is:
filterArray = orderItems.filter { (item) -> Bool in
return item.staffname.range(of: searchText, options: .caseInsensitive) != nil
}
Even simpler:
filterArray = orderItems.filter { $0.staffname.range(of: searchText, options: .caseInsensitive) != nil }
I'm new to swift and i'm extracting data from Parse database.
The data column is stored as array in the database
i managed to extract it as AnyObject and now i want to display each item. AnyObject is displaying as 1 entry instead of array list
class PeopleTable: UITableViewController {
//let textCellIdentifier = "TextCell"
//var window: UIWindow?
//let emptyArray: [AnyObject] = []
var userFriends: [AnyObject] = []
override func viewDidLoad() {
super.viewDidLoad()
queryForTable()
print(userFriends)
}
func queryForTable() {
let relationQuery = PFQuery(className:"User_info")
relationQuery.whereKey("userID", equalTo:"id123")
var userfrnds = try? relationQuery.findObjects()
for eachFriend in userfrnds! {
self.userFriends.append(eachFriend["friends"])
}
}
print(userFriends) command Out Put :
[(
Rudzani,
Terrence,
Thendelano,
"Big-T",
Smallboy
)]
i want the out put to be :
Rudzani,
Terrence,
Thendelano,
"Big-T",
Smallboy
How do i convert AnyObject to Array list of Strings
userFriends is an array in an array, the printed output is of type [[String]].
var userFriends = []
Then get the inner array
let users = userFriends[0]
and join the items
let users = userFriends[0].joinWithSeparator(", ")
As the type is distinct, any further type casting is not needed.
Edit: You have probably to cast the type after retrieving the object
do {
let userfrnds = try relationQuery.findObjects()
for eachFriend in userfrnds {
self.userFriends.append(eachFriend["friends"] as! [String])
}
} catch let error as NSError {
print(error)
}
How can I check in Swift if a value is an Array. The problem is that an array of type Int can apparently not be casted to an array of type Any. Suppose I have an array myArray of type Int and execute the following:
if let array = myArray as? [Any] { return true }
it doesn't return true (which surprises me actually). The same thing appears with dictionaries. I want a dictionary of type String, Any (meaning that Any can be any type). How can I check if it is?
Thanks in advance.
Got it working like this, although it's not as beautiful as I would've hoped:
protocol ArrayType {}
extension Array : ArrayType {}
let intArray : Any = [1, 2, 3]
let stringArray : Any = ["hi", "hello", "world"]
intArray is ArrayType // true
stringArray is ArrayType // true
EDIT: I think I misunderstood your question before, now I got it though:
let intArray = [1, 2, 3]
let anyArray = intArray.map{ $0 as Any }
This is the only way to my knowledge.
You can simply
array is Array<Any>
Got it now, with the idea of #Kametrixom. It's extraordinary ugly but at least it works.
private protocol CJSONArrayType {
func toAny() -> [Any]
}
extension Array: CJSONArrayType {
private func toAny() -> [Any] {
return self.map { $0 as Any }
}
}
extension NSMutableArray: CJSONArrayType { }
extension NSArray: CJSONArrayType {
private func toAny() -> [Any] {
var result = [Any]()
for item in self {
result.append(item as Any)
}
return result
}
}
private protocol CJSONDictionaryType {
func toStringAny() -> [String: Any]
}
extension Dictionary: CJSONDictionaryType {
private func toStringAny() -> [String : Any] {
var result = [String: Any]()
for item in self {
result[item.0 as! String] = item.1 as Any
}
return result
}
}
extension NSMutableDictionary: CJSONDictionaryType { }
extension NSDictionary: CJSONDictionaryType {
private func toStringAny() -> [String : Any] {
var result = [String: Any]()
for item in self {
result[item.0 as! String] = item.1 as Any
}
return result
}
}
If you want to parse JSON, there are only a few supported types which are at least AnyObject rather than Any.
Then it's very easy to check for Array
func checkArray(item : AnyObject) -> Bool {
return item is Array<AnyObject>
}
let integer = 1
let string = "one"
let array = ["one", "two", "three"]
let dictionary = ["one" : 1, "two" : 2]
checkArray(integer) // false
checkArray(string) // false
checkArray(array) // true
checkArray(dictionary) // false
Apple highly recommends to constrain the types at compile time as much as possible
class DropTvViewController: UIViewController , UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var dataTransfer = DataTransfer()
var responseString : String = ""
let storeData = StoreData()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
let pfod = PostForData()
pfod.forData
{ jsonString in
self.responseString = jsonString as String
var dict = self.dataTransfer.jsonToArray(self.responseString)!
if let x: AnyObject = dict.valueForKey("readlist")
{
println( dict.count )
println("X + \(x)")
for var i = 0 ; i < dict.count-1 ; i+=2
{
println("i : \(i)")
let y: AnyObject = x.objectAtIndex(i)
let z: AnyObject? = y.objectForKey("epipic")
let title : AnyObject? = y.objectForKey("epititle")
let time : AnyObject? = y.objectForKey("droptagcreatetime")
let pg : AnyObject? = y.objectForKey("pgname")
var imagessss = UIImage (data : pfod.forPicture())
self.storeData.add(title as! String, aFs: pg as! String, aTs: time as! String, ph: imagessss! , field1s: z as! String, field2s: z as! String, field3s: z as! String, field4s: z as! String )
// I do reload in here,but it will delay about ten seconds.
// I am sure the data is ready to read
self.tableView.reloadData()
}
}
}
}
You can use self.tableView.reloadData() which you are doing, but just in the wrong part of the loop. Just move it outside and you should be fine :)
If you're looking to reload a specific table cell then try: self.tableView.reloadRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimation.None)
Answer taken from here: https://stackoverflow.com/a/26709571/4891259