How to convert NSData to custom object array in swift - swift

I convert the DrawObj Array (custom object array) to NSData and save it to cache directory use NSFileManager to save
then I use [NSData dataWithContentsOfFile:fileURL options:0 error:&err] to get NSData from filesystem
Now I try to restore the NSData to DrawObj Array ([DrawObjs])
How to do ?
I have try to use
extension Data {
func elements <T> () -> [T] {
return withUnsafeBytes {
Array(UnsafeBufferPointer<T>(start: $0, count: count/MemoryLayout<T>.size))
}
}
}
if let objs:[DrawObj] = self.readFromFile()?.elements() {
self.drawObjs = objs
}
but is crash
update show DrawObj model
class DrawObj{
var id : String!;
var height : CGFloat = 0.0;
var width : CGFloat = 0.0;
var points:[CGPoint] = [];
var oPoints:[CGPoint] = [];
var angle : CGFloat = 0.0;
var scaleX : CGFloat = 1.0;
var oStartPoint:CGPoint = CGPoint.zero
var oEndPoint:CGPoint = CGPoint.zero
var scaleY : CGFloat = 1.0;
var currentHeight : CGFloat = 0.0;
var currentWidth : CGFloat = 0.0;
var radius : CGFloat = 0.0;
var drawPara : DrawParam = DrawParam();
var text : String = "";
var isFlip:Bool = false;
var url:String = "";
var image:UIImage?
var fontSize : CGFloat = 16
var originX:String = "left"
var originY:String = "top"
var pathPoint:[PathPoint] = []
var stokeDashArray:[Int] = []
var beizerPath:UIBezierPath?
var nickName:String = ""
init(id: String ){
self.id = id;
}
init( id:String , drawType:DrawType , fillColor : DrawColor , stokeColor : DrawColor , lineWidth : DrawStokeWidth ) {
self.id = id;
self.drawPara.drawType = drawType
self.drawPara.fillColor = fillColor
self.drawPara.stokeColor = stokeColor
self.drawPara.lineWidth = lineWidth
}
}

Related

How declaring and add data in new object correctly

I have this code:
struct Calculators
{
var calculators: [Calculator]?
var activeCalculator: Int = -1
var activeSummary: Bool = false
var activeProfits: Bool = false
public func getCalculators()-> [Calculator]
{
return calculators!
}
}
struct Calculator
{
var priceSum: Float = 0
var weightSum: Float = 0
var pricePerMix: Float = 0
var pricePerPortion: Decimal?
var portionDivider: Float?
var nettoPortionCost: Float?
var profitPerPortion: Float?
var pricePerKgAfterPrepare: Float?
var weightPerPortionInGrams: Float?
var products : [CountedProduct]?
init() {
createTime = NSDate().timeIntervalSince1970 * 1000
}
}
struct CountedProduct
{
var productCode: String
var productCountable: Bool
var pricePerKg: Decimal?
var weightYieldInPercent: Decimal?
var pieceWeight: Decimal?
}
var countedProduct = CountedProduct(productCode: produkt.code!, productCountable: productCountable, pricePerKg: pricePerKg, weightYieldInPercent: weightYieldInPercent, pieceWeight: pieceWeight)
var activeCalculators = Calculators()
var calculatorToAdd = Calculator()
calculatorToAdd.priceSum = 0
calculatorToAdd.weightSum = 0 //?
calculatorToAdd.pricePerMix = Float(countedProduct.weightAfterPrepareKg as! NSNumber)
calculatorToAdd.pricePerPortion = (countedProduct.costOfTheMixturePerPortion as! NSNumber).decimalValue
calculatorToAdd.portionDivider = 0 //?
calculatorToAdd.nettoPortionCost = Float(countedProduct.costOfTheMixturePerPortion as! NSNumber)
calculatorToAdd.profitPerPortion = Float(countedProduct.overheadOnServing as! NSNumber)
calculatorToAdd.pricePerKgAfterPrepare = Float(countedProduct.pricePerKgAfterPrepare as! NSNumber)
calculatorToAdd.weightPerPortionInGrams = Float(countedProduct.weightAfterPrepareKg as! NSNumber)
calculatorToAdd.products?.append(countedProduct)
calculatorToAdd.products?.append(countedProduct)
I can not change the form of these class.
How to correctly initialize a Calculators object?
I have data in produkt.
Is this code correct?
I would like to create a calculator object and insert it into Calculators.
The class code can not be changed.
I assume you can add to the code at the end
activeCalculators.calculators = []
activeCalculators.calculators.append(calculatorToAdd)

iOS - UI Label Not Updating

