supermarin / objectiverecord Goto Github PK
View Code? Open in Web Editor NEWActiveRecord-like API for CoreData
License: MIT License
ActiveRecord-like API for CoreData
License: MIT License
pods version of ObjectiveRecord is outdated and there are few missing methods which are used in SampleProject.
eg.
find in NSManagedObject+ActiveRecord.h
When is the next version planned to be released?
Regards
Johan
Was where:order: class removed?
Right now OR supports value transformation for dates in a common format, or (implicitly) dates in other formats by overriding defaultFormatter
in NSManagedObject
subclasses.
It would be convenient to support a more generic kind of value transformation. Two ideas:
Add a mappings
property for formatter
that takes an NSFormatter
subclass as a value. When a formatter is present, the value for that key is processed through -[FormatterInstance getObjectValue:forString:errorDescription:]
before updating the record. Here's an example usage:
+ (NSDictionary *)mappings
{
return @{
@"id" : PRIMARY_KEY,
@"sandwich" : @{
@"class": [Sandwich class]
@"formatter": [SandwichFormatter class] },
@"timestamp" : @{
@"formatter": [SuperSpecialAPIDateFormatter class] }
};
}
A caveat would be that we'd presumably need to store any instances of formatters in thread dictionaries, as they may not be threadsafe.
Add a transform
block to mappings
, for inline value formatting. Example:
+ (NSDictionary *)mappings
{
return @{
@"id" : PRIMARY_KEY,
@"sandwich" : @{
@"class": [Sandwich class]
@"transform": ^(id value) {
return [SandwichFormatter sanitizeParams:value] } },
@"timestamp" : @{
@"transform": ^(id value) {
return [[SuperSpecialAPIDateFormatter sharedFormatter] dateForString:value]; }
}
};
}
Managing thread safety would be up to the user (and therefore NMP), though this way would probably have more code duplication.
@stephencelis just opening this so we can keep track of the release blockers:
@"surname ASC"
instead of @{@"surname" @"ASC"}
)Feel free to edit the issue if I've left out something
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI managedObjectContext]: unrecognized selector sent to instance 0x16e5e880'
#import "Person.h"
#import "Address.h"
#import "Person+Mappings.h"
#import "Address+Mappings.h"
NSDictionary *aPerson = @{@"name": @"Peter",
@"home":@{@"latitude": @37.12323123,
@"longitude": @141.232323 }
Person *peter = [Person create:aPerson];
+ (NSDictionary *)mappings{
//I put a breakpoint here and it never get called
return @{@"owner": @{@"class": [Person class]}};
}
+ (NSDictionary *)mappings{
//I put a breakpoint here and it never get called
return @{@"home": @{@"class": [Address class]}};
}
there should be possibility to query with aggregated function and other similar operations
Hi,
I just begin to use ObjectiveRecord and I want to say big thanks to those which made this amazing library !
I've a question about find entities from a context. I've an entity named "Basket" which contains the current basket of an user. There will be only one Basket entity.
If I call the method [Basket all]
I will have an array of Basket with all the time only one entity inside.
Is there a method which permits to get only the instance of my entity without returning an array ?
Because if I use method with order
parameter I will still have an array.
Any suggestions ?
I'm using Xcode 5.0.2 and iOS 7. I followed the instructions from the readme file and got the error below. I then tried without using CocoaPods by just copy-pasting the ObjectiveRecord and ObjectiveSugar files into the project directory. I get the same error. (When I try with CocoaPods, I see a missing (red) libPods.a in the projects settings / linked library page.
I'm on a clean, new project. Have I done something wrong or is there some issue with the current version of ObjectiveRecord? Or why else won't it work with a clean project?
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'
*** First throw call stack:
(
0 CoreFoundation 0x01ab05e4 exceptionPreprocess + 180
1 libobjc.A.dylib 0x018338b6 objc_exception_throw + 44
2 CoreData 0x00025b0e -[NSPersistentStoreCoordinator initWithManagedObjectModel:] + 398
3 asdf 0x00007831 -[CoreDataManager persistentStoreCoordinatorWithStoreType:storeURL:] + 193
4 asdf 0x00007299 -[CoreDataManager persistentStoreCoordinator] + 169
5 asdf 0x00006f5a -[CoreDataManager managedObjectContext] + 106
6 asdf 0x00008086 +[NSManagedObjectContext(ActiveRecord) defaultContext] + 86
7 asdf 0x000088da +[NSManagedObject(ActiveRecord) create] + 58
8 asdf 0x0000256d -[ViewController viewDidLoad] + 93
9 UIKit 0x006b5318 -[UIViewController loadViewIfRequired] + 696
10 UIKit 0x006b55b4 -[UIViewController view] + 35
11 UIKit 0x005dd9fd -[UIWindow addRootViewControllerViewIfPossible] + 66
12 UIKit 0x005ddd97 -[UIWindow _setHidden:forced:] + 312
13 UIKit 0x005de02d -[UIWindow _orderFrontWithoutMakingKey] + 49
14 UIKit 0x005e889a -[UIWindow makeKeyAndVisible] + 65
15 UIKit 0x0059bcd0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
16 UIKit 0x005a03a8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
17 UIKit 0x005b487c -[UIApplication handleEvent:withNewEvent:] + 3447
18 UIKit 0x005b4de9 -[UIApplication sendEvent:] + 85
19 UIKit 0x005a2025 _UIApplicationHandleEvent + 736
20 GraphicsServices 0x02ea22f6 _PurpleEventCallback + 776
21 GraphicsServices 0x02ea1e01 PurpleEventCallback + 46
22 CoreFoundation 0x01a2bd65 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 53
23 CoreFoundation 0x01a2ba9b __CFRunLoopDoSource1 + 523
24 CoreFoundation 0x01a5677c __CFRunLoopRun + 2156
25 CoreFoundation 0x01a55ac3 CFRunLoopRunSpecific + 467
26 CoreFoundation 0x01a558db CFRunLoopRunInMode + 123
27 UIKit 0x0059fadd -[UIApplication _run] + 840
28 UIKit 0x005a1d3b UIApplicationMain + 1225
29 asdf 0x0000aafd main + 141
30 libdyld.dylib 0x02b4270d start + 1
31 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I have a field in my remote JSON object that I don't want to use in my core data object.
How can I "unmap" this field to avoid NSUnknownKeyException ?
Thanks for your help.
The above code will fail and fail hard if it cannot setValue:ForKey, should this be guarded against in case the API changes and the mapping has not been updated?
@try {
[self setValue:value forKey:key];
} @catch (NSException *exception) {
NSLog(@"%@", exception);
}
Hello,
pod search shows as '~> 1.3.1' but installs old version which does not have -
Thanks!
One thing I love above ActiveRecord is getting errors on the object. Of course, you can get the errors on the MOC but it gives you errors of EVERY object in the context.
I'm thinking after an [object save] operation, you can go object.errors and it filters only the relevant errors. It could even be spiced up with a special errors class that can respond to messages like toString or toWhatever.
Thoughts?
Hi, this is a just question rather than a bug report. I'm using a separate core data stack manager that is setup nicely for background operations. Its creates the stack and a foreground and background context and manages the merges, etc. It does a good job and I'd like to keep using it.
I'd also like to use your library for the awesome data access methods and was wondering if there is an easy way to initialize it using just the NSManagedObjectContext and avoid it setting up the stack? Basically just a way to simply create the shared instance on top of a context that already exists? I think there was a method to create a custom context, but I'd really like to have an option for the singleton to be setup for my existing context to keep the syntax short and sweet.
I appreciate all your work thanks for any help you can provide.
Hi, I've a project build a time ago and was working fine, but now with the updated ios 7 sdk it stop working, seems that the category is not adding the custom methods. In the xcode recognizes the methods in the autocomplete dropdown. I made no change, it was installed via cocoapods (version 1.4.0) and it doesn't recognize the ObjectiveRecord methods.
In the Prefix.pch added
#import "ObjectiveRecord.h"
And then my model
// Version.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Version : NSManagedObject
@property (nonatomic, retain) NSString * objectId;
@property (nonatomic, retain) NSString * database;
@property (nonatomic, retain) NSNumber * version;
@end
// Version.m
#import "Version.h"
@implementation Version
@dynamic objectId;
@dynamic database;
@dynamic version;
@end
Then I call it
NSArray *versions = [Version where:@{@"database": database}];
And got
+[Version where:]: unrecognized selector sent to class 0x1ee73c
Even if I import ObjectiveRecord in the .m file I got the error
Regards
Hello,
This is really more a question than an issue, I was wondering how you were using this method [[CoreDatamanager sharedInstance] managedObjectContext], I always use it as the main context, so I was wondering if it was meant to be used like that and if it is, then maybe it would make sense to create it like that :
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
instead of simply "init" ?
I'm trying to import JSON data into CoreData using ObjectiveRecord:
for( id eventData in results ) {
[Event findOrCreate: eventData ];
}
Next, I have defined the mappings as followed:
- (NSDictionary *)mappings
{
return @{ @"id" : @"eventID",
@"business_id" : @"businessID",
@"description" : @"detail" };
}
However, I'm getting the following error message:
reason: 'keypath description not found in entity <NSSQLEntity Event id=2>'
I'm guessing that this has something to do with the mappings because it's not 100% certain how this mappings work. Does it work as follows:
@{ @"id_from_json" : @"id_in_core_data_model" }
or
@{ @"id_in_core_data_model" : @"id_from_json" }
In any case, it doesn't appear that this method is ever called when I run the application.
Why is that the mappings are overridden as instance methods of NSManagedObject? Probably they should be a class method of NSManagedObject.
I would not expect different mappings for different instances of the same model class. And additionally I have seen that the mappings are cached as a class method. Is there a particular reason for this? Or maybe just a bug?
Checked out the project and copied the files to my project. Tried to build the whole thing but got an error on NSManagedObject+ActiveRecord.m: "'ObjectiveSugar.h' file not found".
NSManagedObjectContext *newContext = [NSManagedObjectContext new];
Person *john = [Person createInContext:newContext];
Person *john = [Person where:@"name == 'John'" inContext:newContext].first;
NSArray *people = [Person allInContext:newContext];
I use these code, but will crash, reason is:+entityForName: could not locate an NSManagedObjectModel for entity name 'Person'
I think the newContext must setPersistentStoreCoordinator, how do you think about this?
The documentation is mentioning new features (like the count method) that isn't int he current Cocoapods version. Time for a new release?
Hi,
is there a way of setting a date formatter for parsing dates? In the JSON answer I'm getting, the dates are set as milliseconds since 1970 e.g.
"anniversary": 1388646266064
cheers
Hi Marin
I found the override on category not work on my code base
my subclass's + (NSDictionary *)mappings will not be called if I use ObjetiveRecord by Cocoapods,
and + (NSString *)entityName will return NSManagedObject if this call if from NSManagedObject+Mappings.m
I found some explanation, do you think so?
Obj-C allows you to add methods to an existing class using Categories. So if you add a method to NSString, the categoriesed method is available to NSMutableString and all classes which inherits NSString or any subclasses of NSString.
But you should avoid to Override the category.
You will not be 100% sure which method will be called. It depends on compiler.
http://stackoverflow.com/questions/14259517/override-a-method-in-objective-c-via-category
I have a very basic setup. When I try to call [ModelName create] I get an exception at line 120 in CoreDataManager.m
2013-12-02 20:54:10.674 LDLN[1362:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'
The problem seems to be that the code can't find a valid resource with the extension "momd" at line 69 of the same file. This function returns nil which causes the crash when nil is trying to be accessed.
Is this a setup issue that is undocumented or an outlier?
This can be achieved by having exactly one MOC per object but I'm not sure of the implications in both using it and coding it. Would there be huge memory implications? Would this have to be a special condition, like fetching an object with a hasOwnManagedObjectContext flag set to yes? Are there alternatives to this, perhaps when calling save creating a child MOC, saving that, and merging back into the original MOC?
Currently, the delete method marks the object for deletion and saves the context. When iterating through a large number of objects and deleting this could be expensive. Perhaps a method such as the following would be a good solution:
- (void)deleteAndCommit:(BOOL)doCommit;
Hey,
I just saw your project and thought it would be useful to have some validations like in ActiveRecord.
I developed a small library https://github.com/nerdishbynature/ObjcModelValidation) and am using it in production projects.
Are you interested in something like this? I could make a pull request.
Cheers,
Piet.
Hello.
I used methods "each" and "first" from ObjectiveSugar. In previous version of ObjectiveRecord you imported the ObjectiveSugar.h file in NSManagedObject+ActiveRecord.h so "each" and "first" was visible. Now you import ObjectiveSugar.h in "NSManagedObject+ActiveRecord.m" and I can not see and use this two methods. What was the reason for this change and can you make it like it was?
Firstly, I would like to say that your lib is lovely. It really empowers CD and wish that iOS SDK has bundled something like this in their framework.
Being on ror for quite some time, I tend to thing in a interface from rails.
After I use ObjectiveRecord for a while, I find myself using
Person* p = [[Person where:@{ @"id", @5}] first];
if (p) {
[p update:data];
} else {
p = [Person create:data];
}
all the time. My question is simple, do you have interface like 'findOrCreate' just to avoid this boring check?
I'm getting a test failure on this method :
it(@"Finds in a separate context", ^{
[newContext performBlock:^{
Person *found = [Person where:@{ @"firstName": @"Joshua" } inContext:newContext].first;
[[found.lastName should] equal:@"Jobs"];
}];
});
Error message is the following :
[FindersAndCreators FindCreateSaveDeleteSpecs_AllFromAbove_InASeparateContext_FindsAllInASeparateContext] failed:
'Find / Create / Save / Delete specs, All from above, in a separate context!, Finds all in a separate context' [FAILED], expected subject not to be nil
We should probably make ObjectiveRecord/Core
, sub spec in case someone wants no magic and to stay simple.
This also includes a bit of architectural changes in NSManagedObject+ActiveRecord.m
, to check if mappings are present.
Hi guys, first up GREAT work with this project, thank you!
It may be me, but I'm not seeing any of the sort methods in the version coming down from CocoaPods:
#pragma mark - Default Context
- (BOOL)save;
- (void)delete;
+ (void)deleteAll;
+ (id)create;
+ (id)create:(NSDictionary *)attributes;
- (void)update:(NSDictionary *)attributes;
+ (NSArray *)all;
+ (NSArray *)where:(id)condition;
+ (NSArray *)whereFormat:(NSString *)format, ...;
+ (instancetype)findOrCreate:(NSDictionary *)attributes;
My pod entry is:
platform :ios, '7.0'
pod 'ObjectiveRecord'
and when I run pod install I get:
Using ObjectiveRecord (1.4.0).
Advice appreciated and thanks again.
I have a really strange bug appeared while using ObjectiveRecord. I'm not sure it's a bug of ObjectiveRecord. But I have no idea how to fix it.
Here's the code:
ELStack* stack = (ELStack*)([ELStack where:@{@"type": @(ELStackTypeInbox)}][0]);
This code works fine when the code was executed at the first time. It's fetches the things I want, But failed when I try to call it more than once. It'll return a nil result even I haven't change anything about the Object.
I try to solve the problem on my own. So I NSLog what's happening in my database. While I NSLog(@"%@",[ELStack all])
the database, It's appears there IS something happened.
The first fetch (which works fine), the NSLog
return a NSArray
of ELStack
s, which there are no custom attributes showing in the NSLog
. But when I try to fetch them again. The NSLog
return ELStack
s contains attributes. In this period, There's nothing changing in the database. I have no idea what this mean, no idea how it happen, and absolutely no idea how to fix it.
Please help me figure out what really happen. Thank you.
I have been trying to get ObjectiveRecord
to work with swift
for the past few hours. It would be nice if there was a swift
example.
I think the API of this project is amazing! Especially someone coming from Ruby/Rails world into it.
Right now OR handles creating nested entity objects during update:
using the classes specified in an entity's mappings
block. However, when a dictionary contains multiple levels of objects, the nested dictionaries aren't processed recursively, and are treated like values for entity property keys, so -[NSManagedObject predicateForDictionary:]
returns a format like: id == 4 AND type == Cajun AND owner == { id = 6 }
, resulting in a crash, since the owner value is not in a valid format.
Given I have a Restaurant
class, an Owner
class, and a Car
class, where a Restaurant
has an Owner
and an Owner
has a Car
@implementation Restaurant
+ (NSDictionary *)mappings {
return @{ @"id" : @"restaurantID",
@"owner" : @{ @"class" : [Owner class]}};
}
@end
@implementation Owner
+ (NSDictionary *)mappings {
return @{ @"id" : @"ownerID",
@"car" : @{ @"class" : [Car class]}};
}
@end
@implementation Car
+ (NSDictionary *)mappings {
return @{ @"id" : @"carID" };
}
@end
When I want to update my Restaurant
instance with a dictionary that looks like so:
[restaurant update:@{
@"id" : @4,
@"type" : @"Cajun",
@"owner" : @{
@"id" : @6,
@"full_name" : @"Rory Hill"
@"car" : @{ @"id" : @43, @"model" : @"3"}}}];
Then I should have one Restaurant
, one Owner
, and one Car
when the update is complete.
Wouldn't it be better for +(NSArray*) where:(id)condition
to return an empty array rather than nil when there are zero results?
Method
+ (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObjectContext *)context {
NSManagedObject *existing = [self where:properties inContext:context].first;
return existing ?: [self create:properties];
}
finds object in the provided context but creates in default context. I think it would be better also create object in the provided context
Is this by design? Is there a way to nil out values with update:
or a similar method?
[user update:@{@"nickname": @"Stevie"}];
// user's nickname is now "Stevie"
[user update:@{@"nickname": [NSNull null]}];
// user's nickname is still "Stevie"
This is due to bailing out early for NSNull here:
https://github.com/mneorr/ObjectiveRecord/blob/master/Classes/NSManagedObject%2BActiveRecord.m#L310
Since CoreDataManager is a singleton with a managedObjectContext and Apple recommends thread confinement (separate context for each thread) for Core Data, what is the proper way to use ObjectiveRecord in a multi threaded app? For example when some of the data processing occurs on background threads.
I see that most enhanced methods on NSManagedObject have custom context versions. Is this the recommendation?
Hi, thanks for all your great work. This repo works like a charm.
But I found there may be something wrong when trying to update a existing record.
I have a entity called Post and another one called Author. The Post has a simple to one relationship with Author.
When I do the following:
Post *post = [Post whereFormat:@"postId == %d", postId].firstObject;
if (post != nil) {
// if we already got the post, just update.
[post update:attributes];
}
else {
[Post create:attributes];
}
It seems send update message to post always create a new author instance. So after update the post, I got two same author records in sqlite.
This could be caused by the following code in NSManagedObject+ActiveRecord (line 188)
- (void)hydrateObject:(id)properties ofClass:(Class)class forKey:(NSString *)key {
[self setSafeValue:[self objectOrSetOfObjectsFromValue:properties ofClass:class]
forKey:key];
}
objectOrSetOfObjectsFromValue:ofClass: will always create a new instance of class.
I have no idea how to solve this, Please help me out.
For example, when a mapping is missing - we should catch the exception thrown by setting an undefined value for key, and ask the user if he forgot to override mapping in that specific place
Does ObjectiveRecord have NSKeyValueCoding support, for using valueForKeyPath
instead of objectForKey
?
I want to avoid to have an entity for each nested objects in the payload.
This is a map example of what I have, but can't make it work. Any thoughts?
+ (NSDictionary *)mappings {
return @{
@"icons.image_48": @"image48"
@"icons.image_64": @"image64"
};
}
Hi,
I want to create an managed object from a dictionary as shown in the example
[Person create:@{ @"name" : @"John", @"age" : @12, @"member" : @NO }];
but the dictionary I'm getting from a web service has some more attributes that I'm not interested and are not defines in in my model.
When using the create method, it crashes because it tries to assign all attributes from the dictionary to my object.
Is there a way to ignore those ?
regards,
Jan
On 1.4, this snippet works:
MMBundleSet *bundleSet= [MMBundleSet create:@{
@"type": @(1),
}];
NSLog(@"Created bundleSet with type: %i", bundleSet.typeRawValue);
outputting (correctly):
2014-04-24 15:27:09.654 Production 3G[90621:60b] Created bundleSet with type: 1
However on 1.5, it now outputs:
2014-04-24 15:29:47.962 Production 3G[91519:60b] Created bundleSet with type: 0
MMBundleSet has a single attribute typeRaw
, shown here:
I use the following method for storing ENUMs in Core Data:
#pragma mark ENUM Type transformers:
- (TTBundleSetUnit)type {
return (TTBundleSetUnit)[self typeRawValue];
}
- (void)setType:(TTBundleSetUnit)bundleSetUnit {
[self setTypeRawValue:bundleSetUnit];
}
First of all, thanks for really awesome framework, it looks much better than monstrous MagicalRecord.
I'm using ObjectiveRecord in one of my project, and it takes advantage of NSFetchedResultsController to display data in UITableView and UICollectionView. Now most ActiveRecord style methods allow to fetch data from CoreData, but we don't need that with NSFetchedResultsController.
I could, of course, define private category, and just use private method of ObjectiveRecord, but that's probably not good. It could be great, if ObjectiveRecord provided a way to get NSPredicates from fancy where: methods.
Being able to efficiently get the count of all or matching objects would be a useful feature! I can send a pull request.
It would be great to be able to sort the collection. Perhaps add a method such as:
+(NSArray*) where:(id)condition order:(id)sorting;
That could accept a sorting object such as:
@{
@"createdAt" : @"desc",
@"group" : @"asc"
}
I see a few issues with the way mappings are currently implemented:
Let's explore ways to address these issues.
One thought is that we could provide a protocol, like NSCoding, that could be used to serialize/deserialize these mappings. E.g.,
@protocol ORCoding <NSObject>
+ (NSDictionary *)dictionaryFromRemoteDictionary:(NSDictionary)dict;
- (NSDictionary *)remoteDictionaryRepresentation;
@end
conformsToProtocol:
.I'm new to Core Data and iCloud, and ObjectiveRecord looks promising. As I understand it, I don't need any of my Core Data boilerplate code in my AppDelegate file.
But some of that boilerplate is required to plug in to iCloud, particularly the self.persistentStoreCoordinator
which I observer in my iCloud code:
- (void)registerForiCloudNotifications {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(storesWillChange:)
name:NSPersistentStoreCoordinatorStoresWillChangeNotification
object:self.persistentStoreCoordinator];
[notificationCenter addObserver:self
selector:@selector(storesDidChange:)
name:NSPersistentStoreCoordinatorStoresDidChangeNotification
object:self.persistentStoreCoordinator];
[notificationCenter addObserver:self
selector:@selector(persistentStoreDidImportUbiquitousContentChanges:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:self.persistentStoreCoordinator];
}
How do I plug in to ObjectiveRecord's persistent store coordinator for iCloud use?
After you perform
[yourObject delete];
the context isn't saved, so the next time you fire the app, it'll appear again.
It'll be fixed soon.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.