How to get the year metadata of AVAsset URL in Swift? - swift

I tried the below method on an AVAsset URL and all I am getting is nil. Is there anything wrong in my code?
func getYear(musicName: String) -> Date? {
let url = FileManager.customFolderURL.appendingPathComponent(musicName)
let playerItem = AVPlayerItem(url: url)
let metadataList = playerItem.asset.metadata
var date: Date?
for item in metadataList {
switch item.commonKey {
case .commonKeyCreationDate?:
date = item.dateValue
default: break
}
}
return date
}

func getYear(musicName: String) -> Date? {
let url = FileManager.customFolderURL.appendingPathComponent(musicName)
var date: Date?
let asset = AVAsset(url: url)
let metaData = asset.metadata
if let artist = metaData.first(where: {$0.commonKey == .commonKeyCreationDate}), let value = artist.dateValue {
print(value)
date = value
}
return date
}
This Code will work if your file contains value for property .commonKeyCreationData. I didn't have appropriate file for testing. But it was returning value for property .commonKeyArtist and if we would just replace artist.dateValue to artist.stringValue.

Related

firebase firestore date time sptamp returns nil swift

I created a func that reads from firebase
When I print date is always nil and I locked at firebase in my browser and the date exists. so please can some body help me?
func fetchEventData(group:groupeViewModel) {
print("featchingEventData")
if user != nil {
db.collection("events").whereField("group_id", isEqualTo: group.id).addSnapshotListener({(snapshot, err) in
guard let documents = snapshot?.documents else {
print("no docs returned")
return
}
var cont = -1
self.groupes[group.cont].envents = documents.map({docSnapshot -> eventViewModel in
cont += 1
let data = docSnapshot.data()
let docId = docSnapshot.documentID
let name = data["name"] as? String
let des = data["des"] as? String
let res = data["reservation"] as! Int
let cost = data["reservation"] as! Float
let isDate = data["isDate"] as! Bool
var date = data["date"] as? Date
let link = data["link"] as? String
let textColor = data["TextColor"] as! Bool
var res_users = data["res_users"] as? [String]
if res_users == nil{
res_users = [""]
}
if date == nil{
date = Date(timeIntervalSince1970: 135670000)
}
print("date \(date)")
print("update")
return eventViewModel(id: docId, name: name!, description: des!, TextColor: textColor, reservation: res, reserved_user:res_users!, cost: cost, isDate: isDate, date: date!, link: link!, cont: cont)
})
print("events \(self.events)")
})
}
}
You have to toggle between Swift's Date object and Firestore's Timestamp object. Note that Firestore uses tokens to represent timestamps which is not as straightforward as using primitive types like integers or strings. Therefore, if you see unexpected behavior with these timestamps such as nil where there should be value or values that aren't exactly equal but "close enough", it's likely a side effect of this token system.
Read
if let timestamp = data["date"] as? Timestamp {
let date = timestamp.dateValue()
}
Write
let now = Date()
let timestanmp = Timestamp(date: now)

Swift - Why is my JSON object element only adding the last array element?

I have a problem with my JSON object. Everything is working fine creating and printing out my JSON object, apart from the idQty part. It only prints the last key value result. I assume I have a problem with my for loop. If anybody can point out where I've went wrong, it would be of huge help.
Code below:
struct Order: Codable {
let idQty: [IdQty]
let collection: String
let name: String
let phone: Int
let doorNum: Int
let street: String
let postcode: String
}
struct IdQty: Codable {
let itemId: Int
let qty: Int
}
class CheckoutServer: NSObject, URLSessionDataDelegate {
var inputVals = [Int:Int]()
var idQty = [IdQty]()
var collection = String()
var name = String()
var phone = Int()
var doorNum = Int()
var street = String()
var postcode = String()
var request = URLRequest(url: NSURL(string: "http://192.168.1.100/api/AddOrder.php")! as URL)
func downloadItems() {
for(key,value) in inputVals {
idQty = [IdQty(itemId: key,qty: value)]
}
let order = Order(idQty: idQty,collection: collection,name: name,phone: phone,doorNum: doorNum,street: street,postcode: postcode)
let encodedOrder = try? JSONEncoder().encode(order)
var json: Any?
request.httpMethod = "POST"
if let data = encodedOrder {
json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
if let json = json {
}
}
let postParameters = "json="+String(describing: json!)
request.httpBody = postParameters.data(using: .utf8)
print(String(describing: json!))
let defaultSession = URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: request) { (data, response, error) in
if error != nil {
print("Failed to upload data at Menu Type Items")
} else {
print("Data uploaded")
}
}
task.resume()
}
}
Below is the output. the 'idQty' part only ever returns the last entry in the [Int:Int] dictionary:
{
collection = Delivery;
doorNum = 4;
idQty = (
{
itemId = 14;
qty = 2;
}
);
name = James;
phone = 4355345;
postcode = Test;
street = TestStreet;
}
You should append new value to your array instead of recreating it on each iteration
for(key,value) in inputVals
{
idQty.append(IdQty(itemId: key,qty: value))
}

