How to make Chrome extension with Nextjs 13

Issue #940 We can develop Nextjs 13 apps and export it to a Chrome extension. Start by init the project npx create-next-app@latest Here is the project structure with app router and not using src directory. I put an extension to the root of the project, where we can copy over the generated out folder extension - manifest.json app - page.tsx public - images Here is my script to build and copy over generated out and public images to extension folder...

August 2, 2023 · 1 min · 190 words · Khoa

How to scale image fill without affect layout in SwiftUI

Issue #939 Instead of letting the Image decide the size, we can put it as background or overlay. I use clipped and contentShape to avoid the fill image obscuring touch event Color.clear .frame(height: 100) .overlay { AsyncImage(url: item.imageUrl) { image in image .resizable() .scaledToFill() } placeholder: { ProgressView() } } .clipped() .contentShape(Rectangle())

July 30, 2023 · 1 min · 52 words · Khoa

How to move Core Data database to AppGroup folder

Issue #938 To let app and extension to talk to the same database, we need to use AppGroup. Here is how to use replacePersistentStore Replaces one persistent store with another actor DatabaseMigrator { @AppStorage("DatabaseMigrator.hasMigrated") var hasMigrated = false func migrateIfNeeded() { guard !hasMigrated else { return } migrate() hasMigrated = true } private func migrate() { let oldContainer = NSPersistentCloudKitContainer(name: "Bookmarks") guard let oldStoreUrl = oldContainer.persistentStoreDescriptions.first?.url, let newStoreUrl = Constants.appGroup.folderUrl?.appendingPathComponent(oldContainer.name + "....

July 30, 2023 · 1 min · 183 words · Khoa

How to read write files to iCloud Drive

Issue #937 First, you need to enable iCloud Documents capability. Go to target settings -> Signing & Capabilities -> iCloud ` Then inside your Info.plist, add this with your iCloud identifier and app name <key>NSUbiquitousContainers</key> <dict> <key>iCloud.com.onmyway133.PastePal</key> <dict> <key>NSUbiquitousContainerIsDocumentScopePublic</key> <true/> <key>NSUbiquitousContainerName</key> <string>PastePal</string> <key>NSUbiquitousContainerSupportedFolderLevels</key> <string>Any</string> </dict> </dict> To access to your iCloud Drive folder, we use FileManager to retrieve the folder. Returns the URL for the iCloud container associated with the specified identifier and establishes access to that container....

July 28, 2023 · 2 min · 296 words · Khoa

How to make reusable Button component in React

Issue #936 From https://github.com/antonioerdeljac/next13-spotify import { forwardRef } from "react"; import { twMerge } from "tailwind-merge"; export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {} const Button = forwardRef<HTMLButtonElement, ButtonProps>(({ className, children, disabled, type = 'button', ...props }, ref) => { return ( <button type={type} className={twMerge( ` w-full rounded-full bg-green-500 border border-transparent px-3 py-3 disabled:cursor-not-allowed disabled:opacity-50 text-black font-bold hover:opacity-75 transition `, disabled && 'opacity-75 cursor-not-allowed', className )} disabled={disabled} ref={ref} {...props} > {children} </button> ); }); Button....

July 21, 2023 · 1 min · 78 words · Khoa

How to make fullstack web app

