{ "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "items": [ { "originId": "tag:blogger.com,1999:blog-8954608646904080796.post-6562845574025332924", "fingerprint": "57441f5a", "thumbnail": [ { "url": "https://1.bp.blogspot.com/-nSjfvVEYsOE/XZ6cEycVw3I/AAAAAAAADTI/UMdV1Seh7R8c0GdV2RgwjuAoJLW47it1gCLcBGAsYHQ/s72-c/074.jpg", "width": 72, "height": 72 } ], "id": "v0v+7Ya8tssIZvd3/pcnFRr3HwvY/5YK3FGc2t65c0Y=_16db6126dbf:685a:d4506071", "updated": 1570675865985, "author": "Edward Feser", "alternate": [ { "href": "http://edwardfeser.blogspot.com/2019/10/transubstantiation-and-hylemorphism.html", "type": "text/html" } ], "crawled": 1570717724095, "title": "Transubstantiation and hylemorphism", "published": 1570675860000, "origin": { "streamId": "feed/http://edwardfeser.blogspot.com/feeds/posts/default", "htmlUrl": "http://edwardfeser.blogspot.com/", "title": "Edward Feser" }, "content": { "direction": "ltr", "content": "
One of the key themes of the early modern philosophers\u2019 revolt against Scholasticism was a move away from an Aristotelian hylemorphist conception of the nature of physical substance to some variation or other of the mechanical philosophy.\u00a0 The other day I was asked a very interesting question: Can transubstantiation be formulated in terms of a mechanistic conception of physical substance rather than a hylemorphic one?\u00a0 My answer was that I would not peremptorily say that it cannot be, but that the suggestion certainly raises serious philosophical and theological problems.

Here\u2019s why.\u00a0 Hylemorphism in its most straightforward version roughly agrees with common sense about which of the things of everyday experience are distinct substances, which are different parts of the same substance, and which are aggregates rather than true substances.\u00a0 For example, it would say that a stone, a tree, and a dog are all distinct substances from one another; that a particular dog\u2019s nose and its right front leg are different parts of the same substance rather than distinct substances; and that a pile of stones is an aggregate rather than a substance in its own right.\u00a0 Of course, use of the term \u201csubstance\u201d in the technical Aristotelian sense isn\u2019t part of common sense, but even untutored common sense would surely involve the supposition that a stone, a tree, and a dog are all distinct things or objects, that the nose and leg of the dog are parts of a larger thing or object rather than separate things or objects, and that a pile of stones is a bunch of things or objects rather than a single object.\u00a0 At least to that extent, common sense would more or less agree with what I am calling a straightforward version of hylemorphism. \u00a0(See chapter 3 of Scholastic Metaphysics for exposition and defense of the hylemorphist account of substance.)

Now, the mechanical world picture that pushed aside the hylemorphist model tended radically to revise the common sense understanding of physical objects in one of two general ways, depending on how mechanism was spelled out.\u00a0 It reduced ordinary physical objects either to mere aggregates of their innumerably many component parts, or to mere modes of some larger blob of which theywere the parts.

Descartes and Spinoza essentially took the latter option.\u00a0 Though Descartes is often described as positing a plurality of extended substances alongside the plurality of thinking substances, his considered view seemed to be that strictly speaking, there is only a single extended substance, of which the ordinary objects of our experience are merely modifications.\u00a0 Spinoza more famously took such a position (or rather, he took it that Deus sive Naturawas the one substance of which the ordinary physical objects of our experience are all modes).\u00a0 On this view, a stone, a tree, and a dog are not really distinct substances, but merely distinct aspects of one and the same substance \u2013 in something like the way common sense regards the color, weight, and shape of a stone to be mere modes of one and the same object, the stone.

Atomist and corpuscularian versions of the mechanical philosophy went in the other direction.\u00a0 They essentially make either atoms or corpuscles the true substances, and ordinary objects mere aggregates of these purported substances.\u00a0 Just as a pile of rocks is not a true substance but merely a collection of substances (or as the hylemorphist would say, being a pile of rocks is a merely accidental form rather than a substantial form), so too a stone, a tree, or a dog is on this view merely a collection of particles.\u00a0 In effect, the particles are the true substances, and the stone, tree, or dog is like the pile \u2013 a relatively superficial arrangement of metaphysically more fundamental entities.

So, to come to transubstantiation, the idea, of course, is that in the Eucharist, while the accidents of bread and wine remain, the substance of bread and wine are miraculously replaced with that of Christ.\u00a0 Suppose, then, that we were to adopt Descartes\u2019 version of the mechanical philosophy, on which there is just one big physical substance underlying all the things ordinary perceptual experience reveals to us.\u00a0 That would entail that the substance that underlies the accidents of bread and wine that are about to be consecrated is the very same substance as that which underlies stones, trees, dogs, cats, human bodies, apples, oranges, the sun, the moon, water, lead, gold, and every other thing we see, hear, taste, touch, or smell.\u00a0

But in that case, when transubstantiation occurs, it is not just the substance underlying the accidents of bread and wine that is replaced, but the substance underlying all of these other things too.\u00a0 In other words, after transubstantiation occurs, it is really the body and blood of Christ that underlies what we perceive as stones, trees, dogs, cats, human bodies, the sun, the moon, water, etc.!\u00a0 Everything in the physical world would be transubstantiated.\u00a0 We would be left with a kind of pantheism.\u00a0 Absolutely every physical thing would have to treated with the same reverence that the Eucharist is, because every physical thing would be the Eucharist!

Another bizarre implication of this is that transubstantiation could occur only once.\u00a0 For only at the first time it occurs is the one physical substance replaced by that of Christ.\u00a0 If a priest were ever to try to consecrate bread and wine again, he would fail, because there is no longer any physical substance there to be replaced.\u00a0 It is alreadythe body and blood of Christ.

Suppose we went the other route, that of either atomism or corpuscularianism.\u00a0 Then, like stones, trees, and dogs, bread and wine would not be true substances but merely accidental collections of innumerably many true substances.\u00a0 They would be like a pile of rocks, only instead it would be fundamental particles (atoms or corpuscles, depending on your favored version of the mechanical philosophy) that would be piled up.\u00a0 But in that case, exactly what is the substance that is replaced when transubstantiation occurs?\u00a0 Neither the substance of the bread nor that of the wine can be what is replaced, because on this view they just aren\u2019ttrue substances in the first place.\u00a0

Should we say that it is each particle that makes up the aggregate that is transubstantiated (just as Catholic theology allows that many hosts at a time may be consecrated at Mass)?\u00a0\u00a0 But there are several problems with that suggestion.\u00a0 The first is that it is hard to know how to give a principled answer to the question what the boundaries are between those particles that make up the aggregate and those that are not part of it \u2013 and thus between those particles that are transubstantiated, and those that are not.\u00a0 The reason is that the boundaries of an aggregate are much less well defined than those of a substance.\u00a0 Is a stone that is two millimeters away from a pile of stones itself part of the pile or not?\u00a0 And is a particle that falls from the host part of that (purported) aggregate of particles or not?\u00a0

If we think of the host on the model of an Aristotelian substance, then we can say that a fallen particle is part of the host, like a body part that has been severed, as it were.\u00a0 But, again, if instead we think in terms of the model of a pile of stones or some other aggregate, the answer isn\u2019t as clear.

A second problem is that in Catholic theology, not any old matter can be used when consecrating the Eucharist.\u00a0 It has to be bread and wine, specifically.\u00a0 But on the interpretation under consideration, according to which bread and wine are not true substances, it is really the particles (either atoms or corpuscles) that are being consecrated.\u00a0 And the atoms or corpuscles that make up bread and wine are essentially the same as those that make up everything else (just as the stones that make up a pile can be essentially of the same type as those that are used instead to make up a wall).\u00a0 In that case, though, it would be hard to see why there is anything special about bread and wine.\u00a0 Why couldn\u2019t any old physical thing be consecrated, if every physical thing is essentially just the same kind of stuff in relatively superficial differences of configuration?

A third problem is that canon law says that a Catholic ought to receive communion at most only once (or in some special circumstances, perhaps twice) a day.\u00a0 But on the interpretation under consideration, one would in effect be consuming millions of consecrated hosts insofar as each of the millions of particles that make up what common sense regards as a single host was being independently transubstantiated.

Perhaps such problems could be solved, though I am doubtful.\u00a0 Anyway, the issue illustrates the unexpected implications that philosophical assumptions can have for theology.\u00a0 (And thus the caution that any Catholic ought to exercise before embracing philosophical novelties.\u00a0 The Scholastics knew what they were doing.)
" }, "visual": { "url": "https://cdn.vox-cdn.com/thumbor/qEtBNTmNKQvUro7McqHPXL-2OOM=/0x0:6720x4480/1310x873/cdn.vox-cdn.com/uploads/chorus_image/image/59664621/marshall_majorIII_aniconinthemaking_product_rgb_highres_2.0.jpg", "width": 1310, "height": 878, "contentType": "image/jpeg" }, "unread": false, "readTime": 3562, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815", "label": "Macintosh" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/fbdcd69b-7e27-4b6a-bfed-6584b944155d", "label": "\ud83e\udd1e\ud83c\udffb\ud83e\udd1e\ud83c\udffb\ud83e\udd1e\ud83c\udffb" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1572500351314 }, { "keywords": [ "Xcode" ], "originId": "https://nshipster.com/metrickit", "recrawled": 1572363511019, "updateCount": 2, "fingerprint": "9be1d5cd", "id": "CmHb1hXBWguYpGAhzgwJM9xvPVSYJFbt7KLqF3nqYQ0=_16df9da832d:14579:d4506071", "updated": 1571641200000, "author": "Mattt", "summary": { "direction": "ltr", "content": "

At WWDC this year, Apple announced a coordinated effort between Xcode 11 and iOS 13 to bring new insights to developers about how their apps are performing in the field.

" }, "alternate": [ { "href": "http://feedproxy.google.com/~r/NSHipster/~3/o2-j6xKjBrA/", "type": "text/html" } ], "canonical": [ { "href": "https://nshipster.com/metrickit/", "type": "text/html" } ], "crawled": 1571854910253, "title": "MetricKit", "published": 1571641200000, "origin": { "streamId": "feed/http://feeds.feedburner.com/NSHipster", "htmlUrl": "https://nshipster.com/", "title": "NSHipster" }, "content": { "direction": "ltr", "content": "

As an undergraduate student,\nI had a radio show called\n\u201cGoodbye, Blue Monday\u201d\n(I was really into Vonnegut at the time).\nIt was nothing glamorous \u2014\njust a weekly, 2-hour slot at the end of the night\nbefore the station switched into automation.

\n

If you happened to be driving through the hills of Pittsburgh, Pennsylvania\nlate at night with your radio tuned to\nWRCT 88.3,\nyou\u2019d have heard an eclectic mix of\nContemporary Classical,\nAcid Jazz,\nItalian Disco, and\nBebop.\nThat, and the stilting, dulcet baritone of\na college kid doing his best impersonation of\nTony Mowod.

\n

Sitting there in the booth,\nwaiting for tracks to play out before launching into an\nFCC-mandated\nPSA\nor on-the-hour\nstation identification,\nI\u2019d wonder:\nIs anyone out there listening?\nAnd if they were, did they like it?\nI could\u2019ve been broadcasting static the whole time and been none the wiser.

\n

The same thoughts come to mind whenever I submit a build to App Store Connect\u2026\nbut then I\u2019ll remember that, unlike radio,\nyou can actually know these things!\nAnd the latest improvements in Xcode 11 make it easier than ever\nto get an idea of how your apps are performing in the field.

\n

We\u2019ll cover everything you need to know in this week\u2019s NSHipster article.\nSo as they say on the radio:\n\u201cDon\u2019t touch that dial (it\u2019s got jam on it)\u201d.

\n
\n

MetricKit is a new framework in iOS 13\nfor collecting and processing battery and performance metrics.\nIt was announced at WWDC this year\nalong with XCTest Metrics and the Xcode Metrics Organizer\nas part of a coordinated effort to bring new insights to developers\nabout how their apps are performing in the field.

\n
\n\n\n\"MetricKit\n\n
Diagram from WWDC 2019 Session 417: "Improving Battery Life and Performance"
\n
\n

Apple automatically collects metrics from apps installed on the App Store.\nYou can view them in Xcode 11\nby opening the Organizer (\u2325\u2318\u21e7O)\nand selecting the new Metrics tab.

\n

MetricKit complement Xcode Organizer Metrics by providing a programmatic way to\nreceive daily information about how your app is performing in the field.\nWith this information,\nyou can collect, aggregate, and analyze on your own in greater detail\nthan you can through Xcode.

\n

\nUnderstanding App Metrics

\n

Metrics can help uncover issues you might not have seen while testing locally,\nand allow you to track changes across different versions of your app.\nFor this initial release,\nApple has focused on the two metrics that matter most to users:\nbattery usage and performance.

\n

\nBattery Usage

\n\n\n\"MetricKit\n\n

Battery life depends on a lot of different factors.\nPhysical aspects like the age of the device and\nthe number of charge cycles are determinative,\nbut the way your phone is used matters, too.\nThings like CPU usage,\nthe brightness of the display and the colors on the screen,\nand how often radios are used to fetch data or get your current location \u2014\nall of these can have a big impact.\nBut the main thing to keep in mind is that\nusers care a lot about battery life.

\n

Aside from how good the camera is,\nthe amount of time between charges\nis the deciding factor when someone buys a new phone these days.\nSo when their new, expensive phone doesn\u2019t make it through the day,\nthey\u2019re going to be pretty unhappy.

\n

Until recently,\nApple\u2019s taken most of the heat on battery issues.\nBut since iOS 12 and its new\nBattery Usage screen in Settings,\nusers now have a way to tell when their favorite app is to blame.\nFortunately,\nwith iOS 13 you now have everything you need to make sure\nyour app doesn\u2019t run afoul of reasonable energy usage.

\n

\nPerformance

\n

Performance is another key factor in the overall user experience.\nNormally, we might look to stats like\nprocessor clock speed or frame rate\nas a measure of performance.\nBut instead,\nApple\u2019s focusing on less abstract and more actionable metrics:

\n
\n
Hang Rate
\n
How often is the main / UI thread blocked,\nsuch that the app is unresponsive to user input?
\n
Launch Time
\n
How long does an app take to become usable after the user taps its icon?
\n
Peak Memory & Memory at Suspension
\n
How much memory does the app use at its peak\nand just before entering the background?
\n
Disk Writes
\n
How often does the app write to disk,\nwhich \u2014 if you didn\u2019t already know \u2014 is a\ncomparatively slow operation\n(even with the flash storage on an iPhone!)\n
\n
\n

\nUsing MetricKit

\n

From the perspective of an API consumer,\nit\u2019s hard to imagine how MetricKit could be easier to incorporate.\nAll you need is for some part of your app to serve as\na metric subscriber\n(an obvious choice is your AppDelegate),\nand for it to be added to the shared MXMetricManager:

\n
import UIKit\n        import MetricKit\n        @UIApplicationMain\n        class AppDelegate: UIResponder, UIApplicationDelegate {\n        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        MXMetricManager.shared.add(self)\n        return true\n        }\n        func applicationWillTerminate(_ application: UIApplication) {\n        MXMetricManager.shared.remove(self)\n        }\n        }\n        extension AppDelegate: MXMetricManagerSubscriber {\n        func didReceive(_ payloads: [MXMetricPayload]) {\n        ...\n        }\n        }\n        
\n

