Simple App in SwiftUI

lyvennitha sasikumar
4 min readAug 5, 2021

Hey Guys! Here i got one more new concept in SwiftUI for you. Here i implemented List with pop up where the datas come from an open API provided by gov.in. Here i used fish related API i’d get from https://www.fishwatch.gov/api/species. And used the species image and species name to make list in SwiftUI.

Fish App

Prepare for Network Layer

Here i used URLSession to fetch data from the fishwatch API. Create Network Folder. And Create NetworkLayer.swift file in that folder. Create a singleton class.

struct Network{
static var shared = Network()
}

Add some network constants like URL and httpmethod in enum

enum NetworkConstants: String{
case URL = "https://www.fishwatch.gov/api/species"
case httpMethod = "GET"
}

Add Model class for the result JSON in model class file. Here i wont share that as it contains a large set of struct datas. I just provide the typealias for it.

typealias MyFishRecordData = [MyFishRecord]

Create a method to implement URLsession task for getting data. Final Network class looks like below.

struct Network{
static var shared = Network()
var fishRecords = MyFishRecordData()
func getData(completion: @escaping (Result<MyFishRecordData, Error>) -> Void){
let urlRequest = URLRequest(url: URL(string: NetworkConstants.URL.rawValue)!)
URLSession.shared.dataTask(with: urlRequest){ data,response,error in
let
fishRecords = try? JSONDecoder().decode(MyFishRecordData.self, from: data!)
print(fishRecords?.count ?? 0, "count")
completion(.success(fishRecords!))
}.resume()
}
}

Lets prepare for ContentView.swift. Start with creating list with navigation title.

struct ContentView: View {
@State var fishData = MyFishRecordData()
var
body: some View {
NavigationView {
VStack{
List(fishData) { fish in
}
}
}.onAppear(){
getDataforFish()
}
.navigationTitle("Fishes")
}
}
}
}

Output:

OutPut

OOPS!🤭. We forgot to create cell!

Its time to create cells for List.

Here Create a separate file. I just named it as FishRow.swift. Here i used SDWebimage SDK for downloading image from URL. PodFile initiation is normal as like as before. Just add import SDWebImageSwiftUI.

struct FishRow: View {  var fish: MyFishRecord  var body: some View {   HStack {    AnimatedImage(url: URL(string: fish.speciesIllustrationPhoto?.src ?? "")!)   .resizable()    .frame(width: 70, height: 70)  Text(verbatim: fish.speciesName ?? "")  } }}

Result:

Output

Now we will add pop up to list to view more about the listed fishes. Lets create a popup view. Here the datas for more about fish are came in HTML string. I gonna show that in a scroll view for label. Let me explain here how i done this.

Create a PopupView.swift file. Lets create some enum for convenience to make it as Alert look.

enum AlertAction {  case ok  case cancel}

Create a view for popup. I create popup with a image, text, ok and cancel button actions. Below is the code set where we need image, text data from API.

struct AlertView: View {@Binding var shown: Bool@Binding var closureA: AlertAction?var message: Stringvar fish: MyFishRecordvar body: some View {VStack {AnimatedImage(url: URL(string: fish.speciesIllustrationPhoto?.src ?? "")!).resizable().frame(width: 250, height: 250)Spacer()ScrollView{HTMLText(html: fish.biology ?? "", width: 300).padding(15)}Spacer()Divider()HStack {Button("Close") {closureA = .cancelshown.toggle()}.frame(width: UIScreen.main.bounds.width/2-30, height: 40).foregroundColor(.white)Button("Ok") {closureA = .okshown.toggle()}.frame(width: UIScreen.main.bounds.width/2-30, height: 40).foregroundColor(.white}}.frame(width: UIScreen.main.bounds.width-50, height: UIScreen.main.bounds.height - 200).background(Color.black.opacity(0.5)).cornerRadius(12).clipped()}}

What is that HTML text. Yes that is where we convert the html string to normal customised String. He i provided code below for HTMLText.

struct HTMLText: UIViewRepresentable {let html: Stringvar width: CGFloatfunc makeUIView(context: UIViewRepresentableContext<Self>) -> UILabel {let label = UILabel()label.numberOfLines = 0var attributes = [NSAttributedString.Key.font:UIFont(name: "Helvetica", size: 20.0)!,NSAttributedString.Key.foregroundColor: UIColor.white] as NSDictionary?DispatchQueue.main.async {let data = Data(self.html.utf8)if let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: &attributes) {label.attributedText = attributedStringlabel.textColor = .whitelabel.font = UIFont.systemFont(ofSize: 20)label.preferredMaxLayoutWidth = width}}return label}func updateUIView(_ uiView: UILabel, context: Context) {
}
}

Here in the above code, i just initiated a UILabel instance and use it by customising color and font size for attributed string get from HTML String to String converted.

How to use the above popup in List.

AlertView(shown: $shown, closureA: $c, message: message, fish: fishData[selectedIndex ?? 0])

Final Code of ContentView.swift is looks like below!

struct ContentView: View {@State var fishData = MyFishRecordData()@State var shown = false@State var message = ""@State var c: AlertAction?@State var fishD: MyFishRecord?@State var selectedIndex: Int?var body: some View {NavigationView {VStack{List(fishData) { fish inFishRow(fish: fish).onTapGesture {selectedIndex = fishData.firstIndex(where: {$0.speciesName == fish.speciesName})shown.toggle()}}}.onAppear(){getDataforFish()}.navigationTitle("Fishes")}if fishData.count > 0 && shown{AlertView(shown: $shown, closureA: $c, message: message, fish: fishData[selectedIndex ?? 0])}}}

Where to call the API.

extension ContentView{func getDataforFish(){let selfi = self Network.shared.getData(completion: {(result) inswitch(result){case .success(let records):DispatchQueue.main.async {selfi.fishData = records}case .failure(_):print("An error occurred")}})}}

Final Result for popup:

Popup

Just unable to share the code. Soon code for all blogs available in every blog.

HAPPY CODING!🌎

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

lyvennitha sasikumar
lyvennitha sasikumar

Written by lyvennitha sasikumar

Passionate iOS developer chasing my dreams toward success

No responses yet

Write a response