How to initialize ALAssetsGroupType constant in Swift?
Probably the best way, but a straightforward approach is to use a constructor Int32
to create a signed Int32
from UInt32
:
let groupTypes: ALAssetsGroupType = ALAssetsGroupType(Int32(bitPattern: ALAssetsGroupAll))
Description
If you click on the button ALAssetsGroupType
, you will see that this is the typealias for Int
:
typealias ALAssetsGroupType = Int
But, if you then click AssetsLibrary
next to the declared B, you can see that in the header file, this is indeed a typedef for NSUInteger
:
ALAssetsLibrary.h
typedef NSUInteger ALAssetsGroupType;
So what's going on here? Why doesn't Swift relate to NSUInteger
how UInt
? Swift is a strongly typed language, which means you can't just assign Int
UInt
without conversion. To simplify our lives and remove many of these transformations, Swift engineers decided to treat it NSUInteger
like Int
that, which saves a lot of hassle in most cases .
The next piece of mystery is the definition ALAssetsGroupAll
:
enum {
ALAssetsGroupLibrary = (1 << 0), // The Library group that includes all assets.
ALAssetsGroupAlbum = (1 << 1), // All the albums synced from iTunes or created on the device.
ALAssetsGroupEvent = (1 << 2), // All the events synced from iTunes.
ALAssetsGroupFaces = (1 << 3), // All the faces albums synced from iTunes.
ALAssetsGroupSavedPhotos = (1 << 4), // The Saved Photos album.
#if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
ALAssetsGroupPhotoStream = (1 << 5), // The PhotoStream album.
#endif
ALAssetsGroupAll = 0xFFFFFFFF, // The same as ORing together all the available group types,
};
Note that the comment next to ALAssetsGroupAll
says "The same as ORing together all the available group types"
. Well, that 0x3F
would be enough, but presumably the author decided to set all the bits only for future proof if other options are added in the future.
The problem is that as long as 0xFFFFFFFF
suitable for NSUInteger
, he did not fit in Int32
, so you get the overflow warning on 32-bit systems. The solution above converts UInt32
0xFFFFFFFF
to Int32
with the same bit. It is then converted to ALAssetsGroupType
, which is just Int
, so on a 32 bit system you end up Int
with all the bits set (which is the representation -1
). On a 64-bit system, the value is Int32
-1
given a sign extended to -1
in 64-bit, which sets all 64 bits of the value.
Another way to solve this is to define your own AllGroups
:
let AllGroups = -1 // all bits set
let groupTypes: ALAssetsGroupType = AllGroups
Note, this is deprecated in iOS 9:
typedef NSUInteger ALAssetsGroupType NS_DEPRECATED_IOS(4_0, 9_0, "Use PHAssetCollectionType and PHAssetCollectionSubtype in the Photos framework instead");
source to share