how to use random string to let or var to url link

how to use random string to let or var to url link
i want to make random string for url
let url = URL(string:"https://www.pallive.net/random.json")
or see the code when i change values in the site linke in the app do not changed,but if i chnage name of url it change
the code not reload if i change the value in json and keep same file
if i want to reload i have to change the name of file how to do some thange
auotmatic change the url and keep the orginal in the ftp server
import Foundation
class Episode
{
var title: String?
var description: String?
var thumbnailURL: URL?
var url: URL?
var episodes = [Episode]()
init(title: String, description: String, thumbnailURL: URL, createdAt: String, author: String)
{
self.title = title
self.description = description
self.thumbnailURL = thumbnailURL
}
init(espDictionary: [String : AnyObject])
{
self.title = espDictionary["title"] as? String
// description = espDictionary["description"] as? String
thumbnailURL = URL(string: espDictionary["thumbnailURL"] as! String)
self.url = URL(string: espDictionary["link"] as! String)
}
static func downloadAllEpisodes(completion: #escaping ([Episode]) -> ()) {
var episodes = [Episode]()
let url = URL(string:"https://www.pallive.net/random.json")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print(error)
completion(episodes)
}
else {
if let jsonData = data ,let jsonDictionary = NetworkService.parseJSONFromData(jsonData) {
let espDictionaries = jsonDictionary["episodes"] as! [[String : AnyObject]]
for espDictionary in espDictionaries {
let newEpisode = Episode(espDictionary: espDictionary)
episodes.append(newEpisode)
}
}
completion(episodes)
DispatchQueue.main.async(execute: {
completion(episodes)
})
}
}.resume()
}
func randomString(_ length: Int) -> String {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = UInt32(letters.length)
var randomString = ""
for _ in 0 ..< length {
let rand = arc4random_uniform(len)
var nextChar = letters.character(at: Int(rand))
randomString += NSString(characters: &nextChar, length: 1) as String
}
return randomString
}
}

Cannot convert value of type 'String?!' to expected argument type 'Notifications'

