(Swift.LazyMapCollection<Swift.Dictionary<Swift.String, Swift.String>(_base:[ ] - string

The code says that it is perfectly fine and that there are no errors, but when I go to run the simulator, the words will include:
(Swift.LazyMapCollection < Swift.Dictionary < Swift.String, Swift.String > (_base:[ ]
I am trying to create a quote app that displays a quote.
Here is the code for the Import of the Plist:
import Foundation
struct ImportList {
let path: String
init(FileName: String) {
self.path = NSBundle.mainBundle().pathForResource("\(FileName)", ofType:"plist")!
}
var dict: Dictionary<String, String> {
return NSDictionary(contentsOfFile: path)! as! Dictionary
}
var array: Array<AnyObject> {
return [String](arrayLiteral: String(dict.keys) { $0 as String})
}
func count() -> Int {
return array.count
}
}
Thank you.

Don't use arrayLiteral in this case, just use Array():
var array: Array<AnyObject> {
return Array(dict.keys)
}
It safely converts the lazy collection to an actual array.

Related

Count core data attributes that fulfill a certain condition (SwiftUI)

I have created a core data entity with the following attributes (from Item+CoreDataProperties.swift file):
extension Item {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
return NSFetchRequest<Item>(entityName: "Item")
}
#NSManaged public var id: UUID?
#NSManaged public var likes: Int16
}
I am trying to return within ContentView a variable that shows the total number of Item that have more than 5 likes. What would be the best way to do this?
I've tried adding the following computed property, but it only checks whether the first item in the array fulfills the condition and I I'm not sure how to get it to loop over all of them.
#FetchRequest(entity: Item.entity(), sortDescriptors: [])
var item: FetchedResults<Item>
var likesCount:Int {
get {
if item[0].likes > 5 {
return 1
}
else {
return 0
}
}
}
I was also reading about a method called countForFetchRequest, but it seems to only be for detecting errors and I'm not sure it applies here.
Many thanks! Any help greatly appreciated.
Maybe something like this:
var countOfItems: Int {
getCount()
}
and then:
func getCount() -> Int {
var countOfItems: Int = 0
let context = PersistenceController.shared.container.viewContext
let itemFetchRequest: NSFetchRequest<Item> = Item.fetchRequest()
itemFetchRequest.predicate = NSPredicate(format: "likes > %d", 5)
do {
countOfItems = try context.count(for: itemFetchRequest)
print (countOfItems)
}
catch {
print (error)
}
return countOfItems
}

I want to acess the value of this json object without using the key name

{
"callExpDateMap": {
"2020-03-06:2": {
"305.0": [
{
"putCall": "CALL,
}
]
}
}
}
So this is my json object.And As you can see in "callExpDateMap",there is a date("2020-03-06:2" and then there is a value("305.0").The date("2020-03-06:2") and price("305.0") values will not be the same in every response.So If I want to access the value of "putCall" (Please remember that I can't use the key of the date and the price because it keeps changing in every response), How can I do this?...I'm using nodejs.
You need to pass this JSON to a function and call that function recursively with each inner object (or value of JSON key) and when value is string just print it or use in your way.
forEach(Object.keys(jsonobj))
function myfunc(key){
if((typeof jsonobj[key])==object){
forEach(Object.keys(jsonobj[key]));
}else{
console.log(jsonobj[key])
}
}
}
You could loop over the object and get the value,
Example:
let test = {
callExpDateMap: {
"2020-03-06:2": {
"305.0": [
{
putCall: "CALL"
}
]
}
}
};
let callExpDateMap = test.callExpDateMap;
for(const dateValue in callExpDateMap) {
for(const put in callExpDateMap[dateValue]) {
console.log(callExpDateMap[dateValue][put][0]['putCall']);
}
}
or you could use Object.keys to get the value. it's simpler then the previous approach;
let obj = {
callExpDateMap: {
"2020-03-06:2": {
"305.0": [
{
putCall: "CALL"
}
]
}
}
};
let callExpDateMap = obj.callExpDateMap;
let dateKey = Object.keys(callExpDateMap);
let price = Object.keys(callExpDateMap[dateKey]);
let putCall = callExpDateMap[dateKey][price];
console.log(putCall);

Core Data entries not updating correctly in swift3

I have a core data entries with certain keys and values stored in the database fetched from API . Now i want to update some core data entries with the updated values So for this i am using the code as below:
func updateAllRecords(responseArray: [Dictionary<String, String>]) {
for settingsObject in responseArray {
if #available(iOS 10.0, *) {
let keys = settingsObject.flatMap() { $0.0 as? String }
let values = settingsObject.flatMap(){ $0.1 as? String}
let request = NSFetchRequest<ApplicationSettings>(entityName: "ApplicationSettings")
do {
let context = persistentContainer.viewContext
let searchResults = try context.fetch(request)
for settingsKeys in searchResults {
if keys.contains(settingsKeys.key!) {
settingsKeys.value = values[1]
try context.save()
}
}
} catch {
print ("There was an error")
}
} else {
}
}
}
}
I am calling this function from viewcontroller like this:
var dicArray = [Dictionary<String, String>]()
let dic1 = ["IS_CIVIL_ID_MANDATORY": "Smith", "TIME_IN_MIN_BEFORE_ENABLING_START_TRIP": "Robert"]
dicArray.append(dic1)
CoreDataHandler.sharedInstance.updateAllRecords(responseArray: dicArray)
But the entries in the table is not updating correctly for the keys. It is storing the same value for both the keys. See below:
Where i am wrong in this code? Why same values are stored for the keys?
You made mistake here
settingsKeys.value = values[1] here 1 is static
I think you don't require values array separate
just replace this code with my code
for settingsKeys in searchResults {
if keys.contains(settingsKeys.key!)
{
settingsKeys.updateValue(settingObject[settingsKeys.key!], forKey:settingsKeys.key!)
try context.save()
}
}
}
For Demo Example
func updateAllRecords(responseArray: [Dictionary<String, String>])
{
for settingsObject in responseArray
{
var dic2 = ["IS_CIVIL_ID_MANDATORY": "xyz", "TIME_IN_MIN_BEFORE_ENABLING_START_TRIP": "xyz"]
let keys = settingsObject.flatMap() {$0.0}
let values = settingsObject.flatMap(){$0.1}
let settingKeys = dic2.flatMap() {$0.0}
for settingsKey in settingKeys
{
dic2.updateValue(settingsObject[settingsKey]!, forKey: settingsKey)
}
print(keys)
print(dic2)
}
}
var dicArray = [Dictionary<String, String>]()
let dic1 = ["IS_CIVIL_ID_MANDATORY": "Smith", "TIME_IN_MIN_BEFORE_ENABLING_START_TRIP": "Robert"]
dicArray.append(dic1)
updateAllRecords(responseArray: dicArray)
Output
["TIME_IN_MIN_BEFORE_ENABLING_START_TRIP": "Robert", "IS_CIVIL_ID_MANDATORY": "Smith"]

Compare Strings in Swift unit test

How do you test whether two Strings are equal in a Swift unit test? I've tried the == operator but it doesn't recognize it:
import XCTest
#testable import MyProject
class MyProject: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
XCTAssertNil(nil, "This test works")
}
func toJSONTest() {
let currentLocation = deviceLocation(timestamp: "2015-11-02 16:32:15 +0000",latitude: "40.2736577695212",longitude: "-111.715408331498")
var MyProjectStatuses = [MyProjectStatus(id: "", currentLocation: currentLocation)]
let json = ""
XCTAssertTrue(json == "")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
// Put the code you want to measure the time of here.
}
}
}
And the actual method being tested from MyProject.swift:
func toJSON ()->String{
var json = ""
json = "{\"myproject_status\":"
json = json + "{\"id\":\"" + self.Id + "\""
return json
}
This part:
XCTAssertTrue(json == "")
Throws:
Operator is not a known binary operator
The problem is that toJSONTest is not a test. Change the name to testToJSON.
This works fine on my machine:
func testToJSON() {
let json = ""
XCTAssertTrue(json == "")
}
The test runs, and passes. However, I would probably write it like this:
func testToJSON() {
let json = ""
XCTAssertEqual(json, "", "They are not equal")
}
Although this question is explicitly about how to compare two Strings in a Swift unit test, what's implicit in the question is how to compare two JSON Strings. I just wanted to point out that the right thing to do when comparing two JSON strings is to parse the JSON Strings to a Foundation object with the JSONSerialization class and then to compare the resulting Foundation objects. This approach takes care of the problem of the two JSON Strings having slightly different formatting or fields in a different order. So, for example, it's important that "{\"a\":1,\"b\":2}" and "{\"b\":2,\"a\":1}" are deemed to be equal because they are logically equal.
Here's a Swift function I put together which helps with this comparison:
class JSONAssert {
class func assertEquals(expected: String, actual: String) {
let expectedData = Data(expected.utf8)
let actualData = Data(actual.utf8)
let expectedObject: Any
let actualObject: Any
do {
expectedObject = try JSONSerialization.jsonObject(with: expectedData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `expected` (i.e. \(expected)): \(error)")
return
}
do {
actualObject = try JSONSerialization.jsonObject(with: actualData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `actual` (i.e. \(actual)): \(error)")
return
}
guard let expectedDictionary = expectedObject as? NSDictionary else {
XCTFail("Failed casting expected object (i.e. \(expectedObject)) to an NSDictionary")
return
}
guard let actualDictionary = actualObject as? NSDictionary else {
XCTFail("Failed casting actual object (i.e. \(actualObject)) to an NSDictionary")
return
}
XCTAssertEqual(expectedDictionary, actualDictionary)
}
}

ActionScript3 - augmenting prototype of String

In AS2 I could do the following:
String.prototype.startsWith = function(s){
return this.indexOf(s) == 1
}
thus, startsWith is available on every String object
var s = "some string to test with";
s.startsWith("some") // returns true
and did it with great repository of cool tools:
var s = "some #VAR string";
s.startsWith("some");//returns true
s.endsWith("ing");//returns true
s.contains("#");//returns true
s.dataBind({VAR: "awsome"})// returns 'some awsome string'
s = "b";
s.isAnyOf("a","b","c"); //true, because "b" is one of the options
s.isInArr(["a","b","c"]); //true, because "b" is in the passed array
var o = { foo: function(i) { return "wind " + i } }
s = "foo";
f.call(o,3) //returns "wind 3" because method foo is ivoked on o with 3
f.apply(o,[3]) //returns "wind 3" because method foo is ivoked on o with 3
var a1 = [], a2 = []
s.push(a1,a2) // pushes s into a1 and a2
And so on, and so forth with many cool things that makes coding much more fun (and blazing fast when smartly used)
It's not just about String, I have such utils for Number, Date, Boolean, and so on.
Here's what I tried:
[Test]
public function test_stringPrototype()
{
String.prototype.startsWith = function(s):Boolean
{
return return this.indexOf(s) == 1;
}
assertTrue( !!String.prototype.startsWith ) //and so far - so good ! this line passes
var s:String = "some str";
assertTrue(!!o.startsWith ) //and this won't even compile... :(
}
And this won't even compile, not to mention pass or fail the test...
error: Access of possibly undefined property startsWith through a reference with static type String.
Whats the way to do it in AS3?
you could always have the utility class that will collect all those methods and work on the string, e.g.
package utils
{
public class StringUtils
{
public static function startsWith(input:String, test:String):Boolean
{
return input.indexOf(test) == 0;
}
}
}
usage:
trace(StringUtils.startWith("My string", "My"));
or as a "global" function:
package utils
{
public function startsWith(input:String, test:String):Boolean
{
return input.indexOf(test) == 0;
}
}
usage:
trace(startWith("My string", "My"));
best regards
Yes of course, use string representation of a variable name: "startsWith"; Example down
String.prototype.traceME = function():void
{
trace(this);
}
var s:String = "some str";
s["traceME"]();
else method:
var s:Object = new String("some str");
s.traceME();

Resources