Issue #935 I prefer UI Component that works with Nextjs and Tailwind CSS UI Libraries https://ui.shadcn.com/ https://daisyui.com/ https://www.radix-ui.com/ 👍 https://preline.co/ https://nextui.org/ https://mantine.dev/ https://chakra-ui.com/ https://getbootstrap.com/ https://bulma.io/ https://www.floatui.com/ Tailwind CSS templates https://preline.co/ https://tailwindui.com/ https://flowbite.com/ Icon Library https://github.com/lucide-icons/lucide https://github.com/react-icons/react-icons Lib https://github.com/timolins/react-hot-toast https://github.com/pmndrs/zustand https://github.com/react-hook-form/react-hook-form https://github.com/sindresorhus/query-string https://github.com/davidhu2000/react-spinners https://github.com/lukeed/clsx https://github.com/pacocoursey/next-themes https://github.com/colinhacks/zod https://github.com/remarkjs/react-markdown https://github.com/tameemsafi/typewriterjs https://github.com/lodash/lodash https://github.com/dcastil/tailwind-merge https://ahooks.js.org/ https://zod.dev/ Services Support https://crisp.chat Ref https://github.com/antonioerdeljac/next13-spotify https://github.com/shadcn-ui/taxonomy https://github.com/steven-tey/dub https://github.com/Elliott-Chong/quizmify

July 20, 2023 · 1 min · 59 words · Khoa

How to use keychain in Swift

Issue #934 There are a few keychain wrappers around but for simple needs, you can write it yourself Here is a basic implementation. I use actor to go with async/await, and a struct KeychainError to contain status code in case we want to deal with error cases. accessGroup is to define kSecAttrAccessGroup to share keychain across your apps public actor Keychain { public struct KeychainError: Error { let status: OSStatus } let service: String let accessGroup: String?...

July 20, 2023 · 2 min · 389 words · Khoa

How to handle route case sensitivity in Nextjs

Issue #933 By default, Nextjs route is case sensitive, so localhost:3000/About and localhost:3000/about are different routes. To make uppercase routes become lowercase routes, we can add a middleware.tsx file to the src so it is same level as pages import { NextResponse, NextRequest } from "next/server" const Middleware = (req: NextRequest) => { if (req.nextUrl.pathname === req.nextUrl.pathname.toLowerCase()) { return NextResponse.next() } return NextResponse.redirect( new URL(req.nextUrl.origin + req.nextUrl.pathname.toLowerCase()) ) } export default Middleware

July 17, 2023 · 1 min · 72 words · Khoa

How to make share and action extension in iOS

Issue #932 Add Share extension and Action extension respectively in Xcode. We can use the same code to both extension SwiftUI I usually make a ShareView in SwiftUI with ShareViewModel to control the logic struct ShareView: View { @ObservedObject var vm: ShareViewModel var body: some View { NavigationStack(path: $vm.routes) { List {} } } } In ShareViewController, we can just conform to UIViewController and add our SwiftUI view as child view controller...

July 12, 2023 · 2 min · 264 words · Khoa

AppStore screenshots size checklist

Issue #931 AppStore screenshots Screenshot specifications iPhone 6.7" Portrait 1290 x 2796 iPhone 6.5" Portrait 1242 x 2688 In-App Purchase screenshots In-app purchase information iOS 640 x 920 tvO 1920 x1080 pixels macOS 1280 x 800 pixels

July 12, 2023 · 1 min · 37 words · Khoa

How to use AppIntents in iOS 16

Issue #930 AppIntents Declare AppShortcutsProvider, note that appShortcuts uses @AppShortcutsBuilder syntax import AppIntents struct OurShortcutsProvider: AppShortcutsProvider { static var shortcutTileColor: ShortcutTileColor = .lightBlue @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { AppShortcut(intent: AskIntent(), phrases: [ "Hey Joy", "Ask \(.applicationName)" ]) } } We can create an app intent in code import AppIntents import OpenAI struct AskIntent: AppIntent { static var title: LocalizedStringResource = "Hey Joy" static var description: IntentDescription = "Ask me anything" @Parameter(title: "Prompt") var prompt: String?...

July 11, 2023 · 1 min · 195 words · Khoa

How to press and hold button in SwiftUI

Issue #929 We can use ButtonStyleConfiguration to detect isPressed state struct RecordButton: View { var body: some View { Button { } label: { Image(systemSymbol: .micFill) } .buttonStyle(RecordButtonStyle()) } } private struct RecordButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .background { if configuration.isPressed { Circle() .fill(Color.pink) .frame(square: 30) } } .onChange(of: configuration.isPressed) { isPressed in print("isPressed", isPressed) } } } Alternatively, you can just use a DragGesture...