iOS automatically collects samples while your app is being used,\nand once per day (every 24 hours),\nit\u2019ll send an aggregated report with those metrics.

\n

To verify that your MXMetricManagerSubscriber\nis having its delegate method called as expected,\nselect Simulate MetricKit Payloads from the Debug menu\nwhile Xcode is running your app.

\n\n

\nAnnotating Critical Code Sections with Signposts

\n

In addition to the baseline statistics collected for you,\nyou can use the\nmxSignpost function\nto collect metrics around the most important parts of your code.\nThis signpost-backed API\ncaptures CPU time, memory, and writes to disk.

\n

For example,\nif part of your app did post-processing on audio streams,\nyou might annotate those regions with metric signposts\nto determine the energy and performance impact of that work:

\n
let audioLogHandle = MXMetricManager.makeLogHandle(category: "Audio")\n        func processAudioStream() {\n        mxSignpost(.begin, log: audioLogHandle, name: "ProcessAudioStream")\n        ...\n        mxSignpost(.end, log: audioLogHandle, name: "ProcessAudioStream")\n        }\n        
\n

\nCreating a Self-Hosted Web Service for Collecting App Metrics

\n

Now that you have this information,\nwhat do you do with it?\nHow do we fill that ... placeholder in our implementation of didReceive(_:)?

\n

You could pass that along to some paid analytics or crash reporting service,\nbut where\u2019s the fun in that?\nLet\u2019s build our own web service to collect these for further analysis:

\n

\nStoring and Querying Metrics with PostgreSQL

\n

The MXMetricPayload objects received by metrics manager subscribers\nhave a convenient\njsonRepresentation() method\nthat generates something like this:

\n
\n\n
{\n"locationActivityMetrics": {\n"cumulativeBestAccuracyForNavigationTime": "20 sec",\n"cumulativeBestAccuracyTime": "30 sec",\n"cumulativeHundredMetersAccuracyTime": "30 sec",\n"cumulativeNearestTenMetersAccuracyTime": "30 sec",\n"cumulativeKilometerAccuracyTime": "20 sec",\n"cumulativeThreeKilometersAccuracyTime": "20 sec"\n},\n"cellularConditionMetrics": {\n"cellConditionTime": {\n"histogramNumBuckets": 3,\n"histogramValue": {\n"0": {\n"bucketCount": 20,\n"bucketStart": "1 bars",\n"bucketEnd": "1 bars"\n},\n"1": {\n"bucketCount": 30,\n"bucketStart": "2 bars",\n"bucketEnd": "2 bars"\n},\n"2": {\n"bucketCount": 50,\n"bucketStart": "3 bars",\n"bucketEnd": "3 bars"\n}\n}\n}\n},\n"metaData": {\n"appBuildVersion": "0",\n"osVersion": "iPhone OS 13.1.3 (17A878)",\n"regionFormat": "US",\n"deviceType": "iPhone9,2"\n},\n"gpuMetrics": {\n"cumulativeGPUTime": "20 sec"\n},\n"memoryMetrics": {\n"peakMemoryUsage": "200,000 kB",\n"averageSuspendedMemory": {\n"averageValue": "100,000 kB",\n"standardDeviation": 0,\n"sampleCount": 500\n}\n},\n"signpostMetrics": [\n{\n"signpostIntervalData": {\n"histogrammedSignpostDurations": {\n"histogramNumBuckets": 3,\n"histogramValue": {\n"0": {\n"bucketCount": 50,\n"bucketStart": "0 ms",\n"bucketEnd": "100 ms"\n},\n"1": {\n"bucketCount": 60,\n"bucketStart": "100 ms",\n"bucketEnd": "400 ms"\n},\n"2": {\n"bucketCount": 30,\n"bucketStart": "400 ms",\n"bucketEnd": "700 ms"\n}\n}\n},\n"signpostCumulativeCPUTime": "30,000 ms",\n"signpostAverageMemory": "100,000 kB",\n"signpostCumulativeLogicalWrites": "600 kB"\n},\n"signpostCategory": "TestSignpostCategory1",\n"signpostName": "TestSignpostName1",\n"totalSignpostCount": 30\n},\n{\n"signpostIntervalData": {\n"histogrammedSignpostDurations": {\n"histogramNumBuckets": 3,\n"histogramValue": {\n"0": {\n"bucketCount": 60,\n"bucketStart": "0 ms",\n"bucketEnd": "200 ms"\n},\n"1": {\n"bucketCount": 70,\n"bucketStart": "201 ms",\n"bucketEnd": "300 ms"\n},\n"2": {\n"bucketCount": 80,\n"bucketStart": "301 ms",\n"bucketEnd": "500 ms"\n}\n}\n},\n"signpostCumulativeCPUTime": "50,000 ms",\n"signpostAverageMemory": "60,000 kB",\n"signpostCumulativeLogicalWrites": "700 kB"\n},\n"signpostCategory": "TestSignpostCategory2",\n"signpostName": "TestSignpostName2",\n"totalSignpostCount": 40\n}\n],\n"displayMetrics": {\n"averagePixelLuminance": {\n"averageValue": "50 apl",\n"standardDeviation": 0,\n"sampleCount": 500\n}\n},\n"cpuMetrics": {\n"cumulativeCPUTime": "100 sec"\n},\n"networkTransferMetrics": {\n"cumulativeCellularDownload": "80,000 kB",\n"cumulativeWifiDownload": "60,000 kB",\n"cumulativeCellularUpload": "70,000 kB",\n"cumulativeWifiUpload": "50,000 kB"\n},\n"diskIOMetrics": {\n"cumulativeLogicalWrites": "1,300 kB"\n},\n"applicationLaunchMetrics": {\n"histogrammedTimeToFirstDrawKey": {\n"histogramNumBuckets": 3,\n"histogramValue": {\n"0": {\n"bucketCount": 50,\n"bucketStart": "1,000 ms",\n"bucketEnd": "1,010 ms"\n},\n"1": {\n"bucketCount": 60,\n"bucketStart": "2,000 ms",\n"bucketEnd": "2,010 ms"\n},\n"2": {\n"bucketCount": 30,\n"bucketStart": "3,000 ms",\n"bucketEnd": "3,010 ms"\n}\n}\n},\n"histogrammedResumeTime": {\n"histogramNumBuckets": 3,\n"histogramValue": {\n"0": {\n"bucketCount": 60,\n"bucketStart": "200 ms",\n"bucketEnd": "210 ms"\n},\n"1": {\n"bucketCount": 70,\n"bucketStart": "300 ms",\n"bucketEnd": "310 ms"\n},\n"2": {\n"bucketCount": 80,\n"bucketStart": "500 ms",\n"bucketEnd": "510 ms"\n}\n}\n}\n},\n"applicationTimeMetrics": {\n"cumulativeForegroundTime": "700 sec",\n"cumulativeBackgroundTime": "40 sec",\n"cumulativeBackgroundAudioTime": "30 sec",\n"cumulativeBackgroundLocationTime": "30 sec"\n},\n"timeStampEnd": "2019-10-22 06:59:00 +0000",\n"applicationResponsivenessMetrics": {\n"histogrammedAppHangTime": {\n"histogramNumBuckets": 3,\n"histogramValue": {\n"0": {\n"bucketCount": 50,\n"bucketStart": "0 ms",\n"bucketEnd": "100 ms"\n},\n"1": {\n"bucketCount": 60,\n"bucketStart": "100 ms",\n"bucketEnd": "400 ms"\n},\n"2": {\n"bucketCount": 30,\n"bucketStart": "400 ms",\n"bucketEnd": "700 ms"\n}\n}\n}\n},\n"appVersion": "1.0.0",\n"timeStampBegin": "2019-10-21 07:00:00 +0000"\n}\n
\n
\n

