Vapor build failed when the amount of columns in Node are more than 18? - vapor

I'm using "Model" with function "makeNode" in Vapor, and I can successfully build and run the project when the table columns amount are less than about 14.
But when my table columns goes to 19 or 20, then the Vapor starts to build very very slowly, and will report failed eventually.
I have tried using MySQL or MongoDB, both got the same issue. So I'm wondering how to fix this issue when I need to use a table that consists of 20 columns.
The below are the details:
final class TableName: Model {
var id: Node?
var column1: Int
var column2: Int
var column3: String
var column4: String
var column5: String
var column6: String
var column7: String
var column8: String
var column9: String
var column10: String
var column11: String
var column12: String
var column13: String
var column14: String
var column15: String
var column16: String
var createdAt: Double
var updatedAt: Double
init(column1: Int, column2: Int, column3: String, column4: String, column5: String, column6: String, column7: String, column8, column9: String, column10: String, column11: String, column12: String, column13: String, column14: String, column15: String, column16: String, createdAt: Double, updatedAt: Double) {
self.id = UUID().uuidString.makeNode()
self.column1 = column1
self.column2 = column2
self.column3 = column3
self.column4 = column4
self.column5 = column5
self.column6 = column6
self.column7 = column7
self.column8 = column8
self.column9 = column9
self.column10 = column10
self.column11 = column11
self.column12 = column12
self.column13 = column13
self.column14 = column14
self.column15 = column15
self.column16 = column16
self.createdAt = createdAt
self.updatedAt = updatedAt
}
init(node: Node, in context: Context) throws {
id = try node.extract("id")
column1 = try node.extract("column1")
column2 = try node.extract("column2")
// from 2~16, etc... don't repeat here...
updatedAt = try node.extract("updatedAt")
createdAt = try node.extract("createdAt")
}
// Issue happened here...
// when the amount less than about 10, results are ok and build fast,
// but will build slowly and slowly when the number goes more and more,
// even build failed when table columns goes to about 18~20.
func makeNode(context: Context) throws -> Node {
var node = try Node(node: [
"id": id,
"column1": column1,
"column2": column2,
"column3": column3,
"column4": column4,
"column5": column5,
"column6": column6,
"column7": column7,
"column8": column8,
"column9": column9,
"column10": column10,
"column11": column11,
"column12": column12,
"column13": column13,
"column14": column14,
"column15": column15,
"column16": column16,
"createdAt": createdAt,
"updatedAt": updatedAt
])
return node
}
}
And the build error message is:
Command failed due to signal: Killed: 9
So, I would be appreciate for giving me any hint to fix this issue. Thank you.

This sounds like a bug in the compiler. Type hinting (adding in as Foo, etc) is a good way to remedy a confused compiler.
Reporting the full output of the error to https://bugs.swift.org would help the team get it fixed ASAP.

Related

Copy string value to another string?

var phoneUDID: String?
var temporaryUDID: String?
var customUDID: String?
let md5Data = MD5(string: UIDevice.current.identifierForVendor!.uuidString)
let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
self.phoneUDID = md5Hex
self.temporaryUDID = (md5Hex + "#gmail.com")
self.customUDID = self.temporaryUDID
Information: I am using Swift 3 by the way!
Question: Is the self.customUDID = self.temporaryUDID line correct to use? Since they are both strings, is this a safe way of copying a string's value to another string? I submitted my app to the app store and saw this booboo and thought that errors could arise. Please convince me i'm safe. Thanks
String is a value type in Swift. So no, if you change one, the other won't change.
When you do
self.customUDID = self.temporaryUDID
A new string is created and stored in customUDID.
Example:
var s1 = "Foo"
var s2 = s1
s1 = "Bar"
print(s1,s2) //Prints "Bar Foo"

Cannot add an append an array into a dictionary that has an empty array

I have a Profile Data singleton class as follows.
I am trying to store data into an empty array in a dictionary .
After appending data to the array also the count of the array is 0.
class ProfileData{
static let sharedInstance = ProfileData()
var artistProfileDict = [String : Profile]()
var loggedInUserProfile = Profile(artistName: "John Smith", artistDescription: "Admiral of New England, English soldier, explorer, and author.", totalLikes: "174", totalViews: "200", totalFollowing: "100",totalFollowers:"50",imageUrl:"image_singer", feeds:[] )
private init() {
getProfilesDictionary()
}
func getProfilesDictionary()->[String: Profile]{
artistProfileDict["John Smith"] = loggedInUserProfile
return artistProfileDict
}
func add(array: Feed, artistName: String) {
artistProfileDict[artistName]!.feeds.append(array)
}
}
In another view Controller I am trying to add an array to the empty array in the dictionary as follows
let newFeed = Feed(profilePicture: "image",artistName: "New",
videoUrl: "url",videoTitle:"New", videoViews: "160",likes:
"200",shoutouts: "200",comments: [],votes: "50", dateCreated: Date(),
userActivity :"This user liked your video")
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
After appending the array to the empty array in the dictionary I still get the count of the array as 0.
I am not able to figure out the problem here. Any help will appreciated . Thank you.
Profile class
struct Profile {
var artistName: String
var artistDescription: String
var totalLikes: String
var totalViews: String
var totalFollowing: String
var totalFollowers: String
var imageUrl: String
var feeds : [Feed]
init(artistName: String,artistDescription:String,totalLikes:String,totalViews:String,totalFollowing:String,totalFollowers:String,imageUrl:String, feeds:[Feed]) {
self.artistName = artistName
self.artistDescription = artistDescription
self.totalLikes = totalLikes
self.totalViews = totalViews
self.totalFollowing = totalFollowing
self.totalFollowers = totalFollowers
self.imageUrl = imageUrl
self.feeds = feeds
}
}
It's working fine
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
ProfileData.sharedInstance.artistProfileDict["John Smith"]?.feeds.count // 1
Probably you are using wrong class ArtistProfileData instead of ProfileData.