July 10, 2023 · 1 min · 147 words · Khoa

How to copy text to the clipboard in Swift

Issue #928 For iOS, use string Setting this property replaces all current items in the pasteboard with the new item. If the first item has no value of the indicated type, nil is returned. let pasteboard = UIPasteboard.general pasteboard.string = "hello world" For Mac, use clearContents first Clears the existing contents of the pasteboard, preparing it for new contents. This is the first step in providing data on the pasteboard....

July 4, 2023 · 1 min · 106 words · Khoa

How to add launch screen in SwiftUI project

Issue #927 For a plain SwiftUI project, Xcode will generate a Info.plist file once you start to edit the Info tab in target settings. There is a Launch screen (UILaunchScreen) key by default. It has a UILaunchScreen which we don’t need to so we can safely remove it. What we need is a background color and an image. Click the + button next to Launch Screen and type to add Image Name (UIImageName) and Background color (UIColorName)...

July 4, 2023 · 1 min · 187 words · Khoa

How to create UserDefaults property wrapper in Swift

Issue #926 Like AppStorage, we can make a custom UserDefaults property wrapper that conforms to DynamicProperty @propertyWrapper public struct UserDefault<Value>: DynamicProperty { @State private var value: Value let key: String let store: UserDefaults public init( wrappedValue: Value, _ key: String, store: UserDefaults = .standard ) { self.key = key self.store = store let value = (store.object(forKey: key) as? Value) ?? wrappedValue self._value = State(wrappedValue: value) } public var wrappedValue: Value { get { value } nonmutating set { store....

July 3, 2023 · 1 min · 105 words · Khoa

How to encrypt using CryptoKit in Swift

Issue #925 Use AES.GCM method with 128 bits key import CryptoKit public extension Optional { func tryUnwrap() throws -> Wrapped { if let value = self { return value } else { throw NSError(domain: "", code: 0) } } } public struct Crypto { static func encrypt(input: Data, key: String) -> Data { do { let keyData = Data(key.data(using: .utf8)!.prefix(32)) let key = SymmetricKey(data: keyData) let sealed = try AES.GCM.seal(input, using: key) return try sealed....

July 3, 2023 · 1 min · 162 words · Khoa

How to use NavigationSplitView and NavigationStack in SwiftUI

Issue #924 Note Navigation state needs to be in the container of NavigationSplitView for changes to propagate Need to use WindowGroup for navigation bar to work NavigationSplitView the navigation split view coordinates with the List in its first column, so that when people make a selection, the detail view updates accordingly. Programmatic changes that you make to the selection property also affect both the list appearance and the presented detail view...

June 30, 2023 · 1 min · 161 words · Khoa

How to style NavigationLink in macOS

Issue #923 NavigationLink on Mac applies the default button style. We can style it using ButtonStyle, here to use plain style we can just NavigationLink(value: DetailRoute.books) { BooksView() } .buttonStyle(.plain)

June 28, 2023 · 1 min · 30 words · Khoa

SwiftUI EnvironmentValues

Issue #922 EnvironmentValues Views in SwiftUI can react to configuration information that they read from the environment using an Environment property wrapper Updated for iOS 17

June 21, 2023 · 1 min · 26 words · Khoa

How to make TextField Stepper in SwiftUI

Issue #921 Use HStack with TextField and a little extension extension Binding where Value == Int { var toString: Binding<String> { Binding<String>( get: { "\(wrappedValue)" }, set: { wrappedValue = Int($0) ?? 0 } ) } } struct TextFieldStepper: View { @Binding var value: Int var body: some View { HStack(spacing: 0) { TextField("", text: $value.toString) .textFieldStyle(.roundedBorder) .frame(width: 50) Stepper("", value: $value) } } }

June 20, 2023 · 1 min · 65 words · Khoa