show image in imageview from string in swift 4 without url - get

I have a project in swift 4. I need to get an image from the api but I get error as "Cannot assign value of type 'String' to type 'UIImage?'".The codes of my project is:
import UIKit
import Alamofire
import SwiftyJSON
class ViewController: UIViewController {
#IBOutlet weak var coachProfile: UIImageView!
var responseArr = [JSON]()
override func viewDidLoad() {
super.viewDidLoad()
getCoachList()
}
func getCoachList() {
let url = "http://test.ilovecoach.com/api/student"
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let loader = appDelegate.showLoading()
WebServices.sharedInstance.get(toURL: url, successHandler: { (jsonData) in
print("messLists: \(jsonData)")
self.responseArr = jsonData.arrayValue
loader.removeFromSuperview()
let avatar = self.responseArr[0]["photo"].stringValue
print("CoachAvatar",avatar) // gives: 12.png
self.coachProfile.image = avatar //gives error as:Cannot assign value of type 'String' to type 'UIImage?'
}) { (error) in
}
}
}
I have an get method api which gives response as :
[
{
"name" : "Modi",
"title" : "d'Etat",
"id" : 12,
"photo" : "12.png"
}
]
Now, I need to get image named "photo" to coachprofile imageview. How can I solve this in swift 4?

Use this :
self.coachProfile.image = UIImage(named: avatar)

Related

Trying to incorporate sound within a beacon region in Swift