As you can see,\nthere\u2019s a lot baked into this representation.\nDefining a schema for all of this information would be a lot of work,\nand there\u2019s no guarantee that this won\u2019t change in the future.\nSo instead,\nlet\u2019s embrace the NoSQL paradigm\n(albeit responsibly, using Postgres)\nby storing payloads in a JSONB column:

\n
CREATE TABLE IF NOT EXISTS metrics (\n        id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,\n        payload JSONB NOT NULL\n        );\n        
\n

So easy!

\n

We can extract individual fields from payloads\nusing JSON operators\nlike so:

\n
SELECT (payload -> 'applicationTimeMetrics'\n        ->> 'cumulativeForegroundTime')::INTERVAL\n        FROM metrics;\n        -- interval\n        -- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n        -- @ 11 mins 40 secs\n        -- (1 row)\n        
\n\n

\nAdvanced: Creating Views

\n

JSON operators in PostgreSQL can be cumbersome to work with \u2014\nespecially for more complex queries.\nOne way to help with that is to create a view\n(materialized or otherwise)\nto project the most important information to you\nin the most convenient representation:

\n
CREATE VIEW key_performance_indicators AS\n        SELECT\n        id,\n        (payload -> 'appVersion') AS app_version,\n        (payload -> 'metaData' ->> 'deviceType') AS device_type,\n        (payload -> 'metaData' ->> 'regionFormat') AS region,\n        (payload -> 'applicationTimeMetrics'\n        ->> 'cumulativeForegroundTime'\n        )::INTERVAL AS cumulative_foreground_time,\n        parse_byte_count(\n        payload -> 'memoryMetrics'\n        ->> 'peakMemoryUsage'\n        ) AS peak_memory_usage_bytes\n        FROM metrics;\n        
\n

With views,\nyou can perform\naggregate queries\nover all of your metrics JSON payloads\nwith the convenience of a schema-backed relational database:

\n
SELECT avg(cumulative_foreground_time)\n        FROM key_performance_indicators;\n        -- avg\n        -- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n        -- @ 9 mins 41 secs\n        SELECT app_version, percentile_disc(0.5)\n        WITHIN GROUP (ORDER BY peak_memory_usage_bytes)\n        AS median\n        FROM key_performance_indicators\n        GROUP BY app_version;\n        -- app_version \u2502 median\n        -- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n        -- "1.0.1" \u2502 192500000\n        -- "1.0.0" \u2502 204800000\n        
\n\n

\nCreating a Web Service

\n

In this example,\nmost of the heavy lifting is delegated to Postgres,\nmaking the server-side implementation rather boring.\nFor completeness,\nhere are some reference implementations in\nRuby (Sinatra) and JavaScript (Express):

\n
\n
\n\n\n
\n
require 'sinatra/base'\n        require 'pg'\n        require 'sequel'\n        class App < Sinatra::Base\n        configure do\n        DB = Sequel.connect(ENV['DATABASE_URL'])\n        end\n        post '/collect' do\n        DB[:metrics].insert(payload: request.body.read)\n        status 204\n        end\n        end\n        
\n\n
\n

\nSending Metrics as JSON

\n

Now that we have everything set up,\nthe final step is to implement\nthe required MXMetricManagerSubscriber delegate method didReceive(_:)\nto pass that information along to our web service:

\n
extension AppDelegate: MXMetricManagerSubscriber {\n        func didReceive(_ payloads: [MXMetricPayload]) {\n        for payload in payloads {\n        let url = URL(string: "https://example.com/collect")!\n        var request = URLRequest(url: url)\n        request.httpMethod = "POST"\n        request.httpBody = payload.jsonRepresentation()\n        let task = URLSession.shared.dataTask(with: request)\n        task.priority = URLSessionTask.lowPriority\n        task.resume()\n        }\n        }\n        }\n        
\n
\n

When you create something and put it out into the world,\nyou lose your direct connection to it.\nThat\u2019s as true for apps as it is for college radio shows.\nShort of user research studies or\ninvasive ad-tech,\nthe truth is that\nwe rarely have any clue about how people are using our software.

\n\n

Metrics offer a convenient way to at least make sure that\nthings aren\u2019t too slow or too draining.\nAnd though they provide but a glimpse in the aggregate\nof how our apps are being enjoyed,\nit\u2019s just enough to help us honor both our creation and our audience\nwith a great user experience.

\n\n\"\"" }, "visual": { "url": "https://cdn.vox-cdn.com/thumbor/06e5FJWgUfUSmDaPJIEZoGF1XOs=/0x68:2040x1136/fit-in/1200x630/cdn.vox-cdn.com/uploads/chorus_asset/file/10378819/DSCF3031.jpg", "width": 1200, "height": 628, "contentType": "image/jpeg" }, "unread": false, "readTime": 4744, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/e31b3fcb-27f6-4f3e-b96c-53902586e366", "label": "Weblogs" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1572500250190 }, { "originId": "https://inessential.com/2019/10/22/netnewswire_5_0_3_for_mac_released", "fingerprint": "2c4d6d88", "id": "+jHfsXnBCVfCstSIW1WDumAyigT4rnsUPnI5WFxgnAU=_16df54dfcca:13322:d4506071", "summary": { "direction": "ltr", "content": "

\"NetNewsWire

\n

The main things in this release are 1) enhanced performance and 2) importing subscriptions from NetNewsWire 3 (since it won\u2018t run on Catalina).

\n

There are also a bunch of bug fixes \u2014 including a fix for the space bar behavior on Catalina \u2014 and there\u2019s a new feature: you can type the s key to star and unstar an article.

\n

For more details, read the change notes on the NetNewsWire blog.

" }, "alternate": [ { "href": "https://inessential.com/2019/10/22/netnewswire_5_0_3_for_mac_released", "type": "text/html" } ], "crawled": 1571778591946, "title": "NetNewsWire 5.0.3 for Mac Released", "published": 1571775505000, "origin": { "streamId": "feed/http://ranchero.com/xml/rss.xml", "htmlUrl": "https://inessential.com/", "title": "inessential.com" }, "visual": { "url": "http://www.blogcdn.com/www.engadget.com/media/2013/10/nvidia-shield-console-mode.jpg", "width": 620, "height": 340, "contentType": "image/jpg" }, "unread": false, "readTime": 5621, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/66132046-6f14-488d-b590-8e93422723c8", "label": "THree" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1572500226675 }, { "id": "AxO6mug+YPRclcA3EJcsykvvS1qcjXH62IXONGWCBII=_16db2add61b:afd:a4acdac", "originId": "58495.pz39s0 at https://www.imore.com", "fingerprint": "8fe463a6", "content": { "content": "

An Apple Support rep apparently said, "I do not know how this could of happened."

\n

\n

What you need to know

\n
  • An Apple Card user claims he was the victim of fraud.
  • \n
  • When he contacted Apple Support, they said, "I do not know how this could of happened."
  • \n
  • Apple Card touts an extra level of security with no numbers and no CVV.
  • \n

When Apple Card debuted, one of its biggest draws was Apple's focus on security. On Apple's website, it says, "It's hard to steal a credit card number when you can't see it." But that's apparently what happened to one Apple Card user who reached out to 9to5Mac, claiming they were the victim of fraud.

\n

The Apple Card user said they reached out to Apple Support and received this response:

\n
\n

I do not know how this could of happened. It's very rare for your card to be in two places at one time. Since our physical cards have no number on it, it's very hard for someone to copy it.

\n
\n

The Apple Card user confirmed the fraudulent charge after receiving an alert on his iPhone. The tricky thing is the purchase was apparently labeled as being nearby, but clicking on the map revealed it was hours away, 9to5Mac explained.

\n

On Apple's website, the company highlights the fact that the Apple Card doesn't have any numbers on it. "Not even a CVV. So that's one less thing to worry about when you hand over your card at a restaurant or store." But that doesn't guarantee it can't be stolen.

\n

9to5Mac speculates that the Apple Card user may have been the victim of skimming, which can potentially affect all credit cards and debit cards. It's a reminder to be extra vigilant when swiping your card at a gas station or ATM. Better yet, use Apple Pay when possible.

\n

\n
\n

Apple Card

\n

\n
\n

