// // card.swift // card // // Created by Micah Gomez on 8/21/20. // import WidgetKit import SwiftUI extension UserDefaults { func colorForKey(key: String) -> UIColor? { var colorReturnded: UIColor? if let colorData = data(forKey: key) { do { if let color = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(colorData) as? UIColor { colorReturnded = color } } catch { print("Error UserDefaults") } } return colorReturnded } func setColor(color: UIColor?, forKey key: String) { var colorData: NSData? if let color = color { do { let data = try NSKeyedArchiver.archivedData(withRootObject: color, requiringSecureCoding: false) as NSData? colorData = data } catch { print("Error UserDefaults") } } set(colorData, forKey: key) } } struct Provider: TimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), cardName: "Johnny Appleseed", cardPhone: "(123)456-7890", cardEmail: "johnny@appleseed.com", cardPhoto: UIImage(systemName: "person.badge.plus")!, cardQR: UIImage(systemName: "qrcode")!) } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { let entry = SimpleEntry(date: Date(), cardName: "Johnny Appleseed", cardPhone: "(123)456-7890", cardEmail: "johnny@appleseed.com", cardPhoto: UIImage(systemName: "person.badge.plus")!, cardQR: UIImage(systemName: "qrcode")!) completion(entry) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { let defaults = UserDefaults(suiteName:"group.dev.mpg13.busyness") var cardName: String if defaults?.string(forKey: "savedCardName") != nil { cardName = (defaults?.string(forKey: "savedCardName"))! } else { cardName = "Johnny Appleseed" } let cardPhone = defaults?.string(forKey: "savedCardPhone") ?? "Phone/Other" let cardEmail = defaults?.string(forKey: "savedCardEmail") ?? "Email" var cardPhoto: UIImage if defaults?.data(forKey: "savedCardPhoto") != nil { cardPhoto = UIImage(data: (defaults?.data(forKey: "savedCardPhoto"))!)! } else { cardPhoto = UIImage(systemName: "person.badge.plus")! } var cardQR: UIImage if defaults?.data(forKey: "savedQRPhoto") != nil { cardQR = UIImage(data: (defaults?.data(forKey: "savedQRPhoto"))!)! } else { cardQR = UIImage(systemName: "qrcode")! } let date = Date() let entry = SimpleEntry( date: date, cardName: cardName, cardPhone: cardPhone, cardEmail: cardEmail, cardPhoto: cardPhoto, cardQR: cardQR ) let nextUpdateDate = Calendar.current.date(byAdding: .minute, value: 15, to: date)! let timeline = Timeline( entries:[entry], policy: .after(nextUpdateDate) ) /* let currentDate = Date() for minuteOffset in 0 ..< 5 { let entryDate = Calendar.current.date(byAdding: .minute, value: minuteOffset, to: currentDate)! print(entryDate) let entry = SimpleEntry(date: entryDate) entries.append(entry) } let timeline = Timeline(entries: entries, policy: .atEnd)*/ completion(timeline) } } struct SimpleEntry: TimelineEntry { let date: Date let cardName: String let cardPhone: String let cardEmail: String let cardPhoto: UIImage let cardQR: UIImage } struct cardSmallView : View { var entry: Provider.Entry var body: some View{ VStack{ Spacer() Text(entry.cardName).fontWeight(.heavy).lineLimit(2).minimumScaleFactor(0.5) HStack{ Image(uiImage: entry.cardPhoto).resizable().scaledToFit().cornerRadius(16) Image(uiImage: entry.cardQR).resizable().scaledToFit() } Spacer() } } } struct cardMediumView : View { var entry: Provider.Entry var body: some View{ GeometryReader{g in VStack(spacing: 5){ Spacer() Text(entry.cardName).fontWeight(.heavy).lineLimit(1).font(.system(size: 24)).minimumScaleFactor(0.5).multilineTextAlignment(.center).padding(.top) HStack{ Image(uiImage: entry.cardPhoto).resizable() .frame(width: g.size.width / 5, height: g.size.width / 5, alignment: .bottomLeading).cornerRadius(16) Image(uiImage: entry.cardQR).resizable() .frame(width: g.size.width / 5, height: g.size.width / 5, alignment: .bottomLeading) VStack{ Spacer() Text(entry.cardPhone).lineLimit(1).font(.system(size: 18, design: .rounded)).minimumScaleFactor(0.3) Text(entry.cardEmail).lineLimit(1).font(.system(size: 18, design: .rounded)).minimumScaleFactor(0.6) Spacer() }.padding(.bottom) } Spacer() } } } } struct cardLargeView : View { var entry: Provider.Entry var body: some View{ VStack{ Spacer() Text(entry.cardName).fontWeight(.heavy).lineLimit(2).font(.system(size: 36)).minimumScaleFactor(0.5) Spacer() HStack{ Image(uiImage: entry.cardPhoto).resizable().scaledToFit().cornerRadius(16) Image(uiImage: entry.cardQR).resizable().scaledToFit() } Spacer() Text(entry.cardPhone).lineLimit(1).font(.system(size: 20, design: .rounded)).minimumScaleFactor(0.5) Spacer() Text(entry.cardEmail).lineLimit(1).font(.system(size: 20, design: .rounded)).minimumScaleFactor(0.5) Spacer() } } } struct detailsNotAvailable : View { var entry: Provider.Entry var body: some View{ VStack{ Text("Nothing Available") } } } struct cardEntryView : View { var entry: Provider.Entry @Environment(\.widgetFamily) var family: WidgetFamily let defaults = UserDefaults(suiteName:"group.dev.mpg13.busyness") let viewColor = UserDefaults(suiteName:"group.dev.mpg13.busyness")?.colorForKey(key: "savedColor") var body: some View { ZStack { Color(viewColor ?? UIColor.white) .edgesIgnoringSafeArea(.all) Group{ switch family { case .systemSmall: cardSmallView(entry: entry) case .systemMedium: cardMediumView(entry: entry) case .systemLarge: cardLargeView(entry: entry) default: detailsNotAvailable(entry: entry) } }.padding(.horizontal) } } } @main struct card: Widget { let kind: String = "card" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: Provider()) { entry in cardEntryView(entry: entry) } .configurationDisplayName("My Widget") .description("This is an example widget.") } } struct card_Previews: PreviewProvider { static var previews: some View { cardEntryView(entry: SimpleEntry(date: Date(), cardName: "Johnny Appleseed", cardPhone: "(123)456-7890", cardEmail: "johnny@appleseed.com", cardPhoto: UIImage(systemName: "person.badge.plus")!, cardQR: UIImage(systemName: "qrcode")!)) .previewContext(WidgetPreviewContext(family: .systemSmall)) } }