How to show Images imported by JSON data - swiftui

I'm trying to get images to show from a url using json. I can retrieve the url but I do not know how to get it to show as a image. Currently the code compiles but returns no images.
I’ve been using this extension
extension UIImageView {
func load(url: URL) {
DispatchQueue.global().async { [weak self] in
if let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
DispatchQueue.main.async { self?.image = image }
}
}
}
}
}

Add this extension,
func stringToImage(_ handler: #escaping ((UIImage?)->())) {
if let url = URL(string: self) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
let image = UIImage(data: data)
handler(image)
}
}.resume()
}
}
}

Related

nested loadObject call issue

I write some code to show an image dragged from other apps(such as web browser, photos, etc). I make a delegate to perform the drop.
If DropInfo has an image item, I will try to retrieve the data as uiimage by NSItemProvider.loadObject first. If errors occur during loading, I will ask DropInfo again whether it has a url item. If the answer is YES, I will try to retrieve URL by NSItemProvider.loadObject.
It means the second loadObject will be nested in the first one. When running the simulator, I find the second loadObject completion handler is never called which is supposed to be called when I try to retrieve URL. Do I miss anything?
import SwiftUI
import Combine
struct ContentView: View{
#State private var img: UIImage?
var body: some View{
Image(uiImage: img != nil ? img! : UIImage(systemName: "photo")!)
.resizable()
.scaledToFit()
.onDrop(of: [.image], delegate: ImageDropController(img: $img))
}
}
class ImageDropController: DropDelegate{
#Binding var img: UIImage?
init(img: Binding<UIImage?>) {
_img = img
}
func performDrop(info: DropInfo) -> Bool {
if getImgFromImage(info: info){
return true
}else{
return false
}
}
func getImgFromImage(info: DropInfo) -> Bool{
guard info.hasItemsConforming(to: [.image]) else {
return getImgFromUrl(info: info)
}
createImgFromImage(from: info.itemProviders(for: [.image]).first!,info: info)
return true
}
func createImgFromImage(from provider: NSItemProvider, info: DropInfo){
provider.loadObject(ofClass: UIImage.self) { image, error in
var unwrappedImage: UIImage?
if let error = error {
print("unwrapImage failed: ", error.localizedDescription)
_ = self.getImgFromUrl(info: info)
} else {
unwrappedImage = image as? UIImage
}
if let image = unwrappedImage{
DispatchQueue.main.async {
self.img = image
}
}
}
}
func getImgFromUrl(info: DropInfo) -> Bool{
guard info.hasItemsConforming(to: [.url]) else {
return false
}
createImgFromUrl(from: info.itemProviders(for: [.url]).first!)
return true
}
private func createImgFromUrl(from provider: NSItemProvider){
var fetchUrl: URL?
print("create from url")
_ = provider.loadObject(ofClass: URL.self) { url, error in
print("nested handler") <<------- never be called
if let error = error {
print("unwrapUrl failed: ", error.localizedDescription)
} else {
fetchUrl = url
print("url", fetchUrl?.description)
}
if let url = fetchUrl{
// Do some data fetch work using url
}
}
}
}

how to fetch data from array by indexing in SwiftUI?

This is my Json file and i don't understand how to fetch data and set
the Image in our SwiftUI code. please help me resolve this problem.
And this is My Model, is this model correct?
This is My API and wants to fetch only value images array
import Foundation
public struct BannerImages {
public let images: [String]
public init(images: [String]) {
self.images = images
}
}
try this approach to fetch your images and display them in a View:
import Foundation
import SwiftUI
struct ContentView: View {
#StateObject var vm = ViewModel()
var body: some View {
VStack {
Text("Fetching the data...")
List (vm.images, id: \.self) { url in
AsyncImage(url: URL(string: url)) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 111, height: 111)
} placeholder: {
ProgressView()
}
}
}
.task {
await vm.getData()
}
}
}
class ViewModel: ObservableObject {
#Published var images = [String]()
func getData() async {
guard let url = URL(string: "apiurl") else { return }
do {
let (data, _) = try await URLSession.shared.data(from: url)
Task{#MainActor in
let results = try JSONDecoder().decode(APIResponse.self, from: data)
self.images = results.images
}
} catch {
print("---> error: \(error)")
}
}
}
struct APIResponse: Codable {
let images: [String]
}
1. First you need to have a variable with data type of Data like this: var imageData: Data?
2. Then you have to fetch the image data from the link in the array like this:
func getImageData() {
// Check image url isnt nill
guard imageUrl(your image url) != nil else {
return
}
// Download the data for the image
let url = URL(string: imageUrl(your image url)!)
if let url = url {
let session = URLSession.shared
let dataTask = session.dataTask(with: url) { data, response, error in
if error == nil {
DispatchQueue.main.async {
self.imageData = data
}
}
}
dataTask.resume()
}
}
3. Once this is done go to the view file where you want to display the image and create
let uiImage = UIImage(data: put the var in which you stored the image data in previous step ?? Data())
Image(uiImage: uiImage ?? UIImage())

Sharing photo with Whatsapp not working under Xcode 9.1 and iOS11

The below code used to work in Xcode8. But now it is not working in Xcode 9.1 with target iOS11.
I did the following:
class ViewController: UIViewController {
var documentInteractionController: UIDocumentInteractionController = UIDocumentInteractionController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func ShareImages(_ sender: AnyObject)
{
let urlWhats = "whatsapp://app"
if let urlString = urlWhats.addingPercentEncoding(withAllowedCharacters:CharacterSet.urlQueryAllowed) {
if let whatsappURL = URL(string: urlString) {
if UIApplication.shared.canOpenURL(whatsappURL as URL) {
if let image = UIImage(named: "whatsappIcon") {
if let imageData = UIImageJPEGRepresentation(image, 1.0) {
let tempFile = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Documents/whatsAppTmp.wai")
do {
try imageData.write(to: tempFile, options: .atomic)
self.documentInteractionController = UIDocumentInteractionController(url: tempFile)
self.documentInteractionController.uti = "net.whatsapp.image"
self.documentInteractionController.presentOpenInMenu(from: CGRect.zero, in: self.view, animated: true)
} catch {
print(error)
}
}
}
} else {
// Cannot open whatsapp
}
}
}
}
// Added this in info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>whatsapp</string>
</array>

Profile Image does not appear when I run the app.

Theres no error in my code but ImagevIew image doesn't show
let imageCache = NSCache()
extension UIImageView {
func loadImageUsingCacheWithUrlString(urlString: String) {
//self.image = nil
if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
self.image = cachedImage
return
}
let url = URL(string: urlString)
URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async(execute: {
if let currImage = UIImage(data: data!) {
imageCache.setObject(currImage, forKey: urlString as AnyObject)
self.image = currImage
}
})
}).resume()
}
}

Swift 3 JsonSerialization

Code
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnGirisYap(_ sender: Any) {
let url = NSURL(string: "http://www.kerimcaglar.com/yemek-tarifi")!
let task = URLSession.shared.dataTask(with: url as URL) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
//print (jsonResult)
self.txtGirisKullaniciAdi.text = jsonResult["malzemeler"] as! NSString as String
} catch {
print("JSON serialization failed")
}
} else {
print("ERROR FOUND HERE")
}
}
task.resume()
}
}
Can you help with this?
The error message tells you clearly that the deserialized object is an array rather than a dictionary.
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: []) as! [[String:Any]]
for item in jsonResult {
print(item["malzemeler"] as! String) // cast directly to String
}
Notes:
The unspecified JSON dictionary type in Swift 3 is [String:Any].
The mutableContainers option is useless in Swift.