\"\"", "direction": "ltr" }, "title": "Apple Card user says he was the victim of fraud", "author": "Brandon Russell", "summary": { "content": "An Apple Support rep apparently said, "I do not know how this could of happened."\nWhat you need to know\nAn Apple Card user claims he was the victim of fraud.\nWhen he contacted Apple Support, they said, "I do not know how this could of happened."\nApple Card touts an extra level of security with no numbers and no CVV.\nWhen Apple Card debuted, one of its biggest draws was Apple's focus on security. On Apple's website, it says, "It's hard to steal a credit card number when you can't see it." But that's apparently what happened to one Apple Card user who reached out to 9to5Mac, claiming they were the victim of fraud.\nThe Apple Card user said they reached out to Apple Support and received this response:\nI do not know how this could of happened. It's very rare for your card to be in two places at one time. Since our physical cards have no number on it, it's very hard for someone to copy it.\nThe Apple Card user confirmed the fraudulent charge after receiving an alert on his iPhone. ...", "direction": "ltr" }, "alternate": [ { "href": "http://feeds.imore.com/~r/TheIphoneBlog/~3/DzBrQNf9PCU/apple-card-user-says-he-was-victim-fraud", "type": "text/html" } ], "canonical": [ { "href": "https://www.imore.com/apple-card-user-says-he-was-victim-fraud", "type": "text/html" } ], "crawled": 1570660800027, "published": 1570660313000, "origin": { "streamId": "feed/http://www.imore.com/rss.xml", "title": "iMore - The #1 iPhone, iPad, and iPod touch blog", "htmlUrl": "https://www.imore.com/" }, "unread": false, "readTime": 2216, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/66132046-6f14-488d-b590-8e93422723c8", "label": "THree" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1572500208603 }, { "keywords": [ "Development", "How To", "Xcode" ], "originId": "https://ericasadun.com/?p=6502", "fingerprint": "878bb7e8", "id": "eos9yhbovnwyH+gNY6NsrxoZIGI+1zv2KFTRDDBJycA=_16e0e491282:185ad:d4506071", "author": "erica", "summary": { "direction": "ltr", "content": "Most Xcode users quickly become familiar with the basics of the Find Navigator panel. With it, you can find text, regular expressions, and perform search-and-replace, whether matching or ignoring case. But that\u2019s just scratching the surface of the Find Navigator. I thought I\u2019d drop a few words today about search scopes. Controlled from the bottom [\u2026]" }, "alternate": [ { "href": "https://ericasadun.com/2019/10/27/fun-with-xcode-search-domains-excluding-match-text/", "type": "text/html" } ], "crawled": 1572197700226, "title": "Fun with Xcode Search Domains: Excluding match text", "published": 1572195876000, "origin": { "streamId": "feed/http://ericasadun.com/feed/", "htmlUrl": "https://ericasadun.com", "title": "Erica Sadun" }, "content": { "direction": "ltr", "content": "

Most Xcode users quickly become familiar with the basics of the Find Navigator panel.

\n

\"\"

\n

With it, you can find text, regular expressions, and perform search-and-replace, whether matching or ignoring case. But that\u2019s just scratching the surface of the Find Navigator.

\n

I thought I\u2019d drop a few words today about search scopes. Controlled from the bottom left, \u00a0under the search field, you can create narrowed searches. This enables you to, for example, search only in Swift files or exclude files containing the word Test.

\n

To get started, click the icon (two lines with three squares on a line between them) and then New Scope (the plus icon). Here, you can name the scope, limit the search extent, and add criteria for exactly which files should be included or not.

\n

\"\"

\n

The logic is straightforward. You choose where to look (the project, a folder, or through the entire SDK), and whether to include all conditions or some conditions:

\n

\"\"

\n

Each condition is based on the file name, path, extension, UTI (the kind of file, like image which is useful for finding vector assets), Workspace location (namely groups), or source control status (handy for finding newly applied changes.)

\n

Most of my conditions are file-name-based. And for those, you get the following matching conditions. The \u201cends with\u201d is an obvious win for extensions (although you can also use UTIs for that), and \u201cstarts with\u201d can help for projects organized in hierarchical ways.

\n

\"\"

\n

Now, interestingly enough, this list fails to offer \u201cdoes not contain\u201d but that\u2019s fairly easy to work around. Since Xcode supports regex matching, you can easily replicate \u201cdoes not contain\u201d with an appropriate regex:

\n

\"\"

\n

Change the file name to a path to exclude source file directories.

\n

You can create as many search domains as you like. At least, I haven\u2019t found an upper bound yet. I haven\u2019t found a way to reorder the find scopes, although if you\u2019re really controlling about this, you can pop into \u00a0your workspace (ProjectName.xcodeproj/project.xcworkspace/xcuserdata/username.xcuserdatad), convert your UserInterfaceState.xcuserstate to xml (plutil -convert xml1), and hand-edit it the way you need.

\n

There are lots of wonderful little Xcode tweaks like these throughout this monster of an IDE. What are some of your faves? If I have time this week, I\u2019ll share some of mine, such as the four-square \u2014 another of my favorite tools \u2014 and a few great ways to connect your editor to the navigator.

