SwiftUI & Combine app using MovieDB API. With a custom Flux (Redux) implementation.

Overview

Xcode build

MovieSwiftUI

MovieSwiftUI is an application that uses the MovieDB API and is built with SwiftUI. It demos some SwiftUI (& Combine) concepts. The goal is to make a real world application using SwiftUI only. It'll be updated with new features as they come to the SwiftUI framework.

I have written a series of articles that document the design and architecture of the app: Making a Real World Application With SwiftUI.

App Image

Architecture

MovieSwiftUI data flow is a subset and a custom implementation of the Flux part of Redux. It implement the State in an ObservableObject as a @Published wrapped property, so changes are published whenever a dispatched action produces a new state after being reduced. The state is injected as an environment object in the root view of the application, and is easily accessible anywhere in the application. SwiftUI does all aspects of diffing on the render pass when your state changes. No need to be clever when extracting props from your State, they're simple dynamic vars at the view level. No matter your objects' graph size, SwiftUI speed depends on the complexity of your views hierarchy, not the complexity of your object graph.

SwiftUI

MovieSwiftUI is in pure Swift UI, the goal is to see how far SwiftUI can go in its current implementation without using anything from UIKit (basically no UIView/UIViewController representable).

It'll evolve with SwiftUI, every time Apple edits existing or adds new features to the framework.

Platforms

Currently MovieSwiftUI runs on iPhone, iPad, and macOS.

Follow me on Twitter to get the latest update about features, code and SwiftUI tips and tricks!

