How to test push notifications in simulator and production iOS apps

Issue #682 After has recently reminded about his updating APNs provider API which makes me realised a lot has changed about push notifications, both in terms of client and provider approach. The HTTP/2-based Apple Push Notification service (APNs) provider API lets you take advantage of great features, such as authentication with a JSON Web Token, improved error messaging, and per-notification feedback. If you send push notifications with the legacy binary protocol, we strongly recommend upgrading to the APNs provider API....

October 11, 2020 · 12 min · 2474 words · Khoa

How to style multiline Text in SwiftUI for macOS

Issue #681 Only need to specify fixedSize on text to preserve ideal height. The maximum number of lines is 1 if the value is less than 1. If the value is nil, the text uses as many lines as required. The default is nil. Text(longText) .lineLimit(nil) // No need .fixedSize(horizontal: false, vertical: true) If the Text is inside a row in a List, fixedSize causes the row to be in middle of the List, workaround is to use ScrollView and vertical StackView....

October 7, 2020 · 1 min · 98 words · Khoa

How to clear List background color in SwiftUI for macOS

Issue #680 For List in SwiftUI for macOS, it has default background color because of the enclosing NSScrollView via NSTableView that List uses under the hood. Using listRowBackground also gives no effect The solution is to use a library like SwiftUI-Introspect import Introspect extension List { func removeBackground() -> some View { return introspectTableView { tableView in tableView.backgroundColor = .clear tableView.enclosingScrollView!.drawsBackground = false } } } then List { ForEach(items) { item in // view here } } ....

October 4, 2020 · 1 min · 204 words · Khoa

How to avoid reduced opacity when hiding view with animation in SwiftUI

Issue #679 While redesigning UI for my app Push Hero, I ended up with an accordion style to toggle section. It worked great so far, but after 1 collapsing, all image and text views have reduced opacity. This does not happen for other elements like dropdown button or text. extension View { func sectionBackground(_ title: String, _ shows: Binding<Bool>) -> some View { VStack(alignment: .leading) { HStack { Text(title.uppercased()) Spacer() if shows !...

October 1, 2020 · 1 min · 141 words · Khoa

How to dynamically add items to VStack from list in SwiftUI

Issue #678 Use enumerated to get index so we can assign to item in list. Here is how I show list of device tokens in my app Push Hero private var textViews: some View { let withIndex = input.deviceTokens.enumerated().map({ $0 }) let binding: (Int, Input.DeviceToken) -> Binding<String> = { index, token in Binding<String>( get: { token.token }, set: { self.input.deviceTokens[index].token = $0 } ) } return VStack { ForEach(withIndex, id: \....

October 1, 2020 · 1 min · 82 words · Khoa

How to unwrap Binding with Optional in SwiftUI

Issue #677 The quick way to add new properties without breaking current saved Codable is to declare them as optional. For example if you use EasyStash library to save and load Codable models. import SwiftUI struct Input: Codable { var bundleId: String = "" // New props var notificationId: String? This new property when using dollar syntax $input.notificationId turn into Binding with optional Binding<Strting?> which is incompatible in SwiftUI when we use Binding....

September 29, 2020 · 1 min · 136 words · Khoa

How to make custom toggle in SwiftUI

Issue #676 I’ve used the default SwiftUI to achieve the 2 tab views in SwiftUI. It adds a default box around the content and also opinionated paddings. For now on light mode on macOS, the unselected tab has wrong colors. The way to solve this is to come up with a custom toggle, that we can style and align the way we want. Here is how I did for my app Push Hero...

September 29, 2020 · 1 min · 195 words · Khoa

How to use Binding in function in Swift

Issue #675 Use wrappedValue to get the underlying value that Binding contains extension View { func addOverlay(shows: Binding<Bool>) -> some View { HStack { self Spacer() } .overlay( HStack { Spacer() SmallButton( imageName: "downArrow", tooltip: shows.wrappedValue ? "Collapse" : "Expand", action: { shows.wrappedValue.toggle() } ) .rotationEffect(.radians(shows.wrappedValue ? .pi : 0)) } ) } }

September 25, 2020 · 1 min · 54 words · Khoa

How to use HSplitView to define 3 panes view in SwiftUI for macOS

Issue #674 Specify minWidth to ensure miminum width, and use .layoutPriority(1) for the most important pane. import SwiftUI struct MainView: View { @EnvironmentObject var store: Store var body: some View { HSplitView { LeftPane() .padding() .frame(minWidth: 200, maxWidth: 500) MiddlePane(store: store) .padding() .frame(minWidth: 500) .layoutPriority(1) RightPane() .padding() .frame(minWidth: 300) } .background(R.color.background) } }

September 23, 2020 · 1 min · 53 words · Khoa

How to draw arc corner using Bezier Path

Issue #673 To draw rounded 2 corners at top left and top right, let’s start from bottom left let path = UIBezierPath() // bottom left path.move(to: CGPoint(x: 0, y: bounds.height)) // top left corner path.addArc(withCenter: CGPoint(x: radius, y: radius), radius: radius, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 3 / 2, clockwise: true) // top right corner path.addArc(withCenter: CGPoint(x: bounds.width - radius, y: radius), radius: radius, startAngle: CGFloat.pi * 3 / 2, endAngle: 0, clockwise: true) // bottom right path....

September 15, 2020 · 1 min · 86 words · Khoa

How to stitch and sort array in Swift