" }, "unread": false, "readTime": 3406, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/66132046-6f14-488d-b590-8e93422723c8", "label": "THree" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1572499929438 }, { "keywords": [ "Apple" ], "originId": "https://9to5mac.com/?p=617536", "recrawled": 1572455791719, "updateCount": 1, "fingerprint": "77224d8", "id": "BmoAzSEWHFzR01wyxBZAhNEo11Vy8oDR1qKDe+tKVEQ=_16e1d065ad9:1c0f1:d4506071", "author": "Michael Potuck", "summary": { "direction": "ltr", "content": "
\n

Sonos has announced a new initiative today that makes it easy for existing customers to trade in older Sonos products for a nice discount on new ones. For Apple customers, the Trade Up program is a neat opportunity to bring Sonos\u2019 AirPlay 2 compatible speakers into your home.

\n

more\u2026

\n

The post Sonos pushing AirPlay 2 speaker lineup with new Trade Up program appeared first on 9to5Mac.

" }, "alternate": [ { "href": "https://9to5mac.com/2019/10/30/sonos-trade-in-program-airplay-2/", "type": "text/html" } ], "crawled": 1572444986073, "title": "Sonos pushing AirPlay 2 speaker lineup with new Trade Up program", "published": 1572442686000, "origin": { "streamId": "feed/http://9to5mac.com/feed/", "htmlUrl": "https://9to5mac.com", "title": "9to5Mac" }, "visual": { "url": "https://cdn.vox-cdn.com/thumbor/06e5FJWgUfUSmDaPJIEZoGF1XOs=/0x68:2040x1136/fit-in/1200x630/cdn.vox-cdn.com/uploads/chorus_asset/file/10378819/DSCF3031.jpg", "width": 1200, "height": 628, "contentType": "image/jpeg" }, "unread": false, "readTime": 4493, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815", "label": "Macintosh" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1572499889443 }, { "originId": "tag:blogger.com,1999:blog-8954608646904080796.post-4991449931465752891", "fingerprint": "7d99be14", "thumbnail": [ { "url": "https://1.bp.blogspot.com/-rGjQOQb89a8/XbS25YYbgeI/AAAAAAAADUI/s8Q4e0pTtX4qSTP3wrkt13VGV53Q8J0tQCLcBGAsYHQ/s72-c/092.jpg", "width": 72, "height": 72 } ], "id": "v0v+7Ya8tssIZvd3/pcnFRr3HwvY/5YK3FGc2t65c0Y=_16e0a232509:17e32:d4506071", "updated": 1572124724480, "author": "Edward Feser", "alternate": [ { "href": "http://edwardfeser.blogspot.com/2019/10/john-paul-ii-in-defense-of-nation-and.html", "type": "text/html" } ], "crawled": 1572128105737, "title": "John Paul II in defense of the nation and patriotism", "published": 1572124680000, "origin": { "streamId": "feed/http://edwardfeser.blogspot.com/feeds/posts/default", "htmlUrl": "http://edwardfeser.blogspot.com/", "title": "Edward Feser" }, "content": { "direction": "ltr", "content": "
In chapters 11-15 of his last book Memory and Identity, Pope St. John Paul II provides a lucid exposition of the idea of the nation as a natural social institution and of the virtue of patriotism, as these have been understood in traditional natural law theory and Catholic moral theology.\u00a0 The relevance to current controversies will be obvious.

What is the nation, and what is patriotism?\u00a0 John Paul begins by noting the connection between the nation and the family, where the former is in a sense an extension of the latter:

The Latin word patria is associated with the idea and the reality of \u201cfather\u201d (pater).\u00a0 The native land (or fatherland) can in some ways be identified with patrimony \u2013 that is, the totality of goods bequeathed to us by our forefathers\u2026 Our native land is thus our heritage and it is also the whole patrimony derived from that heritage.\u00a0 It refers to the land, the territory, but more importantly, the concept of patria includes the values and spiritual content that make up the culture of a given nation. (p. 60)

As that last remark makes clear, the ties of blood are less important than those of culture.\u00a0 Indeed, multiple ethnicities can make up a nation.\u00a0 Referring to his native Poland, the pope notes that \u201cin ethnic terms, perhaps the most significant event for the foundation of the nation was the union of two great tribes,\u201d and yet other peoples too eventually went on together to comprise \u201cthe Polish nation\u201d (p. 77).\u00a0 It is shared culture, and especially a shared religion, that formed these diverse ethnicities into a nation:

When we speak of Poland\u2019s baptism, we are not simply referring to the sacrament of Christian initiation received by the first historical sovereign of Poland, but also to the event which was decisive for the birth of the nation and the formation of its Christian identity.\u00a0 In this sense, the date of Poland\u2019s baptism marks a turning point.\u00a0 Poland as a nation emerges from its prehistory at that moment and begins to exist in history.\u00a0 (p. 77)

That a shared culture is the key to understanding the nation is a theme John Paul emphasizes repeatedly throughout the book.\u00a0 He says that \u201cevery nation draws life from the works of its own culture\u201d (p. 83), and that:

The nation is, in fact, the great community of men who are united by various ties, but above all, precisely by culture.\u00a0 The nation exists\u00a0\u2018through\u2019 culture and \u2018for\u2019 culture\u00a0and it is therefore the great educator of men in order that they may \u2018be more\u2019 in the community\u2026

I am the son of a nation which\u2026 has kept its identity, and it has kept, in spite of partitions and foreign occupations, its national sovereignty, not by relying on the resources of physical power but solely\u00a0by relying on its culture. \u00a0This culture turned out, under the circumstances, to be more powerful than all other forces.\u00a0 What I say here concerning the right of the nation to the foundation of its culture and its future is not, therefore, the echo of any \u2018nationalism\u2019, but it is always a question of a stable element of human experience and of the\u00a0humanistic perspective of man's development.\u00a0 There exists a fundamental sovereignty of society, which is manifested in the culture of the nation. (p. 85)

In addition to shared values and religion, John Paul identifies shared history as another crucial aspect of a nation\u2019s identifying culture:

Like individuals, then, nations are endowed with historical memory\u2026 And the histories of nations, objectified and recorded in writing, are among the essential elements of culture \u2013 the element which determines the nation\u2019s identity in the temporal dimension.\u00a0 (pp. 73-74)

The pope notes that citizens of modern Western European countries often have \u201creservations\u201d about the notion of \u201cnational identity as expressed through culture,\u201d and have even \u201carrived at a stage which could be defined as \u2018post-identity\u2019\u201d (p. 86).\u00a0 There is \u201ca widespread tendency to move toward supranational structures, even internationalism\u201d with \u201csmall nations\u2026 allow[ing] themselves to be absorbed into larger political structures\u201d (p. 66).\u00a0 However, the disappearance of the nation would be contrary to the natural order of things:

Yet it still seems that nation and native land, like the family, are permanent realities.\u00a0 In this regard, Catholic social doctrine speaks of \u201cnatural\u201d societies, indicating that both the family and the nation have a particular bond with human nature, which has a social dimension.\u00a0 Every society\u2019s formation takes place in and through the family: of this there can be no doubt.\u00a0 Yet something similar could also be said about the nation. (p. 67)

And again:

The term \u201cnation\u201d designates a community based in a given territory and distinguished from other nations by its culture.\u00a0 Catholic social doctrine holds that the family and the nation are both natural societies, not the product of mere convention.\u00a0 Therefore, in human history they cannot be replaced by anything else.\u00a0 For example, the nation cannot be replaced by the State, even though the nation tends naturally to establish itself as a State\u2026 Still less is it possible to identify the nation with so-called democratic society, since here it is a case of two distinct, albeit interconnected orders.\u00a0 Democratic society is closer to the State than is the nation.\u00a0 Yet the nation is the ground on which the State is born. (pp. 69-70)

As this last point about the state and democracy indicates, a nation cannot be defined in terms of, or replaced by, either governmental institutions and their laws and policies on the one hand, or the aggregate of the attitudes of individual citizens on the other.\u00a0 It is something deeper than, and presupposed by, both of these things.\u00a0 It is only insofar as a nation, defined by its culture, is already in place that a polity can come into being.\u00a0 Hence it is a mistake to think that, if the common cultural bonds that define a nation disappear, the nation can still be held together by virtue of governmental policy either imposed from above or arrived at my majority vote.\u00a0 For a people have to be united by common bonds of culture before they can all see either governmental policy or the will of the majority as legitimate.\u00a0 (Readers familiar with the work of Roger Scruton will note the parallels, and how deeply conservative John Paul II\u2019s understanding of the nation is.)\u00a0

Now, as a natural institution, the nation, like the family, is necessary for our well-being.\u00a0 And as with the family, this entails a moral duty to be loyal to and to defend one\u2019s nation \u2013 and for precisely the same sorts of reasons one has a duty of loyalty to and defense of one\u2019s family:

If we ask where patriotism appears in the Decalogue, the reply comes without hesitation: it is covered by the fourth commandment, which obliges us to honor our father and mother.\u00a0 It is included under the umbrella of the Latin word pietas, which underlines the religious dimension of the respect and veneration due to parents\u2026

Patriotism is a love for everything to do with our native land: its history, its traditions, its language, its natural features.\u00a0 It is a love which extends also to the works of our compatriots and the fruits of their genius.\u00a0 Every danger that threatens the overall good of our native land becomes an occasion to demonstrate this love. (pp. 65-66)

Among the dangers to the nation are the opposite extreme economic errors of egalitarian statism and liberal individualism, which threaten to destroy the common culture that defines the nation \u2013 in the one case from the top down and in the other from the bottom up.\u00a0 The pope writes:

[W]e must ask how best to respect the proper relationship between economics and culture without destroying this greater human good for the sake of profit, in deference to the overwhelming power of one-sided market forces.\u00a0 It matters little, in fact, whether this kind of tyranny is imposed by Marxist totalitarianism or by Western liberalism. (pp. 83-84)

If liberal individualism is an error that pays insufficient respect to the nation, there is of course an opposite extreme error which involves giving excessive esteem to the nation \u2013 namely, nationalism.\u00a0 Patriotism, rightly understood, is the middle ground between these extremes:

Whereas nationalism involves recognizing and pursuing the good of one\u2019s own nation alone, without regard for the rights of others, patriotism, on the other hand, is a love for one\u2019s native land that accords rights to all other nations equal to those claimed for one\u2019s own. (p. 67)

John Paul II was clear that the remedy for nationalism was not to go to the opposite extreme (whether in the name of individualism, internationalism, or whatever), but rather precisely to insist on the sober middle ground:

How can we be delivered from such a danger?\u00a0 I think the right way is through patriotism\u2026 Patriotism, in other words, leads to a properly ordered social love. (p. 67)

Now, let\u2019s note a number of things about these remarks and their implications.\u00a0 First, as I have said, what the late pope was giving expression to here is not merely his personal opinion, but traditional natural law political philosophy and Catholic moral teaching \u2013 the kind of thing that would have been well known to someone formed in Thomistic philosophy and theology in the early twentieth century, as John Paul II was.

Second, John Paul\u2019s teaching implies that those who seek to preserve their nation\u2019s common culture, and for that reason are concerned about trends that might radically alter its religious makeup or undermine its common language and reverence for its history, are simply following a natural and healthy human impulse and indeed following out the implications of the fourth commandment.\u00a0 There is no necessary connection between this attitude and racism, hatred for immigrants, religious bigotry, or the like.\u00a0

Of course, a person who seeks to preserve his nation\u2019s culture might also be a racist or xenophobe or bigot.\u00a0 The point, however, is that he need not be, and indeed that it is wrong even to presume that he is, because a special love for one\u2019s own nation and desire to preserve its culture is a natural human tendency, and thus likely to be found even in people who have no racist or xenophobic or bigoted attitudes at all.\u00a0 Indeed, it is, again, even morally virtuous.\u00a0

Needless to say, there is also a moral need to balance this patriotism with a welcoming attitude toward immigrants, with respect for the rights of religious minorities, and so forth.\u00a0 The point, however, is that all of these things need to be balanced. \u00a0Too many contemporary Catholics, including some churchmen, have a tendency to emphasize only the latter while ignoring the former.\u00a0 They have a tendency to buy into the leftist narrative according to which the current wave of populist and patriotic sentiment in the United States and Western Europe is merely an expression of racism and xenophobia.\u00a0 This is deeply unjust, contrary to Catholic teaching, and politically dangerous.\u00a0 It is unjust and contrary to Catholic teaching because, again, both natural law and traditional moral theology affirm that a desire to preserve one\u2019s nation and its culture are natural human sentiments and morally praiseworthy.\u00a0 It is dangerous because, when governing authorities fail to respect and take account of these natural and decent human sentiments, they are inviting rather than preventing a nationalist overreaction.

(President Trump has famously called himself a \u201cnationalist,\u201d which is unfortunate given the connotations of that term.\u00a0 However, from his 2019 address to the United Nations it seems clear that what he means by this is just the defense of the institution of the nation against those who would dissolve it in the name of globalism, open borders, etc.\u00a0 Moreover, he explicitly affirmed the right of every nation to preserve itself and its sovereignty, and the right of everyhuman being to have a special patriotic love and preference for his own country.\u00a0 He also has repeatedly called for the United States to refrain from intervening in the affairs of other nations.\u00a0 So it is evident that it is really just patriotism in the sense described above, rather than some sort of American nationalism, that he intends to promote.)

The current controversy over illegal immigration must be understood in light of these principles.\u00a0 In a 1996 message on World Migration Day, John Paul II emphasized the need to welcome migrants, to take account of the dangerous circumstances they are sometimes fleeing, to avoid all racist and xenophobic attitudes, and so on.\u00a0 At the same time, he acknowledged that \u201cmigration is assuming the features of a social emergency, above all because of the increase in\u00a0illegal migrants\u201d (emphasis in the original), and that the problem is \u201cdelicate and complex.\u201d\u00a0 He affirmed that \u201cillegal immigration should be prevented\u201d and that one reason it is problematic is that \u201cthe supply of foreign labour is becoming excessive in comparison to the needs of the economy, which already has difficulty in absorbing its domestic workers.\u201d\u00a0 And he stated that in some cases, it may be necessary to advise migrants \u201cto seek acceptance in other countries, or to return to their own country.\u201d

The Catechism promulgated by Pope John Paul II teaches that:

The more prosperous nations are obliged, to the extent they are able,to welcome the\u00a0foreigner\u00a0in search of the security and the means of livelihood which he cannot find in his country of origin. Public authorities should see to it that the natural right is respected that places a guest under the protection of those who receive him.

Political authorities, for the sake of the common good for which they are responsible, may make the exercise of the right to immigrate subject to various juridical conditions, especially with regard to the immigrants' duties toward their country of adoption. Immigrants are obliged to respect with gratitude the material and spiritual heritage of the country that receives them, to obey its laws and to assist in carrying civic burdens.\u00a0 (Emphasis added)

End quote.\u00a0 Note that the Catechism teaches that immigrants have a duty to respect the laws and \u201cspiritual heritage\u201d of the nation they seek to enter, and that political authorities may restrict immigration so as to uphold the \u201ccommon good\u201d of the nation they govern.\u00a0

Hence, there is no foundation in Catholic teaching for an open borders position, or for the position that those who seek to uphold the common culture and economic interests of their nation ought to be dismissed as racists and xenophobes.\u00a0 On the contrary, Catholic teaching explicitly rules out those positions.\u00a0

There is a further implication of John Paul II\u2019s teaching.\u00a0 It isn\u2019t merely that having a special love for one\u2019s nation and its culture is natural and virtuous.\u00a0 It is that a failure to have it is vicious \u2013 a violation of the fourth commandment.

Of course, every nation has its faults, and aspects of its history of which one ought to be ashamed.\u00a0 For example, Germans are right to repudiate the Nazi period of their history, and Americans are right to repudiate slavery and segregation.\u00a0 But there is a mentality prevalent in the modern West that goes well beyond that \u2013 that insists on seeing nothing but evil in one\u2019s own nation and its culture and history.\u00a0 This is the mentality sometimes called oikophobia \u2013 the hatred of one\u2019s own \u201chousehold\u201d (oikos), in the sense of one\u2019s own nation.\u00a0 One sees this mentality in Westerners who shrilly and constantly denounce their civilization as irredeemably racist, colonialist, etc., downplaying or denying its virtues, and comparing it unfavorably to other cultures \u2013 as if Western culture is somehow more prone to such failings than other cultures are, and as if it hasn\u2019t contributed enormously to the good of the world (both of which are absurd suppositions).

Oikophobia is evil.\u00a0 It is a spiritual poison that damages both those prone to it (insofar as it makes them bitter, ungrateful, etc.) and the social order of which they are parts (insofar as it undermines the love and loyalty citizens need to have for their nation if it is to survive).\u00a0 It is analogous to the evil of hating and undermining one\u2019s own family.\u00a0 It is a violation of the fourth commandment.

The oikophobe sees his position as a remedy for nationalism, but in fact he is simply guilty of falling into an error that is the opposite extreme from that of the nationalist.\u00a0 Moreover, he is inadvertently promoting nationalism, because human beings have a tendency to overreact to one extreme by going too far in the other direction.\u00a0 Nationalism is bound to arise precisely as an overreaction against oikophobia.\u00a0 Those who are currently reacting to what they perceive as a resurgent nationalism by doubling down on oikophobia \u2013 pushing for open borders, indiscriminately denouncing their opponents as racists and xenophobes, etc. \u2013 are making a true nationalist backlash more likely, not less likely.\u00a0 The only true remedy for the evils of nationalism and oikophobia is, as John Paul II taught, the sober middle ground of patriotism.

It is no accident that those prone to oikophobia tend to be precisely the same people as those who want to push further the sexual revolution, feminism, and the destruction of the traditional family and traditional sex roles that these entail.\u00a0 The same liberal individualist poison is at the core of all of these attitudes.\u00a0 As St. John Paul II said, \u201cpatria is associated with the idea and the reality of \u2018father\u2019 (pater).\u201d\u00a0 Hatred of masculinity and of the paternal authority and responsibilities that are its fulfilment, hatred of the traditional family and of the sexual morality that safeguards it, and hatred of one\u2019s fatherland, are ultimately of a piece.\u00a0 And lurking beneath them all is a deeper hatred for another, heavenly Father.

Further reading:

Liberty, equality, fraternity?

Continetti on post-liberal conservatism

Hayek\u2019s Tragic Capitalism
" }, "visual": { "url": "none" }, "unread": true, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815", "label": "Macintosh" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/fbdcd69b-7e27-4b6a-bfed-6584b944155d", "label": "\ud83e\udd1e\ud83c\udffb\ud83e\udd1e\ud83c\udffb\ud83e\udd1e\ud83c\udffb" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1572499824479 }, { "originId": "https://www.raywenderlich.com/5436806-modern-collection-views-with-compositional-layouts", "fingerprint": "16268498", "id": "RFlzskW4NhJjlZfijOSI8IXqM9+zz6V9qnDVl1gxaJs=_16e1cddfaa1:1c015:d4506071", "updated": 1572440368000, "summary": { "direction": "ltr", "content": "In this tutorial, you\u2019ll learn how to build beautiful, modern UICollectionView layouts using iOS 13\u2019s new declarative UICollectionViewCompositionalLayout API." }, "alternate": [ { "href": "https://www.raywenderlich.com/5436806-modern-collection-views-with-compositional-layouts", "type": "text/html" } ], "crawled": 1572442340001, "title": "Modern Collection Views with Compositional Layouts [FREE]", "published": 1572440368000, "origin": { "streamId": "feed/http://www.raywenderlich.com/feed", "htmlUrl": "http://www.raywenderlich.com/feed", "title": "Ray Wenderlich | High quality programming tutorials: iOS, Android, Swift, Kotlin, Unity, and more" }, "unread": false, "readTime": 3593, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/885f2e01-d314-4e63-abac-17dcb063f5b5", "label": "Programming" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1572499811331 }, { "originId": "https://inessential.com/2019/10/30/etas_follow_up", "fingerprint": "d48dc2d2", "id": "+jHfsXnBCVfCstSIW1WDumAyigT4rnsUPnI5WFxgnAU=_16e1e5e8e9e:1ca95:d4506071", "summary": { "direction": "ltr", "content": "

Some people took my post No ETAs as if I were arguing against doing software estimates of any kind, ever.

\n

I didn\u2019t actually mean that. If your boss, project manager, or person you\u2019re contracting with asks for an estimate, do your best to come up with something accurate. If you\u2019re writing enterprise software, you may even be contractually bound to provide estimates for when features will ship.

\n

There are ways to get pretty good at this. Pay attention to history and avoid wishful thinking. Don\u2019t assume perfect productivity. Allow for the unexpected, because there\u2019s always something.

\n

What I\u2019m talking about is the case where you\u2019re writing a consumer-facing app \u2014\u00a0something that would get published on an app store, for instance \u2014\u00a0and customers or potential customers ask about an ETA for a given feature. Don\u2019t do it! (For the reasons stated in the article.)

" }, "alternate": [ { "href": "https://inessential.com/2019/10/30/etas_follow_up", "type": "text/html" } ], "crawled": 1572467543710, "title": "ETAs: Follow-Up", "published": 1572466202000, "origin": { "streamId": "feed/http://ranchero.com/xml/rss.xml", "htmlUrl": "https://inessential.com/", "title": "inessential.com" }, "unread": false, "readTime": 6552, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/66132046-6f14-488d-b590-8e93422723c8", "label": "THree" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1572499788300 }, { "keywords": [ "Apple" ], "originId": "https://9to5mac.com/?p=617593", "fingerprint": "a1dafaae", "id": "BmoAzSEWHFzR01wyxBZAhNEo11Vy8oDR1qKDe+tKVEQ=_16e1de23321:1c6e3:d4506071", "author": "Guilherme Rambo", "summary": { "direction": "ltr", "content": "
\n

Rumors about a new 16-inch MacBook Pro are not exactly new, with recent icon evidence found in macOS Catalina betas suggesting the redesign mentioned in some reports is not going to happen as we thought.

\n

more\u2026

\n

The post Exclusive: 16-inch MacBook Pro Touch Bar and Touch ID layout confirmed appeared first on 9to5Mac.

" }, "alternate": [ { "href": "https://9to5mac.com/2019/10/30/exclusive-16-inch-macbook-pro-touch-bar-and-touch-id-layout-confirmed/", "type": "text/html" } ], "crawled": 1572459393825, "title": "Exclusive: 16-inch MacBook Pro Touch Bar and Touch ID layout confirmed", "published": 1572456327000, "origin": { "streamId": "feed/http://9to5mac.com/feed/", "htmlUrl": "https://9to5mac.com", "title": "9to5Mac" }, "unread": false, "readTime": 3947, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815", "label": "Macintosh" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1572499186128 }, { "originId": "https://inessential.com/2019/10/30/you_choose_follow_up", "fingerprint": "f1dd63ab", "id": "+jHfsXnBCVfCstSIW1WDumAyigT4rnsUPnI5WFxgnAU=_16e1f71bf1c:1d086:d4506071", "summary": { "direction": "ltr", "content": "

It came to my attention after writing my blog post about how we choose the web we want\u00a0that the pessimism is about not being able to make a living from blogging.

\n

Here\u2019s my followup: I don\u2019t care. Bite me.

" }, "alternate": [ { "href": "https://inessential.com/2019/10/30/you_choose_follow_up", "type": "text/html" } ], "crawled": 1572485578524, "title": "You Choose: Follow-Up", "published": 1572482100000, "origin": { "streamId": "feed/http://ranchero.com/xml/rss.xml", "htmlUrl": "https://inessential.com/", "title": "inessential.com" }, "unread": false, "readTime": 3663, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/66132046-6f14-488d-b590-8e93422723c8", "label": "THree" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1572499146275 }, { "originId": "https://inessential.com/2019/10/14/netnewswire_os_compatibility_strategy", "fingerprint": "fa6e6fff", "id": "+jHfsXnBCVfCstSIW1WDumAyigT4rnsUPnI5WFxgnAU=_16dccdfc972:a6e5:d4506071", "summary": { "direction": "ltr", "content": "

We have two goals with the app: 1) get as many people using RSS as possible, and 2) make the best app we can.