Comments
  • iOS 14 Beta 4 & 5 crash

    iOS 14 Beta 4 & 5 crash

    When scrolling through MoviesList or MovieDetail, the app crashes: Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [inf nan]

    opened by bark1n9 6
  • UserDetaultWrapper.swift -> public var wrappedValue: T {... never sets value

    UserDetaultWrapper.swift -> public var wrappedValue: T {... never sets value

    UserDetaultWrapper.swift -> public var wrappedValue: T {... never sets value

    the get { return ...} is called but never the set {...} so the value stored in the UserDefault never changes

    opened by alancook 6
  • TabbedView forgets state

    TabbedView forgets state

    If you tap a movie in the movies tab, then tap the "My Lists" tab, then switch back to the movies tab, the app forgets that you tapped a movie and resets to the standard view.

    I'm currently playing around with TabbedView in a different project and would be interested on how you would solve this. As far as I understand views are supposed to be "disposable", but storing the state of the subviews in the TabbedView itself feels wrong too...

    opened by hactar 6
  • App crashes on selection of the keywords cell

    App crashes on selection of the keywords cell

    1. Go to the movie detail view
    2. Wait for keywords cell to appear
    3. Select the cell
    4. App presents the next view, then navigates back to movie details view and crashes:
    2019-07-05 17:04:38.789573+0100 MovieSwift[59287:8790893] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (3) must be equal to the number of sections contained in the table view before the update (3), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted).'
    *** First throw call stack:
    (
    	0   CoreFoundation                      0x00007fff23af9c3e __exceptionPreprocess + 350
    	1   libobjc.A.dylib                     0x00007fff50131de0 objc_exception_throw + 48
    	2   CoreFoundation                      0x00007fff23af99b8 +[NSException raise:format:arguments:] + 88
    	3   Foundation                          0x00007fff255749ad -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
    	4   UIKitCore                           0x00007fff46e5975c -[UITableView _Bug_Detected_In_Client_Of_UITableView_Invalid_Number_Of_Sections:] + 193
    	5   UIKitCore                           0x00007fff46e58861 -[UITableView _endCellAnimationsWithContext:] + 14394
    	6   UIKitCore                           0x00007fff46e72a88 -[UITableView endUpdatesWithContext:] + 112
    	7   UIKitCore                           0x00007fff46e72c34 -[UITableView _performBatchUpdates:withContext:completion:] + 253
    	8   UIKitCore                           0x00007fff46e72d4c -[UITableView performBatchUpdates:completion:] + 98
    	9   SwiftUI                             0x00007fff2c24c016 $s7SwiftUI25UpdateCoalescingTableView33_BFB370BA5F1BADDC9D83021565761A49LLC19performBatchUpdates_10completionyyycSg_ySbcSgtF + 470
    	10  SwiftUI                             0x00007fff2c24c19f $s7SwiftUI25UpdateCoalescingTableView33_BFB370BA5F1BADDC9D83021565761A49LLC19performBatchUpdates_10completionyyycSg_ySbcSgtFTo + 175
    	11  SwiftUI                             0x00007fff2c24e151 $s7SwiftUI19ListCoreCoordinator33_BFB370BA5F1BADDC9D83021565761A49LLC17updateUITableView_4from2toySo0mN0C_xxtF + 1521
    	12  SwiftUI                             0x00007fff2c24cb61 $s7SwiftUI9_ListCore33_BFB370BA5F1BADDC9D83021565761A49LLV12updateUIView_7contextySo11UITableViewC_AA0L20RepresentableContextVyADyxq_GGtF + 657
    	13  SwiftUI                             0x00007fff2c573361 $s7SwiftUI32PlatformViewRepresentableAdaptor33_19642D833A8FE469B137699ED1426762LLV06updateD8Provider_7contexty10UIViewTypeQz_AA0cdE7ContextVyADyxGGtF + 289
    	14  SwiftUI                             0x00007fff2c2b322d $s7SwiftUI17PlatformViewChildV6update7contexty14AttributeGraph0H7ContextVyACyxGGz_tFyyXEfU_ + 2205
    	15  SwiftUI                             0x00007fff2c2ae526 $s7SwiftUI17PlatformViewChildV6update7contexty14AttributeGraph0H7ContextVyACyxGGz_tF + 310
    	16  SwiftUI                             0x00007fff2c2b4160 $s7SwiftUI17PlatformViewChildVyxG14AttributeGraph07UntypedF0AaeFP7_update_5graph9attributeySv_So10AGGraphRefaSo11AGAttributeatFZTW + 32
    	17  AttributeGraph                      0x00007fff2f2f18c9 $sTA + 25
    	18  AttributeGraph                      0x00007fff2f2db3ba _ZN2AG5Graph11UpdateStack6updateEv + 1104
    	19  AttributeGraph                      0x00007fff2f2db639 _ZN2AG5Graph16update_attributeEjb + 377
    	20  AttributeGraph                      0x00007fff2f2dff01 _ZN2AG8Subgraph6updateEj + 943
    	21  SwiftUI                             0x00007fff2c18e5c0 $s7SwiftUI9ViewGraphC14runTransaction33_D63C4EB7F2B205694B6515509E76E98BLL2inySo10AGGraphRefa_tF + 224
    	22  SwiftUI                             0x00007fff2c18e48d $s7SwiftUI9ViewGraphC15syncTransaction33_D63C4EB7F2B205694B6515509E76E98BLLyyAA0F0V_ySo10AGGraphRefaXEtFyAIXEfU_03$s7a23UI16AsyncTransaction33_ghijklmn18BLLC5applyyyFySo10O9RefaXEfU_AA0sF0AELLCTf1nnnc_n + 125
    	23  SwiftUI                             0x00007fff2c18e374 $s7SwiftUI9ViewGraphC15syncTransaction33_D63C4EB7F2B205694B6515509E76E98BLLyyAA0F0V_ySo10AGGraphRefaXEtF03$s7a23UI16AsyncTransaction33_ghijklmn18BLLC5applyyyFySo10O9RefaXEfU_AA0sF0AELLCTf1ncn_n + 100
    	24  SwiftUI                             0x00007fff2c18e2fd $s7SwiftUI16AsyncTransaction33_D63C4EB7F2B205694B6515509E76E98BLLC5applyyyF + 141
    	25  SwiftUI                             0x00007fff2c1a6eac $sIeg_ytIegr_TR + 12
    	26  SwiftUI                             0x00007fff2c45b031 $sIeg_ytIegr_TRTA + 17
    	27  SwiftUI                             0x00007fff2c45b289 $sIeg_ytIegr_TRTA.8 + 9
    	28  SwiftUI                             0x00007fff2c45a561 $s7SwiftUI16ViewRendererHostPAAE25dispatchPostUpdateActions33_6C396F98EFDD04A6B58F2F9112448013LLyyFyyXEfU_ + 193
    	29  SwiftUI                             0x00007fff2c45a1e7 $s7SwiftUI16ViewRendererHostPAAE25dispatchPostUpdateActions33_6C396F98EFDD04A6B58F2F9112448013LLyyF + 439
    	30  SwiftUI                             0x00007fff2c45402a $s7SwiftUI16ViewRendererHostPAAE9endUpdateyyF + 154
    	31  SwiftUI                             0x00007fff2c45479d $s7SwiftUI16ViewRendererHostPAAE18performAfterUpdateyyyycF + 205
    	32  SwiftUI                             0x00007fff2c182f36 $s7SwiftUI9ViewGraphC16asyncTransaction_8mutationyAA0F0V_xtAA0D8MutationRzlFAA012InvalidatingdH0V_Tg5Tm + 294
    	33  SwiftUI                             0x00007fff2c2335fe $s7SwiftUI31AttributeInvalidatingSubscriberC010invalidateC033_986362D34F2D1941B9A0AD4E9CF57D06LLyyF + 334
    	34  SwiftUI                             0x00007fff2c233683 $s7SwiftUI31AttributeInvalidatingSubscriberC7receivey7Combine11SubscribersO6DemandV6OutputQzF + 83
    	35  SwiftUI                             0x00007fff2c233ad0 $s7SwiftUI31AttributeInvalidatingSubscriberCyxG7Combine0E0AaeFP7receiveyAE11SubscribersO6DemandV5InputQzFTW + 16
    	36  Combine                             0x00007fff23245da7 $s7Combine10SubscriberP7receiveyAA11SubscribersO6DemandV5InputQzFTj + 7
    	37  SwiftUI                             0x00007fff2c337083 $s7SwiftUI20SubscriptionLifetimeC10Connection33_584E3B65D1FB8867743A7329537CB053LLV7receivey7Combine11SubscribersO6DemandV6OutputQzF + 163
    	38  SwiftUI                             0x00007fff2c337149 $s7SwiftUI20SubscriptionLifetimeC10Connection33_584E3B65D1FB8867743A7329537CB053LLVyx_qd__G7Combine10SubscriberAahIP7receiveyAH11SubscribersO6DemandV5InputQzFTW + 9
    	39  Combine                             0x00007fff232466e3 $sTA.5 + 67
    	40  Combine                             0x00007fff2321091a $s7Combine13AnySubscriberV7receiveyAA11SubscribersO6DemandVxF + 42
    	41  Combine                             0x00007fff2321aa95 $s7Combine18PassthroughSubjectC7ConduitC5offeryyxF + 261
    	42  Combine                             0x00007fff2321b506 $s7Combine18PassthroughSubjectC4sendyyxFyAC7ConduitCyxq__GXEfU_TA + 22
    	43  Combine                             0x00007fff2321b524 $s7Combine18PassthroughSubjectC7ConduitCyxq__Gs5Error_pIggzo_AFsAG_pIegnzo_sAGR_r0_lTRTA + 20
    	44  libswiftCore.dylib                  0x00007fff507395e4 $sSTsE7forEachyyy7ElementQzKXEKF + 452
    	45  libswiftCore.dylib                  0x00007fff507b7a5d $ss26_RandomAccessCollectionBoxC8_forEachyyy7ElementQzKXEKF + 125
    	46  libswiftCore.dylib                  0x00007fff508a0f8e $ss15_AnySequenceBoxC8_forEachyyyxKXEKFTj + 14
    	47  Combine                             0x00007fff2321a949 $s7Combine18PassthroughSubjectC4sendyyxF + 457
    	48  MovieSwift                          0x0000000109fd4966 $s11SwiftUIFlux5StoreC5statexvWyycfU_ + 182
    	49  MovieSwift                          0x0000000109fd49ad $sIeg_IeyB_TR + 45
    	50  libdispatch.dylib                   0x000000010a615e28 _dispatch_call_block_and_release + 12
    	51  libdispatch.dylib                   0x000000010a616d9c _dispatch_client_callout + 8
    	52  libdispatch.dylib                   0x000000010a624e54 _dispatch_main_queue_callback_4CF + 1500
    	53  CoreFoundation                      0x00007fff23a5cbf9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    	54  CoreFoundation                      0x00007fff23a57859 __CFRunLoopRun + 2329
    	55  CoreFoundation                      0x00007fff23a56c16 CFRunLoopRunSpecific + 438
    	56  GraphicsServices                    0x00007fff37a98bb0 GSEventRunModal + 65
    	57  UIKitCore                           0x00007fff46c97bef UIApplicationMain + 1621
    	58  MovieSwift                          0x0000000109e6dabb main + 75
    	59  libdyld.dylib                       0x00007fff50fb24ad start + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    
    opened by ekazaev 4
  • App not usable in Xcode 11 Beta2 simulator

    App not usable in Xcode 11 Beta2 simulator

    Wanted to check if there is an issue on my end or if this is happening for everyone. Running the app on the emulator is painfully slow. Every touch requires 10-15 secs to be performed. I don't have a real device with iOS 13 to test it, but wanted to know if it's an app optimization issue or beta simulator issue.

    opened by cioraneanu 4
  • tvOS?

    tvOS?

    Just curious why tvOS isn't supported out of the box here by SwiftUI.

    Was this a conscious decision or were there things you wanted to do that tvOS didn't let you?

    opened by github-user001 3
  • Can't build unless you're Thomas Ricouard ;)

    Can't build unless you're Thomas Ricouard ;)

    I don't feel like expending the effort of branching and doing a PR just to fix this little project file glitch. Here you go:

    diff --git a/MovieSwift/MovieSwift.xcodeproj/project.pbxproj b/MovieSwift/MovieSwift.xcodeproj/project.pbxproj
    index a8aa808..1f912ad 100644
    --- a/MovieSwift/MovieSwift.xcodeproj/project.pbxproj
    +++ b/MovieSwift/MovieSwift.xcodeproj/project.pbxproj
    @@ -158,7 +158,7 @@
                    6953B50A22D36FF500859723 /* CustomListCoverRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomListCoverRow.swift; sourceTree = "<group>"; };
                    6953B50D22D3774E00859723 /* CustomListHeaderRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomListHeaderRow.swift; sourceTree = "<group>"; };
                    6953B51222D44F9E00859723 /* Collection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Collection.swift; sourceTree = "<group>"; };
    -               69583B4622E0561700C23048 /* MovieContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MovieContextMenu.swift; path = ../../../../../../../../../../../System/Volumes/Data/Users/thomasricouard/Documents/Glose/dev/MovieSwiftUI/MovieSwift/MovieSwift/views/shared/contextMenu/MovieContextMenu.swift; sourceTree = "<group>"; };
    +               69583B4622E0561700C23048 /* MovieContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MovieContextMenu.swift; path = MovieContextMenu.swift; sourceTree = "<group>"; };
                    695882B022ACFB5800AFABA9 /* ImageLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLoader.swift; sourceTree = "<group>"; };
                    695882B422AD008600AFABA9 /* TopRatedList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopRatedList.swift; sourceTree = "<group>"; };
                    695882B722AD01C500AFABA9 /* MovieDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieDetail.swift; sourceTree = "<group>"; };
    
    
    opened by jnutting 3
  • Use existing tab item helper method in HomeView

    Use existing tab item helper method in HomeView

    Instead of duplicating code to create Image and Text views for tab item in TabbedView, use existing tab item helper method and pass in the text string and system image name string.

    opened by kmt901 3
  • The hidden performance issue of single store, especially in NavigationView

    The hidden performance issue of single store, especially in NavigationView

    I applied your single store concept into my project and found some performance issues. Here is my example

    Background

    1. NextUpRootView is the root navigation view
    2. Click navigation item to push RaceCard. In RaceCard, fetch racing data via getRaceCard
    3. Both NextUpRootView and RaceCard have @EnvironmentObject var store: Store

    Problem

    • NextUpRootView comes useless re-rendering even I'm on RaceCard after a getRaceCard operation. This could be a performance problem if navigation view comes a big stack(views). In my application, it also comes a very strange behavior: when i'm on RaceCard page and execute getRaceCard, the app automatically pop back to NextUpRootView view;
    • @EnvironmentObject var store: Store is the evil. Because as long as our state changes, all view that have this has to be rendered again

    Code snippets

    // root view controller
    
    struct NextUpRootView: View {
        @EnvironmentObject var store: Store
        private var racing: AppState.Racing { store.appState.racing }
        ...
    
        var body: some View {
            NavigationView {
                VStack {
                    NavigationLink(destination: RaceCard(data: self.raceCardData))
        }
    }
    
    // race card
    
    struct RaceCard: View {
        
        @EnvironmentObject private var store: Store
        @ObservedObject var viewModel = RaceCardModel()
        
        init(data: VRaceCard) {
            self.viewModel.meetingId = data.meetingId
            self.viewModel.raceId = data.raceId
            self.viewModel.selectedRaceNumber = "\(data.raceNumber - 1)"
        }
    
        var body: some View {
            VStack(spacing: 0) {
                RaceTable(selectedProductGroupId: viewModel.selectedProductGroupId, raceId: viewModel.raceId)
            }
                .onReceive(viewModel.$selectedRaceNumber, perform: { _ in
                    self.getRaceCard()
                })
        }
    }
    
    extension RaceCard {
        private func getRaceCard() {
            store.dispatch(.racing(.getRacecard(raceId: viewModel.raceId)))
        }
     
    }
    opened by ghost 2
  • Click itemView in ScrollView , the app got a  crash

    Click itemView in ScrollView , the app got a crash

    Click itemView in ScrollView , the app got a crash. in MoviesHomePage grid style , click see all in MovieDetail keywords cell , click title area got a recyle push/pop then crash

    is it the iOS13's bug ?

    opened by WhityLL 2
  • Images section - MovieBackdropImage fails to render

    Images section - MovieBackdropImage fails to render

    I have noticed that Images section fails to update with proper images. Did some investigation and it seems that i.e wrapping placeholder like that:

                ZStack {
                  Text ("BUG?")
                  Rectangle()
                      .frame(maxHeight: fill ? 50 : 300)
                      .aspectRatio(500/300, contentMode: fill || !isExpanded ? .fill : .fit)
                      .foregroundColor(.gray)
                      .opacity(0.1)
                }
    

    Solves the issue, yet it's supper hacky and I have no clue, why it fails to render in first place. Any ideas?

    opened by krasi-pl 2
  • List row remains highlighted

    List row remains highlighted

    I have observed that the List row remains highlighted when we come back from detail screen as shown in Screenshot. I have tried multiple things to resolve this but didn't find any solution. Ultimately I ended up using LazyVStack inside ScrollView in my application. I have observed when we keep List inside any container like VStack, Group etc this issue happens. As in MovieSwift app it happens for Movies Tab but not for Fan Club and My Lists. simulator_screenshot_F54EBA25-FCB8-49C2-9A79-B8D014D3E09E

    opened by chitvan832 0
  • contextMenu selects whole HStack

    contextMenu selects whole HStack

    For example in PeopleRow when you press and hold on a person it selects whole hstack and when you tap on "Add to fan club" it adds first person in that hstack.

    Ekran Resmi 2020-07-10 01 03 28
    opened by bark1n9 0
  • Remove store variable for better performance

    Remove store variable for better performance

    As long as a view has a reference to global store. Any update on store from other places will force to refresh the view.

    On the other hand, in order to dispatch an action, we have to use global store within a view. So i think it's a drawback of this structure.

    opened by ghost 1
Owner
Thomas Ricouard
[Entrepreneur, iOS/Mac & Web dev] Work @Medium / @Glose Past: @google, Co-Founded @MySeeen (Share movies !) @RobinBrowser (The smart Browser).
Thomas Ricouard
Swift MovieDB App from TheMovieDB API

Sonix Aims for this project is to browse movies from TheMovieDB API, search for

Jake Round 5 Aug 8, 2022
SwiftUI MovieDB prototype app built with Xcode 11 Beta & macOS 10.15 Catalina

SwiftUI MovieDB iOS 13 App SwiftUI MovieDB prototype app built with Xcode 11 Beta & macOS 10.15 Catalina Requirements macOS 10.15 Catalina Xcode 11 Be

Alfian Losari 297 Dec 17, 2022
content for Using Combine - notes on learning Combine with UIKit and SwiftUI

SwiftUI-Notes A collection of notes, project pieces, playgrounds and ideas on learning and using SwiftUI and Combine. Changes, corrections, and feedba

Joseph Heck 1.7k Dec 27, 2022
Simple Todo Application using SwiftUI / Firebase / Redux.

Simple Todo Application using SwiftUI/Firebase/Redux/Combine. Light _ _ _ _ Dark _ _ _ Feature Use SwiftUI fully. Use Firebase. Authentication Cloud F

Suguru Kishimoto 337 Dec 25, 2022
An example APOD app with SwiftUI and Combine using NASA API

SwiftUI-APOD An example Astronomy Picture of the Day(APOD) application using SwiftUI and Combine under iOS 13 Requirement Xcode 11 macOS 10.15 Catalin

Liang Yi 22 Oct 16, 2022
A to-do list app using SwiftUI and combine with restful api.

Todo Combine SwiftUI It's an experiment project for the brand new SwiftUI + Combine + restful API with dark mode Build follow restfult to-do-api to ru

jamfly 14 Feb 21, 2022
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. ?? Requirements Swift5.1 Beta Xcode11.0

Ryo Aoyama 436 Jan 5, 2023
Sample iOS project built by SwiftUI + MVVM and Combine framework using GitHub API

SwiftUI-MVVM One of the biggest idea for having MVVM is that most of data flow can be testable. Data binding in view layer by SwiftUI is awesome. Howe

Yusuke Kita 592 Jan 2, 2023
small iOS & ipadOS application written in SwiftUI and Combine, that fetches twitter users and tweets using Twitter's api

HomeTwitter Small iOS & ipadOS application written in SwiftUI and Combine, that fetches twitter users and tweets using Twitter's api. This is just a s

Sorin Miroiu 1 May 13, 2022
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. ?? Requirements Swift5.1 Beta Xcode11.0

Ryo Aoyama 435 Dec 28, 2022
A Flutter tourism app that is backed-by Redux, shows animations, internationalization (i18n, English <=> Arabic), ClipPath, and fonts

A Flutter tourism app that is backed-by Redux, shows animations, internationalization (i18n, English <=> Arabic), ClipPath, and fonts. YouTube demo I

Abdulmomen Kadum عبدالمؤمن كاظم 277 Dec 28, 2022
Redux abstractions for BetterMe projects and iOS community

ReduxCore Redux abstractions on Swift for BetterMe projects and iOS community Installation CocoaPods You can install ReduxCore via CocoaPods by adding

BetterMe 15 Mar 24, 2022
Fast Multi-store Redux-like architecture for iOS/OSX applications

Highway Highway is implementation of Redux-like architecture pattern using Swift. If you were looking for a something like this: TEA (The Elm Architec

Dmitrii Cooler 14 Dec 9, 2022
Aplikasi CrypTraces adalah MacOS Widget Crypto Tracker dengan SwiftUI, Combine & Cocoa Framework, dan WebSocket & CoinCap API

Aplikasi CrypTraces adalah MacOS Widget Crypto Tracker dengan SwiftUI, Combine & Cocoa Framework, dan WebSocket & CoinCap API. Aplikasi ini berbentuk Widget di Menu Bar MacOS dengan menampilkan beberapa Crypto Currency seperti Bitcoin (BTC), Ethereum (ETH), Dogecoin (DOGE), Monero (XMR), dan Litecoin (LTC).

DK 6 Aug 1, 2022
iOS app that detects LaTeX symbols from drawings. Built using PencilKit, SwiftUI, Combine and CoreML for iOS 14 and macOS 11.

DeTeXt Finding the symbol you want to use in LaTeX can be hard since you can't memorize all the possible commands and packages for every symbol you mi

Venkat 73 Dec 8, 2022
A Simple ToDo app developed using SwiftUI, Combine and Coredata

SwiftUI_Tasks Tasks is simple ToDo app developed using SwiftUI and Coredata which having features like Add,Delete,Rearrange and send notification base

Shankar Madeshvaran 77 Dec 18, 2022
Github repo search with using mvvm-c and clean architecture and using combine swift

GitSearchWithMVVM-C-CleanArchitecture Github repo search with using mvvm-c and clean architecture and using combine swift. Content Overview How To Run

Muhammad Qasim Majeed 1 Mar 16, 2022
Paginated endless scroll using the SwiftUI and Combine frameworks

Article related to this project Infinite List Scroll with SwiftUI and Combine. InfiniteListSwiftUI A sample project showcasing how to build an infinit

Vadim Bulavin 69 Nov 16, 2022