Issue #672 Supposed we want to stitch magazines array into books array. The requirement is to sort them by publishedDate, but must keep preferredOrder of books. One way to solve this is to declare an enum to hold all possible cases, and then do a sort that check every possible combination struct Book { let preferredOrder: Int let publishedDate: Date } struct Magazine { let publishedDate: Date } enum StitchItem { case book(Book) case magazine(Magazine) } func stitch(_ books: [Book], magazines: [Magazine]) -> [StitchItem] { let items = books....

August 28, 2020 · 2 min · 304 words · Khoa

How to make dynamic font size for UIButton

Issue #671 Use adjustsFontForContentSizeCategory A Boolean that indicates whether the object automatically updates its font when the device’s content size category changes. If you set this property to YES, the element adjusts for a new content size category on a UIContentSizeCategoryDidChangeNotification. button.titleLabel?.adjustsFontForContentSizeCategory = true button.backgroundColor = UIColor.green button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .title1) label.adjustsFontForContentSizeCategory = true label.backgroundColor = UIColor.yellow label.font = UIFont.preferredFont(forTextStyle: .title1) However it seems view (UIButton or UILabel) size is the same, just the inner text increases in size....

August 14, 2020 · 1 min · 95 words · Khoa

How to test for view disappear in navigation controller

Issue #670 To test for viewWillDisappear during UINavigationController popViewController in unit test, we need to simulate UIWindow so view appearance works. final class PopTests: XCTestCase { func testPop() { let window = UIWindow(frame: UIScreen.main.bounds) let navigationController = UINavigationController() window.rootViewController = navigationController let viewController = DetailViewController() navigationController.viewControllers = [ UIViewController(), viewController ] window.makeKeyAndVisible() let expectation = XCTestExpectation() navigationController.popViewController(animated: false) DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { XCTAssertTrue(viewController.wasDismissed) expectation.fulfill() } wait(for: [expectation], timeout: 1) } } class DetailViewController: UIViewController { override func viewWillDisappear(_ animated: Bool) { super....

August 6, 2020 · 1 min · 96 words · Khoa

How to use useEffect in React hook

Issue #669 Specify params as array [year, id], not object {year, id} const { year, id } = props useEffect(() => { const loadData = async () => { try { } catch (error) { console.log(error) } } listenChats() }, [year, id]) } Hooks effect https://reactjs.org/docs/hooks-effect.html https://reactjs.org/docs/hooks-reference.html#useeffect By default, it runs both after the first render and after every update. This requirement is common enough that it is built into the useEffect Hook API....

June 17, 2020 · 1 min · 126 words · Khoa

How to sign in with apple for web with firebase

Issue #668 Authenticate Using Apple with JavaScript Use Firebase JS SDK https://firebase.google.com/docs/auth/web/apple Configure Sign in with Apple for the web https://help.apple.com/developer-account/#/dev1c0e25352 Go to Certificates, Identifiers & Profiles -> Identifier create 2 ids: App ID and Service ID For example: I have App ID com.onmyway133.myapp and Service ID com.onmyway133.myweb Remember that to view App ID or Service ID, there’s dropdown menu on the right For App ID, enable Associated Domains Sign In with Apple: Enable it as Primary App ID For Service ID, use firebase callback url...

June 16, 2020 · 1 min · 199 words · Khoa

How to use firebase cloud functions

Issue #667 Use node 10 Edit package.json "engines": { "node": "10" }, Secret key Go to settings/serviceaccounts/adminsdk, download secret key in form of json and place it in lib/config.json const serviceAccount = require('./config.json') admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://my-app-4b968.firebaseio.com" }) Local serve This builds and spins up emulator to test npm run serve CORS https://stackoverflow.com/questions/42755131/enabling-cors-in-cloud-functions-for-firebase https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html response.set('Access-Control-Allow-Origin', '*'); var cors = require('cors'); // my function var helloFn = function helloFn(req, res) { res....

June 14, 2020 · 1 min · 104 words · Khoa

How to deploy with create react app

Issue #666 Direct url 200.html https://stackoverflow.com/questions/44491184/react-router-does-not-work-in-production-and-surge-deployments Support for client-side routing: https://create-react-app.dev/docs/deployment/#netlify /* /index.html 200 Serving the Same Build from Different Paths "homepage": ".", Updated at 2020-06-14 19:48:16

June 14, 2020 · 1 min · 27 words · Khoa

How to go back to home in React

Issue #665 Usually in header we have logo that takes user back to the home page // index.js import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom' <Router> <Switch> <Route exact path="/"> <Home /> </Route> </Router> // Header.js import { useHistory } from 'react-router-dom' const history = useHistory() <a class="navbar-item" onClick={() => { history.push('/') }}>

June 13, 2020 · 1 min · 57 words · Khoa

How to format date in certain timezone with momentjs

Issue #664 Use moment-timezone https://momentjs.com/timezone/docs/ npm install moment-timezone // public/index.html <script src="moment.js"></script> <script src="moment-timezone-with-data.js"></script> Need to import from moment-timezone, not moment import moment from 'moment-timezone' moment(startAt).tz('America/Los_Angeles').format('MMMM Do YYYY')

June 13, 2020 · 1 min · 28 words · Khoa

How to style video js

Issue #663 /** @jsx jsx */ import { css, jsx } from '@emotion/core' import React from 'react'; import videojs from 'video.js' export default class VideoPlayer extends React.Component { componentDidMount() { // instantiate Video.js this.player = videojs(this.videoNode, this.props, function onPlayerReady() { console.log('onPlayerReady', this) }); } // destroy player on unmount componentWillUnmount() { if (this.player) { this.player.dispose() } } // wrap the player in a div with a `data-vjs-player` attribute // so videojs won't create additional wrapper in the DOM // see https://github....

June 12, 2020 · 1 min · 121 words · Khoa