\n

To reach #2 \u2014\u00a0making the best app we can \u2014\u00a0we need to do a couple things. One is stay modern: use new APIs and tools that make the app better and easier to maintain. A second is to not spend time on things that don\u2019t make the app better. A third is to attract and retain contributors, who are usually more psyched to work with modern stuff than with old stuff.

\n

You can see how that\u2019s in a little bit of conflict with #1 (getting as many people as possible using RSS readers).

\n

Here\u2019s the plan

\n

After a major OS update, we will switch to requiring that update on our next major release \u2014\u00a0where major is defined as something like 5.0 or 5.1, but not something like 5.0.1. (In other words: the upcoming NetNewsWire 5.0.3 release will run on Mojave, while NetNewsWire 5.1 will require Catalina.)

\n

At the same time, we will make older versions available via the website. For instance, the last version that will run on Mojave will likely be 5.0.4 (which isn\u2019t finished yet) \u2014 and we\u2019ll make that version available indefinitely for people who haven\u2019t upgraded to Catalina.

\n

This will mean that people running older OSes will still get a high-quality app \u2014 it\u2019s just that it won\u2019t have the latest features.

\n

The key is that this allows us to make NetNewsWire the best app it can be, and making the best app we can is also part of furthering the goal of getting as many people as possible using RSS. (The biggest part, in fact. Bigger than compatibility with older OSes.)

\n

While I know this will disappoint some people, I hope you\u2019ll understand why we decided to do it this way. Decisions like this are never easy \u2014 there are always conflicting values to weigh, pros and cons and add up \u2014\u00a0and we don\u2019t make them impulsively. But making NetNewsWire the best app it can be has to be job #1.

" }, "alternate": [ { "href": "https://inessential.com/2019/10/14/netnewswire_os_compatibility_strategy", "type": "text/html" } ], "crawled": 1571100281202, "title": "NetNewsWire OS Compatibility Strategy", "published": 1571099404000, "origin": { "streamId": "feed/http://ranchero.com/xml/rss.xml", "htmlUrl": "https://inessential.com/", "title": "inessential.com" }, "unread": false, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/66132046-6f14-488d-b590-8e93422723c8", "label": "THree" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1571123677415 }, { "keywords": [ "Xcode" ], "originId": "https://nshipster.com/swiftui-previews", "recrawled": 1571407228188, "updateCount": 2, "fingerprint": "7582ddff", "id": "08l+9ftpGejQ9f/2DZ6dom5rSnNJJO9OCox6I3nUnWg=_16dc8d7749a:96ed:d4506071", "updated": 1571036400000, "author": "Mattt", "summary": { "direction": "ltr", "content": "