I am getting "Use of unresolved identifier 'player' in my code using beacons and regions. For this particular region, I also want it to play a sound (Siren.wav). Code is below:
import Combine
import CoreLocation
import SwiftUI
import AVFoundation
class BeaconDetector: NSObject, ObservableObject, CLLocationManagerDelegate {
var objectWillChange = ObservableObjectPublisher()
var locationManager: CLLocationManager?
var lastDistance = CLProximity.unknown
var player: AVAudioPlayer?
// var audioPlayer = AVAudioPlayer()
override init() {
super.init()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
if CLLocationManager.isRangingAvailable() {
startScanning()
}
}
}
}
func startScanning() {
let uuid = UUID(uuidString: "00000000-0000-0000-0000-000000000000")!
let constraint = CLBeaconIdentityConstraint(uuid: uuid)
let beaconRegion = CLBeaconRegion(beaconIdentityConstraint: constraint, identifier: "MyBeacon")
locationManager?.startMonitoring(for: beaconRegion)
locationManager?.startRangingBeacons(satisfying: constraint)
}
func locationManager(_ manager: CLLocationManager, didRange beacons: [CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) {
if let beacon = beacons.first {
update(distance: beacon.proximity)
} else {
update(distance: .unknown)
}
}
func update(distance: CLProximity) {
lastDistance = distance
self.objectWillChange.send()
}
}
struct BigText: ViewModifier {
func body(content: Content) -> some View {
content
.font(Font.system(size: 72, design: .rounded))
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
}
struct ContentView: View {
#ObservedObject var detector = BeaconDetector()
var body: some View {
if detector.lastDistance == .immediate {
return Text("DANGER TOO CLOSE")
.modifier(BigText())
.background(Color.red)
.edgesIgnoringSafeArea(.all)
func playSound() {
guard let url = Bundle.main.url(forResource: "Siren", withExtension: "wav") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
guard let player = player else { return }
player.play()
}
catch let error {
print(error.localizedDescription)
The reason you get an "unresolved identifier" error is because the variable player is not defined in the playSound() method. In the Swift language, each variable declaration has a specific "scope" and they cannot be accessed outside that scope.
In this case, player is defined as a member variable in the BeaconDetector class. Because the playSound() method is not in the same variable "scope", you get that error when you try to access the variable.
You might want to read this tutorial on how variable scope works in Swift.

Make class in swift3 with AVplayer

this is the code :
import Foundation
import UIKit
import AVFoundation
class MP3PLAYER {
var player = AVPlayer()
func PLAY (){
player.play()
}
init ( url_ : String , autoplay_ : String , player_ : AVPlayer) {
player = player_
let url = url_
let playerItem = AVPlayerItem( url:URL( string:url )! )
player = AVPlayer(playerItem:playerItem)
player.rate = 1.0;
if autoplay_ == "YES" {
player.play()
print("autoplay is on")
}
}
}
In this code there is no error even warning.
Simply player wont play . If i put code direct in viewController than player working ...
I use class on this way in viewController:
<code>
import UIKit
import AVFoundation
class Mp3Stream_example: UIViewController {
var player = AVPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let STREAM1 = MP3PLAYER(url_: "http://listen.181fm.com:181-soul_128k.mp3" , autoplay_: "YES" , player_ : player )
STREAM1.player.play()
//player.play()
.....
</code>
Your player, STREAM1, is going out of scope and is being deallocated, hence no sound. Make it a class member variable instead of a local variable. e.g.
class Mp3Stream_example: UIViewController {
let STREAM1 = MP3PLAYER(url_: "http://listen.181fm.com:181-soul_128k.mp3" , autoplay_: "YES" , player_ : AVPlayer() )
....
P.S. you've got extra AVPlayers that you don't need.

SWIFT2 : EXC_BAD_ACCESS down casting a class conforming to ErrorType

I have a simple Object hierarchy : RESTError with 2 attributes (httpCode and message), and 4 subclasses of it. One of the subclasses, RESTBusinessError has two additional fields.
I've simplified my code here below, but a RESTError variable (which is actually a RESTBusinessError) is used within a switch statement. Whenever I try to access the fields of the subclass, I've a EXC_BAD_ACCESS. Any idea ? this looks obvious, and in the debug area, I can see that all my variables have the expected values.
I have this issue ONLY in case RESTError conforms to the protocol ErrorType.
Any Idea ?
var tmpError:RESTError;
tmpError=RESTBusinessError(httpCode: 422, message: "error", businessCode: "003", businessMessage: "error");
switch tmpError {
case is RESTAuthorisationError:print("AUTH Error");
case let bError as RESTBusinessError:
let s1=bError.httpCode;
let s2=bError.message;
let s3=bError.businessCode; // <- This systematically fails.
let s4=bError.businessMessage;
print("OK \(s1) \(s2) \(s3) \(s4)");
default: print("default");
}
Object Hierarchy is here below :
public class RESTError : ErrorType{
var httpCode:Int
var message:String
init(httpCode:Int,message:String) {
self.httpCode=httpCode;
self.message=message;
}
}
class RESTAuthorisationError : RESTError {}
class RESTServerError : RESTError {}
class RESTOtherError : RESTError {}
public class RESTBusinessError : RESTError {
var businessCode:String
var businessMessage:String
init(httpCode:Int,message:String, businessCode:String, businessMessage:String) {
self.businessCode=businessCode;
self.businessMessage=businessMessage;
super.init(httpCode: httpCode, message: message);
}
}
check this example
import Foundation
func f() {
let queue = dispatch_queue_create("a", DISPATCH_QUEUE_CONCURRENT)
var i: Int! = 0
dispatch_async(queue) {
i = nil
}
usleep(200000)
print(i) // this is wrong
}
f() // debugger will stop here !!!!

Store Integers in Core Data using Swift and XCode

While Strings appears to be fine I'm having some trouble storing Integers into Core Data. Following tutorials and reading available information out there doesn't seem to be helping me who has no Objective-C background. (Swift seemed like a straight forward language like the languages I'm fluent with PHP/OOPHP/JavaScript/VBScript/... thus I started playing with it and so far have been able to do everything I wanted, almost)
What I want to do now is, to receive the JSON data and store it into Core Data
Here's my Core Data
Entity name: Category
Its Attributes:
id Int16
title String
description String
My Swift model? file: Category.swift
import CoreData
class Category: NSManagedObject {
#NSManaged var id: Int //should I declare this as Int16?
#NSManaged var title: String
#NSManaged var description: String
}
I'm using SwiftyJASON extension? and NSURLSession protocol? to get the data and to parse it as follow:
import UIKit
import CoreData
class ViewController: UIViewController {
let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func fetchData() {
var url = NSURL.URLWithString("http://domain.com/index.php?r=appsync/read&id=category")
var session = NSURLSession.sharedSession()
session.dataTaskWithURL(url, completionHandler: {(data, response, error) in
// parse data into json
let json = JSONValue(data)
let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: self.managedObjectContext)
let category = Category(entity: entityDescription, insertIntoManagedObjectContext: self.managedObjectContext)
for item in json.array! {
category.id = item["id"].string!.toInt()! //goes KABOOM!
category.title = item["title"].string!
category.description = item["description"].string!
managedObjectContext?.save(nil)
}
dispatch_async(dispatch_get_main_queue()) {
// do something
}
}).resume()
}
}
Let's assume the JASON data is:
[{"id":"1","title":"cat1","description":"blabala one"},{"id":"2","title":"cat2","description":"blabala two"}]
At line where it says category.id = item["id"].string!.toInt()! xCode goes KABOOM, what am I doing wrong here?
Notes/More questions:
I tried changing id type within Core Data to Int32 and then declaring it as just Int
in the model (and not Int16 or Int32) which reduced some errors but
xCode still crashes
Probably the way I'm looping stuff is not the best way to do this,
what's the better way of storing array of data into core data at
once?
Most of the tutorials I've seen there's no id's for Entities(tables), am I missing something here?
References:
SiftyJSON: https://github.com/lingoer/SwiftyJSON
Core Data tutorial:
http://rshankar.com/coredata-tutoiral-in-swift-using-nsfetchedresultcontroller/
EDIT > Working code:
Category.swift model file which can be auto generated using File>New>File>iOS>Core Data>NSManagedObject subclass [swift, no need for bridging header but you need to manually add #objc line as below]
import CoreData
#objc(Category) //Wouldn't work without this
class Category: NSManagedObject {
#NSManaged var id: NSNumber //has to be NSNumber
#NSManaged var title: String
#NSManaged var mydescription: String //"description" is reserved so is "class"
}
ViewController.swift
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func fetchData() {
var url = NSURL.URLWithString("http://domain.com/index.php?r=appsync/read&id=category")
var session = NSURLSession.sharedSession()
session.dataTaskWithURL(url, completionHandler: {(data, response, error) in
let json = JSONValue(data)
let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext //this line had to be moved here
let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: managedObjectContext)
for item in json.array! {
let category = Category(entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext) //this line has to be in inside for loop
category.id = item["id"].string!.toInt()!
category.title = item["title"].string!
category.mydescription = item["description"].string!
managedObjectContext?.save(nil)
}
dispatch_async(dispatch_get_main_queue()) {
// do something
}
}).resume()
}
}
Sample fetching data code:
func requestData() {
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Category")
request.returnsObjectsAsFaults = false
var results:NSArray = context.executeFetchRequest(request, error: nil)
//println(results)
for category in results {
var cat = category as Category
println("\(cat.id),\(cat.title),\(cat.mydescription)")
}
}
P.S. Make sure to Clean your project and delete the app from simulator after changing Model
Scalar types (integers, floats, booleans) in core data are broken in the current Swift beta (5). Use NSNumber for the properties, and file a radar.
object.intProperty = NSNumber(int:Int(item["id"] as String))
(Typed on the phone, so sorry if that's wrong, and I know it's disgusting code - hence, file a radar!)
Or, in your specific case, looking at the JSON, use String. Those IDs are coming in as strings anyway.
Updated for Swift 2
If your JSON data is really of type [[String:String]], you can use the following code in order to set category.id:
if let unwrappedString = item["id"], unwrappedInt = Int(unwrappedString) {
category.id = unwrappedInt
}

Core Data in Swift

Trying to work with Core Data in Swift. Found this one example:
http://www.sep.com/sep-blog/2014/06/23/a-c-developer-learns-swift-part-1-core-data/
Created Entity "Person" with two string fields - lastname and firstname. Created UITableViewController (MainTableViewController) to display records on the screen. Created UIViewController (DetailViewController) to add new records. Created my own class (AddrBook) for entity data.
Does not work display the records contained in the entity in main class - MainTableViewController.
My class AddrBook.swift:
import UIKit
import CoreData
#objc(AddrBook)
class AddrBook: NSManagedObject {
#NSManaged var lastname:String
#NSManaged var firstname:String
}
UIViewController to add new records. DetailViewController.swift:
import UIKit
import CoreData
class DetailViewController: UIViewController {
#IBOutlet var lastNameField : UITextField = nil
#IBOutlet var firstNameField : UITextField = nil
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func saveButtonPressed(sender : AnyObject) {
let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
let context:NSManagedObjectContext = appDelegate.managedObjectContext
let projectEntity = NSEntityDescription.entityForName("Person", inManagedObjectContext: context)
var newPerson = AddrBook(entity: projectEntity, insertIntoManagedObjectContext: context)
newPerson.lastname = lastNameField.text
newPerson.firstname = firstNameField.text
context.save(nil)
self.dismissViewControllerAnimated(true, completion: nil)
}
}
Theoretically, in this class all goes well. Entry must be added.
The main class MainTableViewController.swift. To display the records. Trying to get them through the NSLog:
import UIKit
import CoreData
class MainTableViewController: UITableViewController {
init(style: UITableViewStyle) {
super.init(style: style)
}
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
let request = NSFetchRequest(entityName: "Person")
request.returnsObjectsAsFaults = false
let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
let context:NSManagedObjectContext = appDelegate.managedObjectContext
var results:NSArray = context.executeFetchRequest(request, error: nil)
for currentPerson in results as AddrBook[] {
NSLog("\(currentPerson.lastname)")
NSLog("\(currentPerson.firstname)")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
return 1
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
return 0
}
}
Shows that there is an error in the expression
for currentPerson in results as AddrBook[] {
Error:
Cannot convert the expression's type 'AddrBook[]' to type 'AddrBook[]'
What am I doing wrong?
for LombaX:
override func viewDidLoad() {
super.viewDidLoad()
let request = NSFetchRequest(entityName: "Person")
request.returnsObjectsAsFaults = false
let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
let context:NSManagedObjectContext = appDelegate.managedObjectContext
var results : AddrBook[]? = context.executeFetchRequest(request, error: nil) as? AddrBook[]
NSLog("\(results)")
if let array = results // check for nil and unwrap
{
for currentPerson in array as AddrBook[] {
NSLog("\(currentPerson.lastname)")
NSLog("\(currentPerson.firstname)")
}
}
// var results:NSArray = context.executeFetchRequest(request, error: nil)
/*for currentPerson in results as AddrBook[] {
NSLog("\(currentPerson.lastname)")
NSLog("\(currentPerson.firstname)")
}*/
}
Output NSLog - 2014-06-24 21:25:41.243 lesson-12-swift[1651:136375] nil
Variable results is nil :-(
Link to project in Dropbox: https://www.dropbox.com/s/q42rw5fw470timi/lesson-12-swift.zip
First, check that you filled the class in the data model:
As ProjectName.AddrBook (for swift classes you have to specify even the project name). (NOTE: this is needed only if you haven't used the prefix #objc(AddrBook) before the class, but I see that you used it, so this is not the problem).
or
as AddrBook as in this image in the Class section, top right
Moreover, change your cast like these:
// since executeFetchRequest can return nil, cast it as an optional array of [AddrBook]
// note: the first [AddrBook]? Can be omitted
var results : [AddrBook]? = context.executeFetchRequest(request, error: nil) as? [AddrBook]
if let array = results // check for nil and unwrap
{
for currentPerson in array as [AddrBook] {
// print
}
}
Or, less explicit and no check for nil
var results = context.executeFetchRequest(request, error: nil)
for currentPerson in results as [AddrBook] {
// print
}
let arrayresult = context!.executeFetchRequest(request, error: &error)
var arrayvalues=NSArray(array: arrayresult!)
for obj in arrayvalues as [AddrBook]
{
}

Resources