I am trying to build a weather app with AlamoFire and i am getting the JSON Response as expected but when i am trying to update the date to UI Label, my variable is returning a nil. if anyone get a chance to let me know where i am going wrong
import UIKit
class WeatherVC: UIViewController {
#IBOutlet weak var dateLbl: UILabel!
#IBOutlet weak var weatherType: UILabel!
#IBOutlet weak var cityname: UILabel!
#IBOutlet weak var currentTemp: UILabel!
var weatherConstants = WeatherConstant()
override func viewDidLoad() {
super.viewDidLoad()
// updateUI()
//
weatherConstants.downloadCurrentWeather {
self.updateUI()
}
weatherConstants = WeatherConstant()
print(Current_Weather_Url)
}
func updateUI() {
weatherType.text = weatherConstants.weatherType
cityname.text = weatherConstants.cityName
print("current city name is \(weatherConstants.weatherType)")
}
}
Weather Constants
import UIKit
import Alamofire
class WeatherConstant {
var _cityName :String!
var _currentTemp : Double!
var _weatherType : String!
var _highTemp : String!
var _date :String!
var cityName :String {
if _cityName == nil {
_cityName = ""
}
return _cityName
}
var currentTemp : Double{
if _currentTemp == nil {
_currentTemp = 0.0
}
return _currentTemp
}
var weatherType : String {
if _weatherType == nil {
_weatherType = ""
}
return _weatherType
}
var highTemp : String {
if _highTemp == nil {
_highTemp = ""
}
return _highTemp
}
var date : String {
if _date == nil {
_date = ""
}
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
let currentDate = dateFormatter.string(from: Date())
self._date = "Today, \(currentDate)"
return _date
}
//func downloadWeatherDetails(completed : DownloadComplete) ===> downloadWeatherDetails(completed : #escaping DownloadComplete)
func downloadCurrentWeather(completed: #escaping DownloadComplete) {
Alamofire.request(Current_Weather_Url).responseJSON{ response in
let result = response.result
// print(result)
debugPrint(result)
if let dict = result.value as? Dictionary<String, AnyObject>{
if let name = dict["name"] as? String {
self._cityName = name
print("current name is \(self._cityName)")
}
if let currentTemp = dict["weather"] as? [Dictionary<String, AnyObject>] {
if let main = currentTemp[0]["main"] as? String{
self._weatherType = main
print("Current Weather Type \(self._weatherType)")
}
}
}
completed()
}
}
}
JSON Response
https://samples.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=e9a34088739f38c517b4a45084f5ed82
SUCCESS: {
base = stations;
clouds = {
all = 0;
};
cod = 200;
coord = {
lat = "35.02";
lon = "139.01";
};
dt = 1485792967;
id = 1907296;
main = {
"grnd_level" = "1013.75";
humidity = 100;
pressure = "1013.75";
"sea_level" = "1023.22";
temp = "285.514";
"temp_max" = "285.514";
"temp_min" = "285.514";
};
name = Tawarano;
sys = {
country = JP;
message = "0.0025";
sunrise = 1485726240;
sunset = 1485763863;
};
weather = (
{
description = "clear sky";
icon = 01n;
id = 800;
main = Clear;
}
);
wind = {
deg = 311;
speed = "5.52";
};
}
Current Weather Type Optional("Clear")----> this the weather type i am trying to provide to UIlabel
current city name is Optional("") ------> Here i am trying to print what data is in UILabel but its returning empty string
2018-08-07 11:18:09.567868-0700 WeatherApp1.1[82321:3248301] [BoringSSL] Function boringssl_session_errorlog: line 2881 [boringssl_session_read] SSL_ERROR_ZERO_RETURN(6): operation failed because the connection was cleanly shut down with a close_notify alert
You're overwriting the weatherConstants value with a new object in viewDidLoad. Try removing that.
(Longer explanation: you're correctly creating a weatherConstants object, and asking it to fetch data. But while that's happening, you create a second instance of that object which overwrites the first. So while the first instance completes the network request and tells your UI to redraw, the UI is getting its data from the second instance of WeatherConstants)

convert struct array to json swift