Working on a large iOS codebase often involves a lot of waiting. But with Xcode 11, our wait is finally over \u2014 and it\u2019s all thanks to SwiftUI.

" }, "alternate": [ { "href": "https://nshipster.com/swiftui-previews/", "type": "text/html" } ], "crawled": 1571032626330, "title": "SwiftUI Previews on macOS Catalina and Xcode 11", "published": 1571036400000, "origin": { "streamId": "feed/http://nshipster.com/feed.xml", "htmlUrl": "https://nshipster.com/", "title": "NSHipster" }, "content": { "direction": "ltr", "content": "

Working on a large iOS codebase often involves a lot of waiting:\nWaiting for Xcode to index your files,\nwaiting for Swift and Objective-C code to compile,\nwaiting for the Simulator to boot and your app to launch\u2026

\n

And after all of that,\nyou spend even more time getting your app\ninto a particular state and onto a particular screen,\njust to see whether the Auto Layout constraint you just added\nfixes that regression you found.\nIt didn\u2019t, of course,\nso you jump back into Xcode,\ntweak the Content Hugging Priority,\nhit \u2318R,\nand start the whole process again.

\n

We might relate our sorry predicament to\nthat one xkcd comic,\nbut for those of us who don\u2019t so much relish in\nthe stop-and-go nature of app development,\nthere\u2019s an old Yiddish joke about Shlemiel the painter\n(provided below with a few \uf8ff-specific modifications;\nfor the uninitiated,\nplease refer to Joel Spolsky\u2019s\noriginal telling):

\n
\n

Shlemiel gets a job as a software developer,\nimplementing a new iOS app.\nOn the first sprint he opens Xcode\nand implements 10 new screens of the app.\n\u201cThat\u2019s pretty good!\u201d says his manager,\n\u201cyou\u2019re a fast worker!\u201d and pays him a Bitcoin.

\n

The next sprint Shlemiel only gets 5 screens done.\n\u201cWell, that\u2019s not nearly as good as yesterday,\nbut you\u2019re still a fast worker. 5 screens is respectable,\u201d\nand pays him a Bitcoin.

\n

The next sprint Shlemiel implements 1 screen.\n\u201cOnly 1!\u201d shouts his manager.\n\u201cThat\u2019s unacceptable!\nOn the first day you did ten times that much work!\nWhat\u2019s going on?\u201d

\n

\u201cI can\u2019t help it,\u201d says Shlemiel.\n\u201cEach sprint I get further and further away from\napplication(_:didFinishLaunchingWithOptions:)!\u201d

\n
\n

Over the years,\nthere have been some developments that\u2019ve helped things slightly,\nincluding\n@IBInspectable and @IBDesignable\nand Xcode Playgrounds.\nBut with Xcode 11,\nour wait is finally over \u2014\nand it\u2019s all thanks to SwiftUI.

\n
\n\n
\n

Although many of us have taken a \u201cwait and see\u201d approach to SwiftUI,\nwe can start using its capabilities today\nto radically speed up and improve our development process \u2014\nwithout changing a line of code in our UIKit apps.

\n

Consider a subclass of UIButton\nthat draws a border around itself:

\n
final class BorderedButton: UIButton {\n        var cornerRadius: CGFloat { ... }\n        var borderWidth: CGFloat { ... }\n        var borderColor: UIColor? { ... }\n        }\n        
\n

Normally,\nif we wanted to test how our UI element performs,\nwe\u2019d have to add it to a view in our app,\nbuild and run,\nand navigate to that screen.\nBut with Xcode 11,\nwe can now see a preview side-by-side with the code editor\nby adding the following under the original declaration of BorderedButton:

\n
\n
#if canImport(SwiftUI) && DEBUG\n        import SwiftUI\n        @available(iOS 13.0, *)\n        struct BorderedButton_Preview: PreviewProvider {\n        static var previews: some View {\n        UIViewPreview {\n        let button = BorderedButton(frame: .zero)\n        button.setTitle("Follow", for: .normal)\n        button.tintColor = .systemOrange\n        button.setTitleColor(.systemOrange, for: .normal)\n        return button\n        }.previewLayout(.sizeThatFits)\n        .padding(10)\n        }\n        }\n        #endif\n        
\n\n
\n

Using a new feature called dynamic replacement,\nXcode can update this preview without recompiling \u2014\nwithin moments of your making a code change.\nThis lets you rapidly prototype changes like never before.

\n

Want to see how your button handles long titles?\nBang away on your keyboard within the call to setTitle(_:for:)\nin your preview,\nand test out potential fixes in your underlying implementation\nwithout so much as leaving your current file!

\n\n

\nPreviewing Multiple States

\n

Let\u2019s say our app had a FavoriteButton \u2014\na distant cousin (perhaps by composition) to BorderedButton.\nIn its default state,\nit shows has the title \u201cFavorite\u201d\nand displays a \u2661 icon.\nWhen its isFavorited property is set to true,\nthe title is set to \u201cUnfavorite\u201d\nand displays a \u2661\u0338 icon.

\n

We can preview both at once\nby wrapping two UIViewPreview instances within a single SwiftUI Group:

\n
\n
Group {\n        UIViewPreview {\n        let button = FavoriteButton(frame: .zero)\n        return button\n        }\n        UIViewPreview {\n        let button = FavoriteButton(frame: .zero)\n        button.isFavorited = true\n        return button\n        }\n        }.previewLayout(.sizeThatFits)\n        .padding(10)\n        
\n\n
\n\n

\nPreviewing Dark Mode

\n

With Dark Mode in iOS 13,\nit\u2019s always a good idea to double-check that your custom views\nare configured with dynamic colors\nor accommodate both light and dark appearance in some other way.

\n

An easy way to do this\nwould be to use a ForEach element\nto render a preview for each case in the ColorScheme enumeration:

\n
\n
ForEach(ColorScheme.allCases, id: \\.self) { colorScheme in\n        UIViewPreview {\n        let button = BorderedButton(frame: .zero)\n        button.setTitle("Subscribe", for: .normal)\n        button.setImage(UIImage(systemName: "plus"), for: .normal)\n        button.setTitleColor(.systemOrange, for: .normal)\n        button.tintColor = .systemOrange\n        return button\n        }.environment(\\.colorScheme, colorScheme)\n        .previewDisplayName("\\(colorScheme)")\n        }.previewLayout(.sizeThatFits)\n        .background(Color(.systemBackground))\n        .padding(10)\n        
\n\n
\n\n

\nPreviewing Dynamic Type Size Categories

\n

We can use the same approach to preview our views in various\nDynamic Type Sizes:

\n
\n
ForEach(ContentSizeCategory.allCases, id: \\.self) { sizeCategory in\n        UIViewPreview {\n        let button = BorderedButton(frame: .zero)\n        button.setTitle("Subscribe", for: .normal)\n        button.setImage(UIImage(systemName: "plus"), for: .normal)\n        button.setTitleColor(.systemOrange, for: .normal)\n        button.tintColor = .systemOrange\n        return button\n        }.environment(\\.sizeCategory, sizeCategory)\n        .previewDisplayName("\\(sizeCategory)")\n        }.previewLayout(.sizeThatFits)\n        .padding(10)\n        
\n\n
\n

\nPreviewing Different Locales

\n

Xcode Previews are especially time-saving when it comes to\nlocalizing an app into multiple languages.\nCompared to the hassle of configuring Simulator\nback and forth between different languages and regions,\nthis new approach makes a world of difference.

\n

Let\u2019s say that, in addition to English,\nyour app supported various right-to-left languages.\nYou could verify that your\nRTL logic worked as expected like so:

