I need to send tokens with a get url in my iOS app and use its response in my view. One can fetch api through the following code:
final class IMDBAPI{
// function to get data from the api
func getDataForPageNr(page: Int, completion: @escaping (PageData) -> ()){
// check if page argument in the URL is a positive number
guard page >= 1 else{ return }
// create the URL
if let url = URL(string: "http://www.omdbapi.com/?s=Batman&page=\(page)&apikey=eeefc96f"){
// start URL session
URLSession.shared.dataTask(with: url){ data, response, error in
// if you get a data response
if let data = data{
do{
// decode the JSON to the PageData object
let result = try JSONDecoder().decode(PageData.self, from: data)
// we are changing the UI dynamically here, you have to do that on the main thread in SwiftUI
DispatchQueue.main.async {
// use the completion handler and pass the result
completion(result)
}
}
// here handle errors when decoding of JSON fails
catch let error{
print(error)
}
}
}.resume()
}
}
}
the above code works perfectly if one doesn't have tokens to send In my case I have the following api: https://contributorapi.yogpathwellness.com/ProfileMaster/Dashboard/VID_307 and the following tokens to send "Token": "MkpHS3Ftei9kWWRMM3k3eGpaQnNhR2xUK0h2NnI0MlZXV3ZIbjVJY0pjOD0jMjAyMDEyMDEy" "DeviceId": "202012012"
the response I shall be getting from the api
{
"data": {
"Cid": "VID_307",
"Fullname": "Yog maya",
"LiveClass": [
{
"author": "",
"class_starttime": "",
"classid": "",
"image": "https://storage.googleapis.com/yoga_data/DefaultImage.gif",
"starts_in": "",
"title": ""
}
],
"Skill": "",
"Status": "Lead",
"achievment_description": "",
"certificate": "0",
"classes": [
{
"class_name": "",
"consultant": "0",
"image": "https://storage.googleapis.com/yogpath_vendor_data/No_Image_Available.jpg",
"live_classes": "0",
"ratings": "",
"total_video": "0",
"users": "0"
}
],
"descriptions": "",
"experience": "20",
"followers": "0",
"isLive": false,
"latest_video": [
{
"Duration": null,
"Title": "",
"comment": "0",
"content_id": null,
"description": "",
"image": "https://storage.googleapis.com/yogpath_vendor_data/No_Image_Available.jpg",
"like": "0",
"name": "",
"thumbnail": "https://storage.googleapis.com/yogpath_vendor_data/No_Image_Available.jpg",
"time": "",
"vendorprofile": "https://storage.googleapis.com/yogpath_vendor_data/No_Image_Available.jpg",
"videourl": "",
"view": "0",
"viewers": []
}
],
"live_classes": "0",
"no_of_video": "0",
"random_yoga": [
{
"image": "",
"location": "",
"name": "",
"rating": "",
"users": "0"
}
],
"rating": "",
"reviews": "0",
"schedule": [
{
"Date": "",
"DateDynamic": [
{
"name": "",
"subscriber": [
{
"image": "",
"name": "",
"userId": ""
}
],
"time_range": "",
"type": ""
}
]
}
],
"selfie": "https://storage.googleapis.com/yogpath_vendor_data/No_Image_Available.jpg",
"sessions": "0",
"successful_ot": "0",
"total_patients": "0",
"view": "0"
},
"message": "Success",
"status": true
}
I need to store the response in the following Struct:
struct InstructorDetails: Codable {
let data: [Data1]
let message: String
let status: Bool
}
struct Data1: Codable {
let Cid: String
let Fullname: String
let LiveClass: [LiveClass]
let Skill: String
let Status: String
let achievement_description: String
let certificate: String
let classes: [Classes]
let descriptions: String
let experience: String
let followers: String
let isLive: String
let latest_video: [LatestVideo]
let live_classes: String
let no_of_video: String
let random_yoga: [RandomYoga]
let rating: String
let reviews: String
let schedule: [Schedule]
let selfie: String
let sessions: String
let successful_ot: String
let total_patients: String
let views: String
}
struct LiveClass: Codable {
let author: String
let class_starttime: String
let classid: String?
let image: String?
let starts_in: String
let title: String?
}
struct Classes: Codable {
let class_name: String
let consultant: String
let image: String
let live_classes: String
let ratings: String
let total_video: String
let users: String
}
struct LatestVideo: Codable {
let comment: String
let image: String
let like: String
let name: String
let thumbnail: String
let time: String
let venorprofile: String
let videourl: String
let views: String
let viewers: [Int]?
}
struct RandomYoga: Codable {
let image: String
let location: String
let name: String
let rating: String
let users: String
}
struct Schedule: Codable {
let date: String?
let dateDynamic: [DateDynamic]
enum CodingKeys: String, CodingKey{
case date = "Date"
case dateDynamic = "DateDynamic"
}
}
struct DateDynamic: Codable {
let name: String
let subscriber: [Subscriber]
let time_range: String?
let type: String?
}
struct Subscriber: Codable {
let image: String?
let name: String?
let userId: String?
}
I am trying to have a similar approach like this short project(working): https://github.com/themacbookaircoder/IMDB-SwiftUI
Below is my view where I am trying to use it in(failed attempt):
import SwiftUI
import Alamofire
import Kingfisher
import SwiftUIX
struct ProfileTabView: View {
@State var rating = 3.0
@State var followers = "5000"
@State var videos = "254"
@State var liveClasses = "254"
@State var sessions = "254"
@State var imageName = ""
@State var reviews = "4000"
@State var views: Int = 2382
@State var liveClass: [String] = [""]
@State private var instructorDetails = InstructorDetails(data: [], message: "this", status: false)
var gridItemLayout = [GridItem(.fixed(20)), GridItem(.fixed(20)), GridItem(.fixed(20))]
var body: some View {
VStack {
ScrollView {
VStack {
//print(instructorDetails.message)
Group {
ZStack {
Image("default-profile")
// Image("\(imageName)") //default-profile
// .resizable()
// .frame(width: percentWidth(percentage: 100), height: percentHeight(percentage: 100))
HStack {
VStack {
HStack {
Text("Live \(instructorDetails.message)")
.padding(3)
.padding([.leading, .trailing], 5)
.background(Color.red)
.foregroundColor(Color.white)
HStack {
Image("eyeforteen")
.resizable()
.frame(width: 20, height: 15)
Text("\(views)")
.foregroundColor(.white)
.font(Font.custom(FontName.normal, size: 17))
}
.padding(3)
.padding([.leading, .trailing], 5)
.background(Color(red: 0/255, green: 0/255, blue: 0/255, opacity: 0.2))
}
.padding()
Spacer()
}
Spacer()
VStack(spacing: 1) {
Text("\(followers) Followers")
.foregroundColor(.white)
.font(Font.custom(FontName.normal, size: 17))
.padding(5)
Text("\(reviews) Reviews")
.foregroundColor(.white)
.font(Font.custom(FontName.normal, size: 17))
.padding(5)
Button(action: {
print("button pressed \(instructorDetails.message)")
}) {
ZStack {
Image("blue-rect")
.renderingMode(.original)
.resizable()
.frame(width: 120, height: 45)
Text("Follow")
.foregroundColor(.white)
.font(Font.custom(FontName.bold, size: 20))
}
}
.padding(5)
Spacer()
}
}
.padding(.top, 35)
}
HStack {
LazyVGrid(columns: gridItemLayout, spacing: 0) {
ForEach(viewsArr, id: \.self) { registerData in
Image("avatar")
.resizable()
.frame(width: 30, height: 30)
.scaledToFill()
.cornerRadius(15)
}
}
}
Text("999 views")
.foregroundColor(.systemGray)
.font(Font.custom(FontName.normal, size: 12))
}
ZStack {
RoundedRectangle(cornerRadius: 15)
.shadow(color: .gray, radius: 3, x: -2, y: 2)
.foregroundColor(Color.clear)
.padding(1)
VStack {
Image("demoImg")
.resizable()
.frame(width: percentWidth(percentage: 95),
}
VStack {
HStack {
HStack {
Image("demoImg")
.resizable()
.frame(width: 35, height: 35)
.cornerRadius(35/2)
VStack(alignment: .leading) {
HStack {
Text("Linda")
.foregroundColor(.white)
}
HStack {
Text("2 hours ago")
.foregroundColor(.white)
.font(Font.custom(FontName.normal, size: 15))
}
.padding(.trailing, 10)
}
}
.clipShape(Capsule())
Spacer()
}
.padding()
Spacer()
}
}
HStack {
HStack {
Image("heartVid")
.resizable()
.frame(width: 22, height: 22)
Text("1242")
.foregroundColor(.systemGray)
.font(Font.custom(FontName.normal, size: 12))
}
HStack {
Image("commentVid")
.resizable()
.frame(width: 22, height: 22)
Text("1242")
.foregroundColor(.systemGray)
.font(Font.custom(FontName.normal, size: 12))
}
.padding(.leading, 20)
Spacer()
HStack {
LazyVGrid(columns: gridItemLayout, spacing: 0) {
ForEach(viewsArr, id: \.self) { registerData in
Image("avatar")
.resizable()
.frame(width: 30, height: 30)
.scaledToFill()
.cornerRadius(15)
}
}
}
Text("999 views")
.foregroundColor(.systemGray)
.font(Font.custom(FontName.normal, size: 12))
}
}
.frame(width: percentWidth(percentage: 90))
}
.frame(width: percentWidth(percentage: 95))
}
}
Group {
Text("My Class").font(Font.custom(FontName.medium, size: 20)).padding(.trailing, percentWidth(percentage: 72))
VStack {
Image("barometer").resizable().frame(width: percentWidth(percentage: 100), height: percentHeight(percentage: 25), alignment: .leading)
HStack(alignment: .center, spacing: 8) {
Image("video").resizable().frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("100 ").font(Font.custom(FontName.medium, size: 14))
Text("videos").font(Font.custom(FontName.medium, size: 10)).opacity(0.5)
}.padding(.trailing, 14)
Image("liveClasses")
.resizable()
.frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("15 ").font(Font.custom(FontName.medium, size: 14))
Text("live class").font(Font.custom(FontName.medium, size: 10)).opacity(0.5)
}.padding(.trailing, 14)
Image("liveClasses")
.resizable()
.frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("78 ").font(Font.custom(FontName.medium, size: 14))
Text("consultant").font(Font.custom(FontName.medium, size: 9)).opacity(0.5)
}.padding(.trailing, 14)
Image("sessions")
.resizable()
.frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("2000 ").font(Font.custom(FontName.medium, size: 10))
Text("users").font(Font.custom(FontName.medium, size: 10)).opacity(0.5)
}.padding(.trailing, 20)
}
}
VStack {
Image("barometer").resizable().frame(width: percentWidth(percentage: 100), height: percentHeight(percentage: 25), alignment: .leading)
HStack(alignment: .center, spacing: 8) {
Image("video").resizable().frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("100 ").font(Font.custom(FontName.medium, size: 14))
Text("videos").font(Font.custom(FontName.medium, size: 10)).opacity(0.5)
}.padding(.trailing, 14)
Image("liveClasses")
.resizable()
.frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("15 ").font(Font.custom(FontName.medium, size: 14))
Text("live class").font(Font.custom(FontName.medium, size: 10)).opacity(0.5)
}.padding(.trailing, 14)
Image("liveClasses")
.resizable()
.frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("78 ").font(Font.custom(FontName.medium, size: 14))
Text("consultant").font(Font.custom(FontName.medium, size: 9)).opacity(0.5)
}.padding(.trailing, 14)
Image("sessions")
.resizable()
.frame(width: percentWidth(percentage: 8), height: percentHeight(percentage: 4))
VStack {
Text("2000 ").font(Font.custom(FontName.medium, size: 10))
Text("users").font(Font.custom(FontName.medium, size: 10)).opacity(0.5)
}.padding(.trailing, 20)
}
}
Text("My Schedule").font(Font.custom(FontName.medium, size: 18)).opacity(0.4).padding(.trailing, percentWidth(percentage: 70))
Text("Today , Mon, june 8").font(Font.custom(FontName.medium, size:18)).opacity(0.7).padding(.trailing, percentWidth(percentage: 50))
ZStack {
RoundedRectangle(cornerRadius: 6)
.shadow(color: .gray, radius: 3, x: -4, y: 4)
.frame(width: percentWidth(percentage: 92), height: percentHeight(percentage: 20))
.foregroundColor(Color.blue).opacity(0.17)
.padding(5)
HStack {
}
}
}
}
.onAppear {
//network.getUsers()
getDataInstructor() {
instructorDetails in
self.instructorDetails = instructorDetails
}
//InstructorAPI()
// InstructorAPI().getDataForInstructor{ (instructorDetails) in
// self.instructorDetails = instructorDetails
}
.edgesIgnoringSafeArea(.all)
}
func getDataInstructor(completion: @escaping (InstructorDetails) -> ()){
if let url = URL(string: "https://contributorapi.yogpathwellness.com/ProfileMaster/Dashboard/VID_307"){
var urlRequest = URLRequest(url: url)
urlRequest.setValue("MkpHS3Ftei9kWWRMM3k3eGpaQnNhR2xUK0h2NnI0MlZXV3ZIbjVJY0pjOD0jMjAyMDEyMDEy", forHTTPHeaderField: "Token")
urlRequest.setValue("202012012", forHTTPHeaderField: "DeviceId")
let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if let error = error {
print("Request error: ", error)
return
}
guard let response = response as? HTTPURLResponse else { return }
if response.statusCode == 200 {
guard let data = data else { return }
do {
print("User Data Respons\(data)")
// let decodedUsers = try JSONDecoder().decode([User].self, from: data)
// self.users = decodedUsers
}
DispatchQueue.main.async {
}
}
}
dataTask.resume()
}
}
}
I am able to get the user data in my Xcode log as: User Data Respons1444 bytes I am looking for a clean approach which decodes my data and feed that to the instructorDetails object(of InstructorDetails struct) An approach using Alamofire would also be welcomed.
CodePudding user response:
Do you mean you want to send "Token" and "DeviceId" in your URLRequest?
var apiRequest = URLRequest(url: URL(string: "your url link")!)
apiRequest.httpMethod = "GET"
apiRequest.addValue("MkpHS3Ftei9kWWRMM3k3eGpaQnNhR2xUK0h2NnI0MlZXV3ZIbjVJY0pjOD0jMjAyMDEyMDEy", forHTTPHeaderField: "Token")
apiRequest.addValue("202012012", forHTTPHeaderField: "DeviceId")
apiRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: apiUrlRequest){ data, response, error in
//process the response
}.resume()
Difference of "addValue" and "setValue" here