I have an array of struct's that I need to write to a server side code, I can't seem to find any examples of adding a json object with multiple parent keys.
struct Photo {
var imageName = "", thumbFileURL = "", viewCount = 0, likeCount = 0
}
and then I have a couple of photo object that are declared like...
var photo1 = Photo()
photo1.imageName = "ImPhoto1"
photo1.thumbFileURL = "www.SO.com"
photo1.viewCount = 5
photo1.likeCount = 1
var photo2 = Photo()
photo1.imageName = "ImPhoto2"
photo1.thumbFileURL = "www.SO.com"
photo1.viewCount = 10
photo1.likeCount = 2
////// and then same for x amount of Photo() object
And then I have an array
myArray = [photo1,photo2,photo3, ...]
and then I need to write a json that looks something ike this:
myJson object = {
photo1: {
imageName: "ImPhoto1"
thumbFileURL = "www.SO.com"
viewCount: 5
likeCount: 1
},
photo2: {
imageName: "Imphoto2"
....
},
....
}
so my question is, how do I convert myarray -> myJson
You need a custom implementation of Encodable of PhotoCollection, which is a wrapper type for an array of photos:
struct Photo : Codable {
var imageName = "", thumbFileURL = "", viewCount = 0, likeCount = 0
}
struct PhotoCollection: Encodable, ExpressibleByArrayLiteral {
var photos: [Photo]
typealias ArrayLiteralElement = Photo
init(arrayLiteral elements: Photo...) {
photos = elements
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
for (i, photo) in photos.enumerated() {
try container.encode(photo, forKey: CodingKeys(stringValue: "photo\(i + 1)")!)
}
}
struct CodingKeys: CodingKey, ExpressibleByStringLiteral {
var stringValue: String { return key }
init?(stringValue: String) {
key = stringValue
}
var intValue: Int? { return Int(key) }
init?(intValue: Int) {
key = "\(intValue)"
}
init(stringLiteral value: String) {
key = value
}
var key: String
}
}
var photo1 = Photo()
photo1.imageName = "ImPhoto1"
photo1.thumbFileURL = "www.SO.com"
photo1.viewCount = 5
photo1.likeCount = 1
var photo2 = Photo()
photo1.imageName = "ImPhoto2"
photo1.thumbFileURL = "www.SO.com"
photo1.viewCount = 10
photo1.likeCount = 2
let photoCollection: PhotoCollection = [photo1, photo2]
let json = try JSONEncoder().encode(photoCollection)
print(String(data: json, encoding: .utf8)!)
This prints:
{"photo2":{"imageName":"","likeCount":0,"viewCount":0,"thumbFileURL":""},"photo1":{"imageName":"ImPhoto2","likeCount":2,"viewCount":10,"thumbFileURL":"www.SO.com"}}
Formatted:
{
"photo2": {
"imageName": "",
"likeCount": 0,
"viewCount": 0,
"thumbFileURL": ""
},
"photo1": {
"imageName": "ImPhoto2",
"likeCount": 2,
"viewCount": 10,
"thumbFileURL": "www.SO.com"
}
}
struct Photo:Codable {
var imageName = "", thumbFileURL = "", viewCount = 0, likeCount = 0
}
var photo1 = Photo()
photo1.imageName = "ImPhoto1"
photo1.thumbFileURL = "www.SO.com"
photo1.viewCount = 5
photo1.likeCount = 1
var photo2 = Photo()
photo1.imageName = "ImPhoto2"
photo1.thumbFileURL = "www.SO.com"
photo1.viewCount = 10
photo1.likeCount = 2
var myArray = [photo1,photo2]
let tempData = try? JSONEncoder().encode(myArray)
//Create JSON
var Finaldata: Any?
if let data = tempData { Finaldata = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) }
This Will Work

Populating a generator. Is it possible?

I have a generator that generates a circle(SKShapeNode) every 2 seconds from the y-axis. (Moves up). I would like to know if it is possible to populate this generator uniformly(every x number of points.
Here is my code for said generator:
class CircleGen: SKShapeNode {
var circles = [WhiteCircles]()
var circleTracker = [WhiteCircles]()
var generationTimer: NSTimer!
var circ: WhiteCircles!
func generateCircles() {
for var i = 0; i < 4; i++ {
var scale: CGFloat
let rand = arc4random_uniform(10)
if rand == 0 {
scale = -15.0
} else {
scale = 15.0
}
let circle = WhiteCircles()
circle.position.x = lineGen.position.x
circle.physicsBody?.affectedByGravity = false
circle.position.y = 35
self.circles.append(circle)
circleTracker.append(circle)
foregroundNode.addChild(circle)
}
}
func startGeneratingEvery(seconds: NSTimeInterval) {
let callGenerateAction = SKAction.runBlock { () -> Void in
self.generateCircles()
}
let waitOneSecond = SKAction.waitForDuration(seconds)
let sequenceAction = SKAction.sequence([callGenerateAction, waitOneSecond])
let circleGenerateAction = SKAction.repeatActionForever(sequenceAction)
self.runAction(circleGenerateAction, withKey: "generateCircles")
}
}
Will post more code if necessary. Thank you in advance.

If statements and strings error

I Have
if rockNamesArray == "rock2" {
let firstPos: CGFloat = 300.0
UIView.animateWithDuration(3.0, animations: { () -> Void in
self.mrock.frame = CGRectMake(167, 600, CGFloat(self.mrock.bounds.size.width), CGFloat(self.mrock.bounds.size.height))
})}
as well as
var rockNamesArray:[String ] = ["bird", "rock2", "rock3"]
var rockpos = Int(arc4random_uniform(UInt32(3)))
var firstrockString:String = rockNamesArray[rockpos]
But its telling me I can't use "==" for the if statement. What would I use in place for it. "rock2" is a string
If you want to check if "rock2" is inside the array:
if contains(rockNamesArray, "rock2") {
// Do your stuff
}
Or if you want to check a certain index of the array and compare it to "rock2" with n being the index:
var rockNamesArray:[String ] = ["bird", "rock2", "rock3"]
var rockpos = Int(arc4random_uniform(UInt32(3)))
if rockNamesArray[rockpos] == "rock2" {
let firstPos: CGFloat = 300.0
UIView.animateWithDuration(3.0) {
self.mrock.frame = CGRectMake(167, 600, CGFloat(self.mrock.bounds.size.width), CGFloat(self.mrock.bounds.size.height))
}
}