\n
\n
let supportedLocales: [Locale] = [\n        "en-US", // English (United States)\n        "ar-QA", // Arabic (Qatar)\n        "he-IL", // Hebrew (Israel)\n        "ur-IN"  // Urdu (India)\n        ].map(Locale.init(identifier:))\n        func localizedString(_ key: String, for locale: Locale) -> String? { ... }\n        return ForEach(supportedLocales, id: \\.identifier) { locale in\n        UIViewPreview {\n        let button = BorderedButton(frame: .zero)\n        button.setTitle(localizedString("Subscribe", for: locale), for: .normal)\n        button.setImage(UIImage(systemName: "plus"), for: .normal)\n        button.setTitleColor(.systemOrange, for: .normal)\n        button.tintColor = .systemOrange\n        return button\n        }.environment(\\.locale, locale)\n        .previewDisplayName(Locale.current.localizedString(forIdentifier: locale.identifier))\n        }.previewLayout(.sizeThatFits)\n        .padding(10)\n        
\n\n
\n\n

\nPreviewing View Controllers on Different Devices

\n

SwiftUI previews aren\u2019t limited to views,\nyou can also use them with view controllers.\nBy creating a custom UIViewControllerPreview type\nand taking advantage of some\nnew UIStoryboard class methods in iOS 13,\nwe can easily preview our view controller\non various devices \u2014\none on top of another:

\n
\n
#if canImport(SwiftUI) && DEBUG\n        import SwiftUI\n        let deviceNames: [String] = [\n        "iPhone SE",\n        "iPad 11 Pro Max",\n        "iPad Pro (11-inch)"\n        ]\n        @available(iOS 13.0, *)\n        struct ViewController_Preview: PreviewProvider {\n        static var previews: some View {\n        ForEach(deviceNames, id: \\.self) { deviceName in\n        UIViewControllerPreview {\n        UIStoryboard(name: "Main", bundle: nil)\n        .instantiateInitialViewController { coder in\n        ViewController(coder: coder)\n        }!\n        }.previewDevice(PreviewDevice(rawValue: deviceName))\n        .previewDisplayName(deviceName)\n        }\n        }\n        }\n        #endif\n        
\n\n
\n\n
\n

Although most of us are still some years away from shipping SwiftUI in our apps\n(whether by choice or necessity),\nwe can all immediately benefit from the order-of-magnitude improvement\nit enables with Xcode 11 on macOS Catalina.

\n

By eliminating so much time spent waiting for things to happen,\nwe not only get (literally) hours more time each week,\nbut we unlock the possibility of maintaining an unbroken flow state during that time.\nNot only that,\nbut the convenience of integrated tests\nfundamentally changes the calculus for testing:\ninstead of being a rare \u201cnice to have,\u201d\nthey\u2019re the new default.\nPlus:\nthese inline previews serve as living documentation\nthat can help teams both large and small\nfinally get a handle on their design system.

\n

It\u2019s hard to overstate how much of a game-changer Xcode Previews are for iOS development,\nand we couldn\u2019t be happier to incorporate them into our workflow.

\n" }, "visual": { "url": "none" }, "unread": false, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/885f2e01-d314-4e63-abac-17dcb063f5b5", "label": "Programming" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1571037592868 }, { "originId": "tag:blogger.com,1999:blog-8954608646904080796.post-3215871338266756283", "fingerprint": "717870dc", "thumbnail": [ { "url": "https://1.bp.blogspot.com/-JTONCNpv2X8/XaEUgnGZSzI/AAAAAAAADTg/EaM5cDjkD3kRnXPIR0-6AX-3VxlC_br_QCEwYBhgL/s72-c/091.jpg", "width": 72, "height": 72 } ], "id": "v0v+7Ya8tssIZvd3/pcnFRr3HwvY/5YK3FGc2t65c0Y=_16dbd619e56:82fa:d4506071", "updated": 1570837682218, "author": "Edward Feser", "alternate": [ { "href": "http://edwardfeser.blogspot.com/2019/10/around-web.html", "type": "text/html" } ], "crawled": 1570840354390, "title": "Around the web", "published": 1570837680000, "origin": { "streamId": "feed/http://edwardfeser.blogspot.com/feeds/posts/default", "htmlUrl": "http://edwardfeser.blogspot.com/", "title": "Edward Feser" }, "content": { "direction": "ltr", "content": "
At The Catholic Thing, Fr. Thomas Weinandy on the studied ambiguity of Pope Francis.\u00a0 In his new book Conciliar Octet, Fr. Aidan Nichols on the hermeneutic of continuity and Vatican II.

At Medium, philosopher Kathleen Stock on gender theory versus academic freedom in the UK.\u00a0 At Inside Higher Education, twelve prominent philosophers defend the right to free inquiry on matters of sex and gender.\u00a0

Philosopher Daniel A. Kaufman on the \u201cwoke\u201d fanatics increasingly infesting academic philosophy, at The Electric Agora.\u00a0 Richard Marshall interviews Kaufman at 3:16.\u00a0

Peggy Noonan on transgender Jacobinism, at The Wall Street Journal.\u00a0 At YouTube, video of an indoctrination session.

Jacob Howland on Borges\u2019s Library of Babel, at The New Criterion.

At New Statesman, John Gray on Tom Holland on the Christian origins of modern secular liberal values.\u00a0 More reviews at The University Bookman and at Literary Review.

At Quillette, Benedict Beckeld diagnoses Western self-hatred or oikophobia.

Donald Fagen interviewed on Paul Shaffer Plus One.

Kay Hymowitz on the sexual revolution and mental health, at The Washington Examiner.

John DeRosa of the Classical Theism Podcast interviews Thomist philosopher Gaven Kerr on the topic of Aquinas and creation.

Ronald W. Dworkin on \u201cartificial intelligence\u201d as a projection of artificial intelligence researchers, at The American Interest.

New books on Aquinas: Aquinas and the Metaphysics of Creation, by Gaven Kerr; The Discovery of Being and Thomas Aquinas, edited by Christopher Cullen and Franklin Harkins; The Human Person: What Aristotle and Thomas Aquinas Offer Modern Psychology, by Thomas Spalding, James Stedman, Christina Gagn\u00e9, and Matthew Kostelecky.

At the Institute of Art and Ideas: Philosopher of physics Tim Maudlin on quantum physics and common sense.\u00a0 Physicist Subir Sarkar and philosophers Nancy Cartwright and John Dupr\u00e9 discuss physics and materialism.

Philosopher Dennis Bonnette on the distinction between the intellect and the imagination, at Strange Notions.

Philosopher of time Ross Cameron is interviewed by Richard Marshall at 3:16.

Duns Scotus in focus at Philosophy Now and Commonweal.\u00a0

10 facts about\u00a0Alfred Hitchcock Presents, at Mental Floss.

Tim Maudlin on Judea Pearl on causation versus correlation, at the Boston Review.\u00a0 Maudlin\u2019s book Philosophy of Physics: Quantum Theory is reviewed at Notre Dame Philosophical Reviews.

Charles Styles interviews Peter Harrison on the subject of the best books on the history of science and religion, at Five Books.

At Quillette, Kevin Mims on The Exorcist as a film about the breakdown of the family.

Society in Mind on the replication crisis in psychology.

Matias Slavov on Hume and Einstein on the nature of time, at Aeon.

At Catholic World Report, philosopher Joseph Trabbic on Aquinas and political liberalism.

Boston Review on post-liberal academic political philosophy.\u00a0 The Chronicle of Higher Educationon post-liberal Catholic political philosophy.\u00a0

Blue World, an album of lost John Coltrane tracks, has been released.

It\u2019s a thing.\u00a0 The Huffington Post reports on millennials who are becoming nuns.

Scott Alexander on LGBT as a new civil religion, at Slate Star Codex.\u00a0 C. C. Pecknold on the phony neutrality of post-Obergefell liberalism, at Catholic Herald.
" }, "visual": { "url": "http://b.vimeocdn.com/ts/452/218/452218069_1280.jpg", "width": 1280, "height": 720, "contentType": "image/jpeg" }, "unread": false, "categories": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815", "label": "Macintosh" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/fbdcd69b-7e27-4b6a-bfed-6584b944155d", "label": "\ud83e\udd1e\ud83c\udffb\ud83e\udd1e\ud83c\udffb\ud83e\udd1e\ud83c\udffb" } ], "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" } ], "actionTimestamp": 1571037184309 }, { "keywords": [ "Google", "Apple Arcade" ], "originId": "https://www.macrumors.com/2019/09/26/apple-arcade-vs-google-play-pass/", "fingerprint": "fd93a55d", "id": "SusR11hdg5ydv7o+xGl+0XlI0AhBL77Oxid8QOO3j5k=_16d6f7df794:48e16:18991ffa", "author": "Juli Clover", "summary": { "direction": "ltr", "content": "With the launch of iOS 13, Apple released Apple Arcade, a new $4.99 per month gaming service that provides unlimited access to new and exclusive games.\n
\n
\nLess than two weeks later, Google announced its own gaming service called Play Pass, which also offers unlimited access to games. In our latest YouTube video, we went hands-on with both services to compare them.\n
\n
\n
Subscribe to the MacRumors YouTube channel for more videos.
\n
\nBoth Apple Arcade and Play Pass are priced at $4.99 per month. Apple offers a one-month free trial while Google offers a 10-day free trial, but for the first year, Google is offering a deal that drops the price of Play Pass to $1.99 per month.\n
\n
\nThough the prices are similar, the two services are quite different. Apple Arcade features new and exclusive games, some of which were funded by Apple, while Google's Play Pass offers up older games.\n
\n
\nPlay Pass includes some super popular titles like Stardew Valley, Reigns, Star Wars Knights of the Old Republic, Terraria, and more, but the problem with older games is that many people may have already played them.\n
\n
\nPlay Pass is also not limited to games -- Google is including apps too. AccuWeather, Pic Stitch, ISS HD, and Tunable are some of the apps offered.\n
\n
\nApple Arcade only offers gaming titles, but all of the games are fresh, new, and exclusive to Apple Arcade. In some cases, though, some of the games are also available on consoles, but on mobile platforms, Apple Arcade gets exclusive access. That means no Android equivalent.\n
\n
\nIt's not clear if apps can leave Apple Arcade, but Google warns that apps can leave Play Pass. If that happens, users will need to buy the game to continue to use it if it's a paid game, and for free titles, ads and in-app purchases may show up.\n
\n
\nGoogle says there are hundreds of apps and games included with more being added every month. Apple Arcade launched with right around 60 games, and Apple has also promised new content on a monthly basis. Both services offer offline gaming, so no internet connection is required.\n
\n
\nWith both services, content is ad free and features no in-app purchases. Apple titles were designed from the ground up with no additional purchases, but for Play Pass, these gaming elements have been removed from titles that previously offered them.\n
\n
\nApple allows up to six family members to share games through a single Apple Arcade subscription using Family Sharing, and Google allows for up to five family members to share content through its Google Play Family Library.\n
\n
\nApple Arcade has launched in multiple countries around the world, while Play Pass is limited to the United States at the current time. Google does plan to expand, however.\n
\n
\nOne other aspect worth noting is privacy. Apple specifically mentions privacy protections and says that users are able to choose to share data, while Google's Play Pass materials don't mention privacy or data sharing. "Every game must meet Apple's high privacy standards," reads Apple's press release for Apple Arcade.\n
\n
\nMost people are locked in to either Android or iOS and few have both, so most people won't need to choose between services.\n
\n
\nApple users who have a Mac, iPhone, iPad, or Apple TV can access Apple Arcade on those devices, while Google Play Pass requires a smartphone, laptop, or tablet with Android 4.4 or above and Play Store version 16.6.25. Google Play Pass games can't be played on the larger screen of a television, which gives Apple Arcade a bit of an edge when it comes to non-mobile gaming.\n
\n
\nDo you prefer Apple Arcade with its fresh selection of titles, or Google Play Pass with its larger library of already available games? Let us know in the comments.

Tags: Google, Apple Arcade

This article, "Apple Arcade vs. Google Play Pass" first appeared on MacRumors.com

Discuss this article in our forums

\n \n
\"\"" }, "alternate": [ { "href": "https://www.macrumors.com/2019/09/26/apple-arcade-vs-google-play-pass/", "type": "text/html" } ], "crawled": 1569533589396, "title": "Apple Arcade vs. Google Play Pass", "published": 1569531802000, "origin": { "streamId": "feed/http://www.macrumors.com/macrumors.xml", "htmlUrl": "https://www.macrumors.com", "title": "MacRumors: Mac News and Rumors - Front Page" }, "visual": { "url": "https://cdn.vox-cdn.com/thumbor/m3ztxUEeETYXD9gGfyEjUpS0GFE=/0x0:800x533/1310x873/cdn.vox-cdn.com/uploads/chorus_image/image/59662701/800x_1.0.jpg", "width": 1310, "height": 873, "contentType": "image/jpeg" }, "unread": false, "readTime": 33744, "tags": [ { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.read", "label": "" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.unsaved", "label": "Unsaved" }, { "id": "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/tag/global.saved", "label": "Saved For Later" } ], "actionTimestamp": 1569536278861 } ] }