Creating a survey and graphing app using Swift and Swift UI

I've been focusing much creative energy on making activities for students which blend simple tools of Swift with Swift UI. My students have a bit of traditional computer science training from using the Develop with Swift Explorations, and we have made a few simple user interfaces with other activities. The app shown here does not require MacBooks or XCode, and can be made completely on the iPad through Swift Playgrounds.


One of my goals as an educator is to provide my students with culturally relevant assignments and tasks, projects which they are inspired to work on because it speaks to them directly. I've found most students want to influence their school, and so we create this simple app which allows the user to conduct a simple survey of other people, then click a button have have a graph of the results appear.

This task can be modified to change the content of the survey, or the color schemes, and it is probably fairly easy to change it to display a bar graph. I like it because it builds user interface building skills without introducing several different complicated libraries, and it requires no outside data.

Here is a youtube video of me making the app, with commentary:

 

https://www.youtube.com/embed/3CZQMFgP0E8?showinfo=0&enablejsapi=1



And here is the actual code for the main file:

//This app was made by Andy Lapetina
//This app will administer a survey
//It should plot results in a graph

import SwiftUI

@main
struct LunchSurveyApp: App {
    var body: some Scene {
        WindowGroup {
            HomeScreen()
        }
    }
}

The home screen:

//This will start by showing the options for a survey 
//of what we should have for lunch

import SwiftUI

struct HomeScreen : View {
    @State private var selectedOption: String = "Burgers"
    @State private var surveyResults: [String: Int] = ["Burgers":0, "Sandwich":0, "Salad":0]
    @State private var showResults = false
        
    let options = ["Burgers", "Sandwich", "Salad"]
    
    var body: some View {
        VStack {
            Text ("Choose your preferred option for lunch.")
                .font (.title)
            
            Picker ("Choose your lunch.", selection: $selectedOption) {
                ForEach(options,id:\.self){ option in 
                    Text (option)
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            
            Button ("Submit Entry"){
                surveyResults[selectedOption, default:0]+=1
            }
                .padding()
                .background (Color.blue)
                .foregroundColor (.white)
                .cornerRadius (8)
            Button ("View Results"){
                showResults = true
            }
                .padding ()
                .background (Color.green)
                .foregroundColor (.white)
                .cornerRadius (8)
            Spacer ()
                .navigationTitle("Get Results")
                .sheet(isPresented: $showResults){
                    ResultsView (surveyResults : surveyResults)
                }
        }
    }
}

And the graphing swift file:

import SwiftUI
import Charts

struct SurveyData: Identifiable {
    let id = UUID()
    let option: String
    let count: Int
}

struct ResultsView: View{
    let surveyResults: [String:Int]
    
    var chartData: [SurveyData]{
        surveyResults.map {SurveyData (option:$0.key, count:$0.value)}
    }
    var body: some View {
        VStack {
            Text ("Survey Results")
                .font (.title)
                .padding ()
            
            Chart {
                ForEach (chartData){ data in
                    SectorMark(
                        angle: .value ("Count", data.count),
                        innerRadius: .ratio (0.5),
                        angularInset: 1
                    )
                    .foregroundStyle ( by: .value ("Option", data.option))
                    
                }
            }
            .chartLegend (.visible)
            .frame (height: 300)
            .padding ()
            
            Spacer()
        }
    }
    
}

During the video, I certainly use the wrong words to describe some of the programming content. Please feel free to correct me in the comments! Thanks!

0 replies