I am trying to check the id of a record before I put it into the array, using xcode swift
here is the code. But, i get the following error
Notifications.swift:50:46: Cannot convert value of type 'String?!' to expected argument type 'Notifications'
on this line
*if (readRecordCoreData(result["MessageID"])==false)*
Please can some one help to explain this error
import CoreData
struct Notifications{
var NotifyID = [NSManagedObject]()
let MessageDesc: String
let Messageid: String
init(MessageDesc: String, Messageid:String) {
self.MessageDesc = MessageDesc
self.Messageid = Messageid
// self.MessageDate = MessageDate
}
static func MessagesWithJSON(results: NSArray) -> [Notifications] {
// Create an empty array of Albums to append to from this list
var Notification = [Notifications]()
// Store the results in our table data array
if results.count>0 {
for result in results {
//get fields from json
let Messageid = result["MessageID"] as! String
let MessageDesc = result["MessageDesc"] as? String
let newMessages = Notifications(MessageDesc: MessageDesc!, Messageid:Messageid)
//check with id's from core data
if (readRecordCoreData(result["MessageID"])==false)
{
Notification.append(newMessages)
}
}
}
return Notification
}
//check id
func readRecordCoreData(Jsonid: String) -> Bool {
var idStaus = false
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let fetchRequest = NSFetchRequest(entityName: "ItemLog")
//3
do {
let resultsCD = try! managedContext.executeFetchRequest(fetchRequest)
if (resultsCD.count > 0) {
for i in 0 ..< resultsCD.count {
let match = resultsCD[i] as! NSManagedObject
let id = match.valueForKey("notificationID") as! String
if (Jsonid as String! == id)
{
idStaus = true
}
else{
idStaus = false
}
}
}
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
return idStaus
}
One of your methods is static and the other one is not :
func readRecordCoreData(Jsonid: String) -> Bool
static func MessagesWithJSON(results: NSArray) -> [Notifications]
Depending on what you want to accomplish you could declare both static, none, or replace
//check with id's from core data
if (readRecordCoreData(result["MessageID"])==false)
{
Notification.append(newMessages)
}
By
//check with id's from core data
if (Notifications.readRecordCoreData(Messageid)==false)
{
Notification.append(newMessages)
}
Not sure if the code will work past compilation however as there are many readability issues

Definition of Global Variable Resetting

I have a class designed to take the temperature data from an API for a specific date and add it to a dictionary. The URL for the API is stored in a global variable called baseURL. It is defined at the beginning as an empty string, but is later changed. My class is below:
import UIKit
import Foundation
typealias ServiceResponse = (JSON, NSError?) -> Void
class WeatherManager: NSObject {
var baseURL: String = ""
var data: String = ""
static let sharedInstance = WeatherManager()
func getRandomUser(onCompletion: (JSON) -> Void) {
println("Starting getRandomUser")
let route = self.baseURL
println(self.baseURL)
makeHTTPGetRequest(route, onCompletion: { json, err in
onCompletion(json as JSON)
})
}
func makeHTTPGetRequest(path: String, onCompletion: ServiceResponse) {
let request = NSMutableURLRequest(URL: NSURL(string: path)!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
let json:JSON = JSON(data: data)
onCompletion(json, error)
if error != nil {
println("No Error")
} else {
println("Error")
}
})
task.resume()
}
func addData() {
WeatherManager.sharedInstance.getRandomUser { json in
var jsonData = json["response"]["version"]
self.data = "\(jsonData)"
dispatch_async(dispatch_get_main_queue(),{
let alert = UIAlertView()
alert.title = "Weather Data Update"
if self.data != "null" {
println("Value:\(self.data)")
alert.message = "The weather data was updated successfully."
alert.addButtonWithTitle("OK")
alert.show()
} else {
println("Error Reading Data")
println(self.data)
alert.message = "HealthTrendFinder encountered an error while updating data."
alert.addButtonWithTitle("OK")
alert.show()
}
})
}
}
func updateWeatherHistory() {
println(self.baseURL)
let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
println("Weather Updating...")
// This sets the start date to midnight of the current date if no start date has been set.
if StorageManager.getValue(StorageManager.StorageKeys.WeatherStartDate) == nil {
let startDate: NSDate = calendar.startOfDayForDate(NSDate())
StorageManager.setValue(startDate, forKey: StorageManager.StorageKeys.WeatherStartDate)
}
// This adds a data array if it hasn't been created yet.
if StorageManager.getValue(StorageManager.StorageKeys.WeatherData) == nil {
StorageManager.setValue([:], forKey: StorageManager.StorageKeys.WeatherData)
}
var weatherData: [NSDate: NSObject] = StorageManager.getValue(StorageManager.StorageKeys.WeatherData)! as! [NSDate : NSObject]
let startMidnight: NSDate = StorageManager.getValue(StorageManager.StorageKeys.WeatherStartDate) as! NSDate
let currentMidnight: NSDate = calendar.startOfDayForDate(NSDate())
let daysFromStartDate: Int = calendar.components(NSCalendarUnit.CalendarUnitDay, fromDate: startMidnight, toDate: currentMidnight, options: nil).day
println("Starting Loop")
for i: Int in 0..<daysFromStartDate {
let dateToBeExamined: NSDate = calendar.dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: i, toDate: startMidnight, options: nil)!
if weatherData[dateToBeExamined] == nil {
let calendarUnits: NSCalendarUnit = .CalendarUnitDay | .CalendarUnitMonth | .CalendarUnitYear
let components = NSCalendar.currentCalendar().components(calendarUnits, fromDate: dateToBeExamined)
var month: String
var day: String
if components.month < 10 {
month = "0\(components.month)"
} else {
month = "\(components.month)"
}
if components.day < 10 {
day = "0\(components.day)"
} else {
day = "\(components.day)"
}
var dateString = "\(components.year)\(month)\(day)"
self.baseURL = "http://api.wunderground.com/api/91e65f0fbb35f122/history_\(dateString)/q/OR/Portland.json"
println(self.baseURL)
var get: () = WeatherManager.sharedInstance.addData()
println(get)
weatherData[dateToBeExamined] = self.data
// There is no data for the NSDate dateForInspection. You need to pull data and add it to the dictionary.
} else {
// Data exists for the specified date, so you don't need to do anything.
}
}
println("Loop has finished or been skipped")
}
}
The problem is, baseURL reverts to an empty string when getRandomUser is executed, after baseURL is set to the URL. Why is this happening, and how do I fix it?
Your code is unnecessarily complex, making it hard to diagnose the problem without more information. But here is a suggestion:
Try making it impossible to instantiate more than one instance of your WeatherManager singleton:
class WeatherManager {
private static let _sharedInstance = WeatherManager()
private init() { super.init() }
static func sharedInstance() -> WeatherManager {
return _sharedInstance
}
}
When you are working from outside WeatherManager, you access it by calling:
let wm = WeatherManager.sharedInstane()
Then, when you are working inside WeatherManager, make sure that all your references are to self - i.e., self.baseURL = ... or self.updateWeatherHistory(), instead of WeatherManager.sharedInstance.baseURL = ..., etc.
Though your code is complicated, I think what is going on is you actually have two instances of WeatherManager in play. You are setting the value of baseURL on one, but not the other. If you want it to be a singleton, you need to make it impossible to create more than one.