How to update Firebase with struct

I have a struct EventDate and am trying to update a reference in Firebase.
struct EventDate {
var club: String = ""
var date: String = ""
var eventText: String = ""
var free: String = ""
var monthYear: String = ""
}
My update function throws lldb. I guess because the keys are no Strings(?)
func updateEvent(_ backendlessUserObjectID: String, event: EventDate) {
let reference = firebase.child("eventDates").child(backendlessUserObjectID).child(event.date)
reference.setValue(event) { (error, ref) -> Void in
if error != nil {
print("\(error)")
}
} // lldb here
}
If I change the function to the following, everything is fine (because Keys and Values are now Strings?)
func updateEvent(_ backendlessUserObjectID: String, event: EventDate) {
let item: NSMutableDictionary = ["club" : event.club,
"date" : event.date,
"eventText" : event.eventText,
"free" : event.free,
"monthYear" : event.monthYear]
let reference = firebase.child("eventDates").child(backendlessUserObjectID).child(event.date)
reference.setValue(item) { (error, ref) -> Void in
if error != nil {
print("\(error)")
}
}
}
Am I right that I receive lldb because the keys from my models are not Strings? Or what am I missing and how will I be able to save the values into my Firebase using my model without creating the NSMutableDictionary? Help is very appreciated.
PS: print(event.date) = 201610120200000000 -> the desired value for .child
Firebase data exists in a JSON format which can be thought of as key:value pairs. The keys must be strings and the values can be any of the for data types mentioned in Dravidians answer (which is a correct answer and should be accepted). I would like to add some additional comments that may help as well.
There are times when you want to use a structure in code and that can't be written to Firebase directly - you need some way to get the data out of the structure into something Firebase likes - which is a Dictionary.
Heres an example (Swift 3, Firebase 2.x)
struct EventDate {
var club: String = ""
var date: String = ""
var eventText: String = ""
var free: String = ""
var monthYear: String = ""
func getDict() -> [String:String] {
let dict = ["club": self.club,
"date": self.date,
"eventText": self.eventText,
"free": self.free,
"monthYear": self.monthYear
]
return dict
}
}
var event = EventDate()
event.club = "Wimbledon"
event.date = "20161023"
event.eventText = "Special Tennis Event"
event.free = "Free"
event.monthYear = "10/2016"
let ref = self.myRootRef.child(byAppendingPath: "events")!
let eventRef = ref.childByAutoId() //Firebase 2.x
eventRef?.setValue( event.getDict() )
This results in a node being written to Firebase that looks like this
"events" : {
"-KUli8oiM_KKw8GZ0MMm" : {
"club" : "Wimbeldon",
"date" : "20161023",
"eventText" : "Special Tennis Event",
"free" : "Free",
"monthYear" : "10/2016"
}
}
No it has nothing to do with the type of keys that you are trying to save in your Firebase Database its just that struct is a dataModel or to be precise a physically grouped list of variables which you initialise with some custom Data, and you can only save four types of values types in your Firebase Database:-
NSDictionary
NSArray
NSNumber
NSString
Look up the docs :- Read And Write data, Firebase- iOS
So when you cast your values in a NSMutableDictionary, you come clean of struct. And struct and class is not recognisable by the Firebase Database.

How to sort 1 array in Swift / Xcode and reorder multiple other arrays by the same keys changes

Sorry for the complex wording of the question. My main experience is with PHP and it has a command called array_multisort. The syntax is below:
bool array_multisort ( array &$array1 [, mixed $array1_sort_order = SORT_ASC [, mixed $array1_sort_flags = SORT_REGULAR [, mixed $... ]]] )
It lets you sort 1 array and the reorder multiple other arrays based on the key changes in the original.
Is there an equivalent command in Swift / Xcode 7.2?
I have currently have a set of arrays:
FirstName
Age
City
Country
Active
Active is an array of time in seconds that a user has been active within my app. I would like to order that descending or ascending and the other arrays to change to remain consistent.
You could create an array of indexes in sorted order and use it as a mapping:
var names = [ "Paul", "John", "David" ]
var ages = [ 35, 42, 27 ]
let newOrder = names.enumerate().sort({$0.1<$1.1}).map({$0.0})
names = newOrder.map({names[$0]})
ages = newOrder.map({ages[$0]})
[EDIT] Here's an improvement on the technique :
It's the same approach but does the sorting and assignment in one step.
(can be reassigned to original arrays or to separate ones)
(firstNames,ages,cities,countries,actives) =
{(
$0.map{firstNames[$0]},
$0.map{ages[$0]},
$0.map{cities[$0]},
$0.map{countries[$0]},
$0.map{actives[$0]}
)}
(firstNames.enumerated().sorted{$0.1<$1.1}.map{$0.0})
[EDIT2] and an Array extension to make it even easier to use if you are sorting in place:
extension Array where Element:Comparable
{
func ordering(by order:(Element,Element)->Bool) -> [Int]
{ return self.enumerated().sorted{order($0.1,$1.1)}.map{$0.0} }
}
extension Array
{
func reorder<T>(_ otherArray:inout [T]) -> [Element]
{
otherArray = self.map{otherArray[$0 as! Int]}
return self
}
}
firstNames.ordering(by: <)
.reorder(&firstNames)
.reorder(&ages)
.reorder(&cities)
.reorder(&countries)
.reorder(&actives)
combining the previous two:
extension Array
{
func reordered<T>(_ otherArray:[T]) -> [T]
{
return self.map{otherArray[$0 as! Int]}
}
}
(firstNames,ages,cities,countries,actives) =
{(
$0.reordered(firstNames),
$0.reordered(ages),
$0.reordered(cities),
$0.reordered(countries),
$0.reordered(actives)
)}
(firstNames.ordering(by:<))
I would go with #AntonBronnikov suggestion, and put all your properties into an struct, making an Array of that particular struct and then sorting it.
This data is clearly related and it's a cleaner approach.
Edit this is valid for 2 arrays:
Adding to #AlainT answer, but using zip:
var names = [ "Paul", "John", "David" ]
var ages = [ 35, 42, 27 ]
let sortedTuple = zip(names, ages).sort { $0.0.0 < $0.1.0 }
Something more generic:
names.enumerate().sort({$0.1<$1.1}).map({ (name: $0.1, age: ages[$0.0]) })
I believe AlainT:s solution is to prefer, but to extend the variety of options, below follows a solution mimicking what a zip5 method could let us achive (in case we could use zip for zipping together 5 sequences instead of its limit of 2):
/* example arrays */
var firstName: [String] = ["David", "Paul", "Lisa"]
var age: [Int] = [17, 27, 22]
var city: [String] = ["London", "Rome", "New York"]
var country: [String] = ["England", "Italy", "USA"]
var active: [Int] = [906, 299, 5060]
/* create an array of 5-tuples to hold the members of the arrays above.
This is an approach somewhat mimicking a 5-tuple zip version. */
var quinTupleArr : [(String, Int, String, String, Int)] = []
for i in 0..<firstName.count {
quinTupleArr.append((firstName[i], age[i], city[i], country[i], active[i]))
}
/* sort w.r.t. 'active' tuple member */
quinTupleArr.sort { $0.4 < $1.4 }
/* map back to original arrays */
firstName = quinTupleArr.map {$0.0}
age = quinTupleArr.map {$0.1}
city = quinTupleArr.map {$0.2}
country = quinTupleArr.map {$0.3}
active = quinTupleArr.map {$0.4}

return random dictionary items in swift

I'm trying to return a random name and a random email from this function have got so far but I'm wondering what should I be returning here obviously as I want to return a tuple it needs to be 2 string values which I need randomly from my function
func randomAuthor () -> (name : String, email : String) {
struct Author {
var name : String
var email : String
}
let firstAuthor = Author(name: "jon", email: "jonsEmail")
let secondAuthor = Author(name: "richard", email: "richardsEmail")
let thirdAuthor = Author(name: "steve", email: "stevesEmail")
let fourthAuthor = Author(name: "simon", email: "simonsEmail")
let fifthAtouh = Author(name: "wes", email: "wesEmail")
var dictionary = [firstAuthor.name : firstAuthor.email, secondAuthor.name : secondAuthor.email, thirdAuthor.name : thirdAuthor.email, fourthAuthor.name : fourthAuthor.email, fifthAuthor.name : fithAtouh.email]
var unsignedDictionaryCount = UInt32(dictionary.count)
var unsignedRandom = arc4random_uniform(unsignedDictionaryCount)
var random = unsignedRandom
return()
}
any help appreciated
thanks
Random value from an Dictionary in several steps:
Create your Dictionary
Get a random Int using arc4random_uniform
Used this random Int to get a random key (using keys), and get its value
Return them, and you are done !
var dictionary : [String:String] = [firstAuthor.name : firstAuthor.email, secondAuthor.name : secondAuthor.email, thirdAuthor.name : thirdAuthor.email, fourthAuthor.name : fourthAuthor.email]
let index: Int = Int(arc4random_uniform(UInt32(dictionary.count)))
let value = Array(dictionary.values)[index]
let key = Array(dictionary.keys)[index]
let value = dictionary[key]
return (key, value!)
Use your random integer as an index into dictionary.keys. This will fetch you the name that you can use to look up your email.

Resources